Skip to content

Commit 27ffd9c

Browse files
author
Andrei Neagu
committed
fixed test
1 parent 3b8056b commit 27ffd9c

File tree

1 file changed

+186
-0
lines changed

1 file changed

+186
-0
lines changed
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
# pylint:disable=redefined-outer-name
2+
# pylint:disable=unused-argument
3+
4+
from functools import cached_property
5+
6+
import nicegui
7+
import pytest
8+
from fastapi import FastAPI
9+
from helpers import assert_contains_text
10+
from nicegui import APIRouter, ui
11+
from nicegui.element import Element
12+
from playwright.async_api import Page
13+
from pytest_mock import MockerFixture
14+
from simcore_service_dynamic_scheduler.api.frontend._common.base_display_model import (
15+
BaseUpdatableDisplayModel,
16+
)
17+
from simcore_service_dynamic_scheduler.api.frontend._common.updatable_component import (
18+
BaseUpdatableComponent,
19+
)
20+
from simcore_service_dynamic_scheduler.api.frontend._utils import (
21+
get_settings,
22+
set_parent_app,
23+
)
24+
from simcore_service_dynamic_scheduler.core.settings import ApplicationSettings
25+
26+
pytest_simcore_core_services_selection = [
27+
"postgres",
28+
"rabbit",
29+
"redis",
30+
]
31+
32+
pytest_simcore_ops_services_selection = [
33+
"redis-commander",
34+
]
35+
36+
37+
class Pet(BaseUpdatableDisplayModel):
38+
name: str
39+
species: str
40+
41+
42+
class Friend(BaseUpdatableDisplayModel):
43+
name: str
44+
age: int
45+
46+
47+
class Person(BaseUpdatableDisplayModel):
48+
@cached_property
49+
def rerender_on_type_change(self) -> set[str]:
50+
return {"companion"}
51+
52+
name: str
53+
age: int
54+
companion: Pet | Friend
55+
56+
57+
class PersonDisplay(BaseUpdatableComponent[Person]):
58+
def _get_parent(self) -> Element:
59+
return ui.column()
60+
61+
def _draw(self) -> None:
62+
print("calling _draw")
63+
ui.label(f"Name: {self.display_model.name}")
64+
ui.label(f"Age: {self.display_model.age}")
65+
66+
@ui.refreshable
67+
def comp_ui() -> None:
68+
if isinstance(self.display_model.companion, Friend):
69+
ui.label().bind_text_from(
70+
self.display_model.companion,
71+
"name",
72+
backward=lambda name: f"Friend Name: {name}",
73+
)
74+
ui.label(f"Friend Age: {self.display_model.companion.age}")
75+
76+
if isinstance(self.display_model.companion, Pet):
77+
ui.label().bind_text_from(
78+
self.display_model.companion,
79+
"name",
80+
backward=lambda name: f"Pet Name: {name}",
81+
)
82+
ui.label(f"Pet Species: {self.display_model.companion.species}")
83+
84+
comp_ui()
85+
86+
# self.display_model.on_value_change("companion", comp_ui.refresh)
87+
self.display_model.on_type_change("companion", comp_ui.refresh)
88+
89+
90+
@pytest.fixture
91+
def use_internal_scheduler() -> bool:
92+
return True
93+
94+
95+
@pytest.fixture
96+
def person() -> Person:
97+
return Person(name="Alice", age=30, companion=Pet(name="Fluffy", species="cat"))
98+
99+
100+
@pytest.fixture
101+
def router(person: Person) -> APIRouter:
102+
103+
router = APIRouter()
104+
105+
@ui.page("/", api_router=router)
106+
async def index():
107+
person_display = PersonDisplay(person)
108+
109+
ui.label("BEFORE_LABEL")
110+
person_display.add_to_ui()
111+
ui.label("AFTER_LABEL")
112+
113+
return router
114+
115+
116+
@pytest.fixture
117+
def not_initialized_app(not_initialized_app: FastAPI, router: APIRouter) -> FastAPI:
118+
minimal_app = FastAPI()
119+
120+
settings = ApplicationSettings.create_from_envs()
121+
minimal_app.state.settings = settings
122+
123+
nicegui.app.include_router(router)
124+
125+
nicegui.ui.run_with(
126+
minimal_app,
127+
mount_path=settings.DYNAMIC_SCHEDULER_UI_MOUNT_PATH,
128+
storage_secret=settings.DYNAMIC_SCHEDULER_UI_STORAGE_SECRET.get_secret_value(),
129+
)
130+
set_parent_app(minimal_app)
131+
return minimal_app
132+
133+
134+
async def test_updatable_component(
135+
mocker: MockerFixture,
136+
app_runner: None,
137+
async_page: Page,
138+
server_host_port: str,
139+
person: Person,
140+
# person_display: PersonDisplay,
141+
):
142+
await async_page.goto(
143+
f"{server_host_port}{get_settings().DYNAMIC_SCHEDULER_UI_MOUNT_PATH}"
144+
)
145+
146+
# ensre render worked
147+
await assert_contains_text(async_page, "BEFORE_LABEL")
148+
await assert_contains_text(async_page, "AFTER_LABEL")
149+
150+
await assert_contains_text(async_page, "Name: Alice")
151+
await assert_contains_text(async_page, "Age: 30")
152+
153+
# _draw_spy = mocker.spy(person_display, "_draw")
154+
# _recreate_ui_spy = mocker.spy(person_display, "_recrate_ui")
155+
156+
# # TODO: test that it changes when accessing the propeties directly
157+
158+
await assert_contains_text(async_page, "Pet Name: Fluffy")
159+
person.companion.name = "Buddy"
160+
# : TODO: bidn property
161+
await assert_contains_text(async_page, "Pet Name: Buddy", timeout=2)
162+
163+
# # TODO: check that UI was rerendered with new pet name
164+
165+
# person.name = "Bob"
166+
# # TODO: check that UI was rerendered with new name
167+
168+
# person.companion = Pet(name="Buddy", species="dog")
169+
# # TODO: check that ui has no changes only values changed
170+
171+
person.companion = Friend(name="Charlie", age=25)
172+
await assert_contains_text(async_page, "Friend Name: Charlie2", timeout=2)
173+
174+
# # TODO: test that it changes if we apply the updates via the update method on the object?
175+
176+
# # TODO: check that ui has changed as expected
177+
# assert person.requires_rerender({"age": 31}) is False
178+
# person_display.update_model({"age": 31})
179+
180+
# # TODO: check that ui has changed as expected
181+
# assert person.requires_rerender({"companion": {"name": "Daisy"}}) is False
182+
# person_display.update_model({"companion": {"name": "Daisy"}})
183+
184+
# # TODO: check that ui has changed as expected
185+
# assert person.requires_rerender({"companion": {"age": 28}}) is False
186+
# person_display.update_model({"companion": {"name": "Eve", "age": 28}})

0 commit comments

Comments
 (0)