|
2 | 2 | # pylint:disable=unused-argument |
3 | 3 |
|
4 | 4 | from functools import cached_property |
| 5 | +from unittest.mock import Mock |
5 | 6 |
|
6 | 7 | import nicegui |
7 | 8 | import pytest |
8 | 9 | from fastapi import FastAPI |
9 | 10 | from helpers import assert_contains_text |
10 | 11 | from nicegui import APIRouter, ui |
11 | 12 | from playwright.async_api import Page |
| 13 | +from pydantic import NonNegativeInt |
| 14 | +from pytest_simcore.helpers.typing_env import EnvVarsDict |
12 | 15 | from simcore_service_dynamic_scheduler.api.frontend._common.base_display_model import ( |
13 | 16 | BaseUpdatableDisplayModel, |
14 | 17 | ) |
15 | 18 | from simcore_service_dynamic_scheduler.api.frontend._common.updatable_component import ( |
16 | 19 | BaseUpdatableComponent, |
17 | 20 | ) |
18 | | -from simcore_service_dynamic_scheduler.api.frontend._utils import ( |
19 | | - get_settings, |
20 | | - set_parent_app, |
21 | | -) |
22 | | -from simcore_service_dynamic_scheduler.core.settings import ApplicationSettings |
| 21 | +from simcore_service_dynamic_scheduler.api.frontend._utils import set_parent_app |
| 22 | + |
23 | 23 |
|
24 | | -pytest_simcore_core_services_selection = [ |
25 | | - "postgres", |
26 | | - "rabbit", |
27 | | - "redis", |
28 | | -] |
| 24 | +@pytest.fixture |
| 25 | +def app_environment() -> EnvVarsDict: |
| 26 | + return {} |
29 | 27 |
|
30 | | -pytest_simcore_ops_services_selection = [ |
31 | | - "redis-commander", |
32 | | -] |
| 28 | + |
| 29 | +@pytest.fixture |
| 30 | +def mount_path() -> str: |
| 31 | + return "/dynamic-scheduler/" |
| 32 | + |
| 33 | + |
| 34 | +@pytest.fixture |
| 35 | +def use_internal_scheduler() -> bool: |
| 36 | + return True |
| 37 | + |
| 38 | + |
| 39 | +@pytest.fixture |
| 40 | +def router(person: "Person") -> APIRouter: |
| 41 | + router = APIRouter() |
| 42 | + |
| 43 | + @ui.page("/", api_router=router) |
| 44 | + async def index(): |
| 45 | + _index_page_ui(person) |
| 46 | + |
| 47 | + return router |
| 48 | + |
| 49 | + |
| 50 | +@pytest.fixture |
| 51 | +def not_initialized_app( |
| 52 | + reset_nicegui_app: None, |
| 53 | + app_environment: EnvVarsDict, |
| 54 | + router: APIRouter, |
| 55 | + mount_path: str, |
| 56 | +) -> FastAPI: |
| 57 | + minimal_app = FastAPI() |
| 58 | + |
| 59 | + mock_settings = Mock() |
| 60 | + mock_settings.DYNAMIC_SCHEDULER_UI_MOUNT_PATH = mount_path |
| 61 | + minimal_app.state.settings = mock_settings |
| 62 | + |
| 63 | + nicegui.app.include_router(router) |
| 64 | + |
| 65 | + nicegui.ui.run_with( |
| 66 | + minimal_app, mount_path=mount_path, storage_secret="test-secret" |
| 67 | + ) |
| 68 | + set_parent_app(minimal_app) |
| 69 | + return minimal_app |
33 | 70 |
|
34 | 71 |
|
35 | 72 | class Pet(BaseUpdatableDisplayModel): |
@@ -105,40 +142,6 @@ def _index_page_ui(person: Person) -> None: |
105 | 142 | ui.label("AFTER_LABEL") |
106 | 143 |
|
107 | 144 |
|
108 | | -@pytest.fixture |
109 | | -def use_internal_scheduler() -> bool: |
110 | | - return True |
111 | | - |
112 | | - |
113 | | -@pytest.fixture |
114 | | -def router(person: Person) -> APIRouter: |
115 | | - router = APIRouter() |
116 | | - |
117 | | - @ui.page("/", api_router=router) |
118 | | - async def index(): |
119 | | - _index_page_ui(person) |
120 | | - |
121 | | - return router |
122 | | - |
123 | | - |
124 | | -@pytest.fixture |
125 | | -def not_initialized_app(not_initialized_app: FastAPI, router: APIRouter) -> FastAPI: |
126 | | - minimal_app = FastAPI() |
127 | | - |
128 | | - settings = ApplicationSettings.create_from_envs() |
129 | | - minimal_app.state.settings = settings |
130 | | - |
131 | | - nicegui.app.include_router(router) |
132 | | - |
133 | | - nicegui.ui.run_with( |
134 | | - minimal_app, |
135 | | - mount_path=settings.DYNAMIC_SCHEDULER_UI_MOUNT_PATH, |
136 | | - storage_secret=settings.DYNAMIC_SCHEDULER_UI_STORAGE_SECRET.get_secret_value(), |
137 | | - ) |
138 | | - set_parent_app(minimal_app) |
139 | | - return minimal_app |
140 | | - |
141 | | - |
142 | 145 | async def _ensure_before_label(async_page: Page) -> None: |
143 | 146 | await assert_contains_text(async_page, "BEFORE_LABEL") |
144 | 147 |
|
@@ -176,33 +179,38 @@ async def _ensure_index_page(async_page: Page, person: Person) -> None: |
176 | 179 |
|
177 | 180 |
|
178 | 181 | @pytest.mark.parametrize( |
179 | | - "person, person_update", |
| 182 | + "person, person_update, expected_callbacks_count", |
180 | 183 | [ |
181 | 184 | pytest.param( |
182 | 185 | Person(name="Alice", age=30, companion=Pet(name="Fluffy", species="cat")), |
183 | 186 | Person(name="Alice", age=30, companion=Pet(name="Buddy", species="dog")), |
184 | | - id="change-pet", |
185 | | - ) |
| 187 | + 0, |
| 188 | + id="update-pet-via-attribute-biding-no-rerender", |
| 189 | + ), |
| 190 | + pytest.param( |
| 191 | + Person(name="Alice", age=30, companion=Pet(name="Fluffy", species="cat")), |
| 192 | + Person(name="Alice", age=30, companion=Friend(name="Marta", age=30)), |
| 193 | + 1, |
| 194 | + id="update-pet-ui-rerednder", |
| 195 | + ), |
186 | 196 | ], |
187 | 197 | ) |
188 | 198 | async def test_updatable_component( |
189 | 199 | app_runner: None, |
190 | 200 | async_page: Page, |
| 201 | + mount_path: str, |
191 | 202 | server_host_port: str, |
192 | 203 | person: Person, |
193 | 204 | person_update: Person, |
| 205 | + expected_callbacks_count: NonNegativeInt, |
194 | 206 | ): |
195 | | - await async_page.goto( |
196 | | - f"{server_host_port}{get_settings().DYNAMIC_SCHEDULER_UI_MOUNT_PATH}" |
197 | | - ) |
| 207 | + await async_page.goto(f"{server_host_port}{mount_path}") |
198 | 208 |
|
199 | 209 | # check initial page layout |
200 | 210 | await _ensure_index_page(async_page, person) |
201 | 211 |
|
202 | | - person.update(person_update) |
| 212 | + callbacks_count = person.update(person_update) |
| 213 | + assert callbacks_count == expected_callbacks_count |
203 | 214 |
|
204 | 215 | # change layout after update |
205 | 216 | await _ensure_index_page(async_page, person_update) |
206 | | - |
207 | | - |
208 | | -# TODO: make tests go faster since we are running differently |
|
0 commit comments