подгрузка данных для api из env
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
APP = (ROOT / "app.py").read_text(encoding="utf-8")
|
||||
INTEGRATION = (ROOT / "ui_builder" / "integration.py").read_text(encoding="utf-8")
|
||||
UI_JS = (ROOT / "ui_builder" / "static" / "app.js").read_text(encoding="utf-8")
|
||||
TOURNAMENT_JS = (ROOT / "hockey_data" / "static" / "tournament-menu.js").read_text(encoding="utf-8")
|
||||
SERVICE = (ROOT / "hockey_data" / "service.py").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_runtime_is_default_even_for_legacy_editor_bookmarks():
|
||||
assert 'return RedirectResponse("/", status_code=302)' in APP
|
||||
assert 'request.query_params.get("open") != "1"' in INTEGRATION
|
||||
assert 'function explicitEditorUrl()' in UI_JS
|
||||
assert 'open=1' in UI_JS
|
||||
|
||||
|
||||
def test_match_selection_no_longer_depends_on_full_details_sync():
|
||||
assert 'Match selection itself depends only on the local/cached schedule row.' in TOURNAMENT_JS
|
||||
assert 'void enrichOpenedGame(String(id), state.selectedId, generation);' in TOURNAMENT_JS
|
||||
assert 'Full match JSON, rosters, shots and directories are enrichment data.' in TOURNAMENT_JS
|
||||
assert 'gameOpenGeneration' in TOURNAMENT_JS
|
||||
|
||||
|
||||
def test_server_returns_cached_match_when_full_details_are_unavailable():
|
||||
assert 'payload = await asyncio.wait_for(' in SERVICE
|
||||
assert 'timeout=12.0' in SERVICE
|
||||
assert '"details_sync_failed": True' in SERVICE
|
||||
assert 'Полная карточка матча пока недоступна' in SERVICE
|
||||
|
||||
|
||||
def test_games_url_keeps_selected_date_and_language():
|
||||
assert '?on_date=${encodeURIComponent(state.gameDate)}' in TOURNAMENT_JS
|
||||
assert '&language=${encodeURIComponent(state.language)}' in TOURNAMENT_JS
|
||||
37
tests/test_build67_admin_connection_diagnostics.py
Normal file
37
tests/test_build67_admin_connection_diagnostics.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
JS = (ROOT / "hockey_data" / "static" / "tournament-menu.js").read_text(encoding="utf-8")
|
||||
ROUTER = (ROOT / "hockey_data" / "router.py").read_text(encoding="utf-8")
|
||||
CSS = (ROOT / "hockey_data" / "static" / "tournament-menu.css").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_connection_diagnostics_are_admin_only():
|
||||
assert '@router.get("/admin/connection-diagnostics", dependencies=admin)' in ROUTER
|
||||
assert 'service.database.engine.connect()' in ROUTER
|
||||
assert 'service.test_connection()' in ROUTER
|
||||
assert 'agent_hub.list_mapping_devices()' in ROUTER
|
||||
assert 'required_for_match_selection' in ROUTER
|
||||
assert 'required_for_remote_sync' in ROUTER
|
||||
|
||||
|
||||
def test_runtime_knows_admin_before_rendering_navigation():
|
||||
assert 'state.isAdmin = Boolean(user?.is_admin);' in JS
|
||||
assert 'await ensureAccountScopedRuntimeState();\n ensureShell();' in JS
|
||||
assert '${state.isAdmin ? `' in JS
|
||||
assert 'data-open-connection-diagnostics' in JS
|
||||
assert 'data-open-settings' in JS
|
||||
|
||||
|
||||
def test_non_admin_does_not_get_misleading_connection_setup_warning():
|
||||
assert ': state.isAdmin\n ? t("notConfigured")\n : t("noGamesLoaded")' in JS
|
||||
assert 'if (!state.isAdmin) return;' in JS
|
||||
|
||||
|
||||
def test_failed_match_can_be_diagnosed_with_deep_probe():
|
||||
assert 'lastAttemptedGameId' in JS
|
||||
assert 'lastGameOpenError' in JS
|
||||
assert 'data-match-error-diagnostics' in JS
|
||||
assert 'showConnectionDiagnostics({ deep: true })' in JS
|
||||
assert 'deep: deep ? "true" : "false"' in JS
|
||||
assert '.hockey-connection-diagnostics-card' in CSS
|
||||
58
tests/test_build68_settings_env_git.py
Normal file
58
tests/test_build68_settings_env_git.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from pathlib import Path
|
||||
|
||||
from hockey_data.config import HockeySettingsStore
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def test_git_tracks_ui_settings_but_keeps_credentials_local():
|
||||
text = (ROOT / ".gitignore").read_text(encoding="utf-8")
|
||||
assert "settings/*" in text
|
||||
assert "!settings/ui_builder_draft.json" in text
|
||||
assert "!settings/ui_builder_published.json" in text
|
||||
assert "!settings/hockey_api.json" in text
|
||||
assert "settings/stat2tv_credentials.local.json" in text
|
||||
assert "settings/editor_security.json" in text
|
||||
|
||||
|
||||
def test_stat2tv_env_credentials_override_local_file(tmp_path, monkeypatch):
|
||||
store = HockeySettingsStore(tmp_path / "settings")
|
||||
store.secret_file.write_text(
|
||||
'{"username":"file-user","password":"file-pass"}',
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setenv("STAT2TV_LOGIN", "env-user")
|
||||
monkeypatch.setenv("STAT2TV_PASSWORD", "env-pass")
|
||||
|
||||
assert store.credentials() == ("env-user", "env-pass")
|
||||
status = store.status()
|
||||
assert status["credentials_configured"] is True
|
||||
assert status["credentials_source"] == "env"
|
||||
assert "env-pass" not in str(status)
|
||||
|
||||
|
||||
def test_local_credentials_remain_fallback_without_env(tmp_path, monkeypatch):
|
||||
monkeypatch.delenv("STAT2TV_LOGIN", raising=False)
|
||||
monkeypatch.delenv("STAT2TV_PASSWORD", raising=False)
|
||||
store = HockeySettingsStore(tmp_path / "settings")
|
||||
store.secret_file.write_text(
|
||||
'{"username":"file-user","password":"file-pass"}',
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
assert store.credentials() == ("file-user", "file-pass")
|
||||
assert store.status()["credentials_source"] == "local_file"
|
||||
|
||||
|
||||
def test_production_env_file_fallback_is_present():
|
||||
app = (ROOT / "app.py").read_text(encoding="utf-8")
|
||||
assert 'HOCKEY_ENV_FILE' in app
|
||||
assert '"/mnt/khl/.env"' in app
|
||||
assert 'load_dotenv(_external_env, override=False)' in app
|
||||
|
||||
|
||||
def test_admin_diagnostics_reports_credential_source_without_secret():
|
||||
router = (ROOT / "hockey_data" / "router.py").read_text(encoding="utf-8")
|
||||
js = (ROOT / "hockey_data" / "static" / "tournament-menu.js").read_text(encoding="utf-8")
|
||||
assert '"credentials_source": settings_status.get("credentials_source", "missing")' in router
|
||||
assert "Credentials source" in js
|
||||
Reference in New Issue
Block a user