File size: 5,125 Bytes
89419ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import builtins
import shutil
import sys
import tempfile
import types
from pathlib import Path

from fastapi.testclient import TestClient

import webui
import src.config.settings as settings_module
import src.database.session as db_session
from src.web.app import create_app
from src.web.routes import api_router


def test_api_router_mounts_external_routes():
    paths = {route.path for route in api_router.routes}
    assert "/external/capabilities" in paths
    assert "/external/registration/batches" in paths


def test_app_startup_tolerates_missing_external_recovery(monkeypatch):
    import src.database.init_db as init_db
    import src.database.session as db_session

    monkeypatch.setattr(init_db, "initialize_database", lambda: None)

    class _DummyDbContext:
        def __enter__(self):
            return object()

        def __exit__(self, exc_type, exc, tb):
            return False

    monkeypatch.setattr(db_session, "get_db", lambda: _DummyDbContext())

    original_import = builtins.__import__

    def _patched_import(name, globals=None, locals=None, fromlist=(), level=0):
        if "external_batches.recovery" in name:
            raise ModuleNotFoundError(name)
        if name.endswith("external_batches") and fromlist and "recovery" in fromlist:
            raise ModuleNotFoundError(name)
        return original_import(name, globals, locals, fromlist, level)

    monkeypatch.setattr(builtins, "__import__", _patched_import)

    app = create_app()
    with TestClient(app) as client:
        response = client.get("/login")
        assert response.status_code == 200


def test_start_webui_uses_preloaded_app_instance(monkeypatch):
    fake_app = object()

    class _Settings:
        webui_host = "127.0.0.1"
        webui_port = 1455
        debug = False

    fake_module = types.ModuleType("src.web.app")
    fake_module.app = fake_app
    captured = {}

    monkeypatch.setattr(webui, "setup_application", lambda: _Settings())
    monkeypatch.setitem(sys.modules, "src.web.app", fake_module)
    monkeypatch.setattr(webui.uvicorn, "run", lambda **kwargs: captured.update(kwargs))

    webui.start_webui()

    assert captured["app"] is fake_app
    assert captured["host"] == "127.0.0.1"
    assert captured["port"] == 1455


def test_main_prefers_port_environment_variable(monkeypatch):
    captured = {}

    monkeypatch.setenv("PORT", "7860")
    monkeypatch.delenv("WEBUI_PORT", raising=False)
    monkeypatch.delenv("APP_PORT", raising=False)
    monkeypatch.delenv("WEBUI_HOST", raising=False)
    monkeypatch.delenv("APP_HOST", raising=False)
    monkeypatch.setattr(sys, "argv", ["webui.py"])
    monkeypatch.setattr(webui, "initialize_database", lambda: None)
    monkeypatch.setattr(webui, "start_webui", lambda: None)

    import src.config.settings as settings_module
    monkeypatch.setattr(settings_module, "update_settings", lambda **kwargs: captured.update(kwargs))

    webui.main()

    assert captured["webui_port"] == 7860


def test_main_uses_webui_env_when_port_missing(monkeypatch):
    captured = {}

    monkeypatch.delenv("PORT", raising=False)
    monkeypatch.setenv("WEBUI_PORT", "8080")
    monkeypatch.setenv("WEBUI_HOST", "0.0.0.0")
    monkeypatch.delenv("APP_PORT", raising=False)
    monkeypatch.delenv("APP_HOST", raising=False)
    monkeypatch.setattr(sys, "argv", ["webui.py"])
    monkeypatch.setattr(webui, "initialize_database", lambda: None)
    monkeypatch.setattr(webui, "start_webui", lambda: None)

    import src.config.settings as settings_module
    monkeypatch.setattr(settings_module, "update_settings", lambda **kwargs: captured.update(kwargs))

    webui.main()

    assert captured["webui_host"] == "0.0.0.0"
    assert captured["webui_port"] == 8080


def test_setup_application_refreshes_stale_settings_cache(monkeypatch):
    from src.database.init_db import initialize_database

    temp_root = Path(tempfile.mkdtemp())
    try:
        data_dir = temp_root / "data"
        logs_dir = temp_root / "logs"
        data_dir.mkdir()
        logs_dir.mkdir()

        monkeypatch.setattr(webui, "project_root", temp_root)
        monkeypatch.setenv("APP_DATA_DIR", str(data_dir))
        monkeypatch.setenv("APP_LOGS_DIR", str(logs_dir))
        monkeypatch.setattr(db_session, "_db_manager", None)
        monkeypatch.setattr(settings_module, "_settings", None)
        monkeypatch.setattr(webui, "setup_logging", lambda **kwargs: None)

        initialize_database()
        settings_module.update_settings(
            external_api_enabled=True,
            external_api_key="test-external-key",
        )

        monkeypatch.setattr(
            settings_module,
            "_settings",
            settings_module.Settings(external_api_enabled=False),
        )

        settings = webui.setup_application()

        assert settings.external_api_enabled is True
        assert settings.external_api_key.get_secret_value() == "test-external-key"
        db_session._db_manager.engine.dispose()
        monkeypatch.setattr(db_session, "_db_manager", None)
    finally:
        shutil.rmtree(temp_root, ignore_errors=True)