1+ from pathlib import Path
12from unittest .mock import patch
23
34import pytest
@@ -10,54 +11,42 @@ def test_ensure_static_path_ready_uses_existing_static_path(tmp_path) -> None:
1011 static_path .mkdir ()
1112 (static_path / "index.html" ).write_text ("<html></html>" , encoding = "utf-8" )
1213
13- with (
14- patch .object (webui_app , "_resolve_static_path" , return_value = static_path ),
15- patch .object (webui_app , "_try_build_dashboard" ) as build_mock ,
16- ):
14+ with patch .object (webui_app , "_resolve_static_path" , return_value = static_path ):
1715 result = webui_app ._ensure_static_path_ready ()
1816
1917 assert result == static_path
20- build_mock .assert_not_called ()
21-
2218
23- def test_ensure_static_path_ready_retries_after_auto_build (tmp_path ) -> None :
24- static_path = tmp_path / "dist"
25- static_path .mkdir ()
26- (static_path / "index.html" ).write_text ("<html></html>" , encoding = "utf-8" )
2719
20+ def test_ensure_static_path_ready_logs_install_hint_when_static_assets_are_missing () -> None :
2821 with (
29- patch .object (webui_app , "_resolve_static_path" , side_effect = [None , static_path ]),
30- patch .object (
31- webui_app ,
32- "_try_build_dashboard" ,
33- return_value = webui_app .DashboardAutoRecoveryResult (succeeded = True ),
34- ) as build_mock ,
22+ patch .object (webui_app , "_resolve_static_path" , return_value = None ),
23+ patch .object (webui_app .logger , "warning" ) as warning_mock ,
3524 ):
3625 result = webui_app ._ensure_static_path_ready ()
3726
38- assert result == static_path
39- build_mock .assert_called_once_with ()
27+ assert result is None
28+ warning_mock .assert_any_call (webui_app .t ("startup.webui_static_assets_unavailable" ))
29+ warning_mock .assert_any_call (
30+ webui_app .t ("startup.webui_dashboard_package_hint" , command = webui_app ._MANUAL_INSTALL_COMMAND )
31+ )
4032
4133
42- def test_ensure_static_path_ready_logs_manual_hint_when_auto_build_fails () -> None :
34+ def test_ensure_static_path_ready_logs_index_error_when_static_path_is_invalid (tmp_path ) -> None :
35+ static_path = tmp_path / "dist"
36+ static_path .mkdir ()
37+
4338 with (
44- patch .object (webui_app , "_resolve_static_path" , return_value = None ),
45- patch .object (
46- webui_app ,
47- "_try_build_dashboard" ,
48- return_value = webui_app .DashboardAutoRecoveryResult (
49- succeeded = False ,
50- manual_recovery_command = webui_app ._MANUAL_BUILD_COMMAND ,
51- ),
52- ),
39+ patch .object (webui_app , "_resolve_static_path" , return_value = static_path ),
5340 patch .object (webui_app .logger , "warning" ) as warning_mock ,
5441 ):
5542 result = webui_app ._ensure_static_path_ready ()
5643
5744 assert result is None
58- warning_mock .assert_any_call (webui_app .t ("startup.webui_auto_recovery_failed" ))
5945 warning_mock .assert_any_call (
60- webui_app .t ("startup.webui_manual_build_hint" , command = webui_app ._MANUAL_BUILD_COMMAND )
46+ webui_app .t ("startup.webui_index_missing" , index_path = static_path / "index.html" )
47+ )
48+ warning_mock .assert_any_call (
49+ webui_app .t ("startup.webui_dashboard_package_hint" , command = webui_app ._MANUAL_INSTALL_COMMAND )
6150 )
6251
6352
@@ -73,43 +62,21 @@ def test_setup_static_files_does_not_duplicate_warning_when_static_path_is_unava
7362 warning_mock .assert_not_called ()
7463
7564
76- def test_get_dashboard_build_command_defaults_to_npm (tmp_path ) -> None :
77- (tmp_path / "package.json" ).write_text ("{}" , encoding = "utf-8" )
65+ def test_resolve_static_path_prefers_installed_dashboard_package (monkeypatch , tmp_path ) -> None :
66+ package_dist = tmp_path / "site-packages" / "maibot_dashboard" / "dist"
67+ package_dist .mkdir (parents = True )
7868
79- with patch .object (
80- webui_app .shutil ,
81- "which" ,
82- side_effect = lambda tool_name : "/usr/bin/npm" if tool_name == "npm" else None ,
83- ):
84- command = webui_app ._get_dashboard_build_command (tmp_path )
69+ class _DashboardModule :
70+ @staticmethod
71+ def get_dist_path () -> Path :
72+ return package_dist
8573
86- assert command == ["npm" , "run" , "build" ]
87-
88-
89- def test_try_build_dashboard_installs_missing_dependencies_before_build (monkeypatch , tmp_path ) -> None :
90- (tmp_path / "package.json" ).write_text ("{}" , encoding = "utf-8" )
91- run_results = [
92- webui_app .CompletedProcess (args = ["npm" , "install" , "--no-package-lock" ], returncode = 0 , stdout = "" , stderr = "" ),
93- webui_app .CompletedProcess (args = ["npm" , "run" , "build" ], returncode = 0 , stdout = "" , stderr = "" ),
94- ]
74+ monkeypatch .setattr (webui_app , "_get_project_root" , lambda : tmp_path )
9575
96- monkeypatch . setattr (webui_app , "_get_dashboard_root " , lambda : tmp_path )
97- monkeypatch . setattr ( webui_app , "_should_auto_install_dashboard_dependencies" , lambda dashboard_root : True )
76+ with patch . object (webui_app , "import_module " , return_value = _DashboardModule ()):
77+ resolved_path = webui_app . _resolve_static_path ( )
9878
99- with (
100- patch .object (webui_app , "_get_dashboard_build_command" , return_value = ["npm" , "run" , "build" ]),
101- patch .object (webui_app , "run" , side_effect = run_results ) as run_mock ,
102- ):
103- result = webui_app ._try_build_dashboard ()
104-
105- assert result .succeeded is True
106- assert run_mock .call_count == 2
107- install_call = run_mock .call_args_list [0 ]
108- build_call = run_mock .call_args_list [1 ]
109- assert install_call .args [0 ] == ["npm" , "install" , "--no-package-lock" ]
110- assert install_call .kwargs ["cwd" ] == tmp_path
111- assert build_call .args [0 ] == ["npm" , "run" , "build" ]
112- assert build_call .kwargs ["cwd" ] == tmp_path
79+ assert resolved_path == package_dist
11380
11481
11582def test_resolve_static_path_uses_dashboard_dist (monkeypatch , tmp_path ) -> None :
0 commit comments