"""Tests for Flask web application.""" from vigilar.config import CameraConfig, VigilarConfig from vigilar.web.app import create_app def test_app_creates(): cfg = VigilarConfig() app = create_app(cfg) assert app is not None def test_index_loads(): cfg = VigilarConfig(cameras=[ CameraConfig(id="test", display_name="Test", rtsp_url="rtsp://localhost"), ]) app = create_app(cfg) with app.test_client() as client: resp = client.get("/") assert resp.status_code == 200 assert b"Vigilar" in resp.data assert b"Test" in resp.data def test_settings_loads(): cfg = VigilarConfig() app = create_app(cfg) with app.test_client() as client: resp = client.get("/system/settings") assert resp.status_code == 200 assert b"Settings" in resp.data def test_kiosk_loads(): cfg = VigilarConfig(cameras=[ CameraConfig(id="cam1", display_name="Cam 1", rtsp_url="rtsp://a"), ]) app = create_app(cfg) with app.test_client() as client: resp = client.get("/kiosk/") assert resp.status_code == 200 assert b"Cam 1" in resp.data assert b"kiosk-grid" in resp.data def test_system_status_api(): cfg = VigilarConfig() app = create_app(cfg) with app.test_client() as client: resp = client.get("/system/status") assert resp.status_code == 200 data = resp.get_json() assert "arm_state" in data def test_config_api(): cfg = VigilarConfig() app = create_app(cfg) with app.test_client() as client: resp = client.get("/system/api/config") assert resp.status_code == 200 data = resp.get_json() assert "system" in data assert "cameras" in data # Secrets should be redacted assert "password_hash" not in data.get("web", {}) def test_camera_status_api(): cfg = VigilarConfig(cameras=[ CameraConfig(id="test", display_name="Test", rtsp_url="rtsp://localhost"), ]) app = create_app(cfg) with app.test_client() as client: resp = client.get("/cameras/api/status") assert resp.status_code == 200 data = resp.get_json() assert len(data) == 1 assert data[0]["id"] == "test" def test_events_page_loads(): cfg = VigilarConfig() app = create_app(cfg) with app.test_client() as client: resp = client.get("/events/") assert resp.status_code == 200 assert b"Event Log" in resp.data def test_sensors_page_loads(): cfg = VigilarConfig() app = create_app(cfg) with app.test_client() as client: resp = client.get("/sensors/") assert resp.status_code == 200 def test_recordings_page_loads(): cfg = VigilarConfig() app = create_app(cfg) with app.test_client() as client: resp = client.get("/recordings/") assert resp.status_code == 200 def test_system_status_reflects_fsm_arm_state(tmp_path, monkeypatch): """system_status must read the current arm state from the DB, not return a hardcoded stub. Regression guard for the web-to-FSM async flow introduced in issue #2.""" from vigilar.config import SystemConfig, VigilarConfig import vigilar.storage.db as db_module from vigilar.storage.db import get_db_path from vigilar.storage.schema import metadata from vigilar.storage.queries import insert_arm_state from vigilar.web.app import create_app from sqlalchemy import create_engine data_dir = tmp_path / "data" data_dir.mkdir() cfg = VigilarConfig(system=SystemConfig(data_dir=str(data_dir))) # Build an isolated engine (bypass the module-level singleton) db_path = get_db_path(str(data_dir)) isolated_engine = create_engine(f"sqlite:///{db_path}", echo=False) metadata.create_all(isolated_engine) insert_arm_state(isolated_engine, "ARMED_AWAY", "test", None) # Patch the singleton so the blueprint's get_engine() returns our engine monkeypatch.setattr(db_module, "_engine", isolated_engine) app = create_app(cfg) with app.test_client() as c: resp = c.get("/system/status") assert resp.status_code == 200 assert resp.get_json()["arm_state"] == "ARMED_AWAY"