1
0
Эх сурвалжийг харах

providing default favicon route only once
and began with favicon tests

Rodja Trappe 2 жил өмнө
parent
commit
384f36b34f

+ 3 - 7
nicegui/favicon.py

@@ -11,16 +11,12 @@ if TYPE_CHECKING:
 
 
 def create_favicon_route(path: str, favicon: Optional[str]) -> None:
-    if favicon and (is_remote_url(favicon) or is_char(favicon)):
-        return
-    fallback = Path(__file__).parent / 'static' / 'favicon.ico'
-    path = f'{"" if path == "/" else path}/favicon.ico'
-    globals.app.remove_route(path)
-    globals.app.add_route(path, lambda _: FileResponse(favicon or globals.favicon or fallback))
+    if favicon and Path(favicon).exists():
+        globals.app.add_route(path, lambda _: FileResponse(favicon))
 
 
 def get_favicon_url(page: 'page', prefix: str) -> str:
-    favicon = page.favicon or globals.favicon
+    favicon = str(page.favicon or globals.favicon)
     if favicon and is_remote_url(favicon):
         return favicon
     elif not favicon:

+ 4 - 0
nicegui/nicegui.py

@@ -66,6 +66,10 @@ def handle_startup(with_welcome_message: bool = True) -> None:
                            'remove the guard or replace it with\n'
                            '   if __name__ in {"__main__", "__mp_main__"}:\n'
                            'to allow for multiprocessing.')
+    if globals.favicon and Path(globals.favicon).exists():
+        globals.app.add_route('/favicon.ico', lambda _: FileResponse(globals.favicon))
+    else:
+        globals.app.add_route('/favicon.ico', lambda _: FileResponse(Path(__file__).parent / 'static' / 'favicon.ico'))
     globals.state = globals.State.STARTING
     globals.loop = asyncio.get_running_loop()
     with globals.index_client:

+ 2 - 0
tests/conftest.py

@@ -37,6 +37,8 @@ def selenium(selenium: webdriver.Chrome) -> webdriver.Chrome:
 
 @pytest.fixture(autouse=True)
 def reset_globals() -> Generator[None, None, None]:
+    # we need to remove
+    [globals.app.routes.remove(r) for r in globals.app.routes if 'favicon' in r.path]
     for path in {'/'}.union(globals.page_routes.values()):
         globals.app.remove_route(path)
     importlib.reload(globals)

+ 2 - 2
tests/screen.py

@@ -21,16 +21,16 @@ IGNORED_CLASSES = ['row', 'column', 'q-card', 'q-field', 'q-field__label', 'q-in
 class Screen:
     IMPLICIT_WAIT = 4
     SCREENSHOT_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'screenshots')
-    UI_RUN_KWARGS = {'port': PORT, 'show': False, 'reload': False}
 
     def __init__(self, selenium: webdriver.Chrome, caplog: pytest.LogCaptureFixture) -> None:
         self.selenium = selenium
         self.caplog = caplog
         self.server_thread = None
+        self.ui_run_kwargs = {'port': PORT, 'show': False, 'reload': False}
 
     def start_server(self) -> None:
         '''Start the webserver in a separate thread. This is the equivalent of `ui.run()` in a normal script.'''
-        self.server_thread = threading.Thread(target=ui.run, kwargs=self.UI_RUN_KWARGS)
+        self.server_thread = threading.Thread(target=ui.run, kwargs=self.ui_run_kwargs)
         self.server_thread.start()
 
     @property

+ 44 - 0
tests/test_favicon.py

@@ -0,0 +1,44 @@
+from pathlib import Path
+
+import requests
+from bs4 import BeautifulSoup
+
+from nicegui import ui
+
+from .screen import PORT, Screen
+
+
+def assert_favicon_url_starts_with(screen: Screen, content: str):
+    soup = BeautifulSoup(screen.selenium.page_source, 'html.parser')
+    icon_link = soup.find("link", rel="icon")
+    assert icon_link['href'].startswith(content)
+
+
+def test_default(screen: Screen):
+    ui.label('Hello, world')
+
+    screen.open('/')
+    response = requests.get(f'http://localhost:{PORT}/favicon.ico')
+    assert response.status_code == 200
+
+
+def test_emoji(screen: Screen):
+    ui.label('Hello, world')
+
+    screen.ui_run_kwargs['favicon'] = '👋'
+    screen.open('/')
+    response = requests.get(f'http://localhost:{PORT}/favicon.ico')
+    assert response.status_code == 200, 'default favicon should still be available for plain FastAPI requests running in the browser'
+    assert (Path(__file__).parent.parent / 'nicegui' / 'static' / 'favicon.ico').read_bytes() == response.content
+    assert_favicon_url_starts_with(screen, 'data:image/svg+xml')
+
+
+def test_custom_file(screen: Screen):
+    ui.label('Hello, world')
+
+    screen.ui_run_kwargs['favicon'] = Path(__file__).parent.parent / 'website' / 'static' / 'logo_square.png'
+    screen.open('/')
+    assert_favicon_url_starts_with(screen, '/favicon.ico')
+    response = requests.get(f'http://localhost:{PORT}/favicon.ico')
+    assert response.status_code == 200
+    assert screen.ui_run_kwargs['favicon'].read_bytes() == response.content