Refine built-in web app experience

This commit is contained in:
Artem Kokos
2026-05-21 21:47:33 +07:00
parent 61b21c63ea
commit f55e00bce1
11 changed files with 1320 additions and 456 deletions

View File

@@ -20,7 +20,7 @@ os.environ["IGNIS_SYNC_DATABASE_URL"] = f"sqlite:///{TEST_DB_PATH}"
import main # noqa: E402
from app.api.routes import control # noqa: E402
from app.core.database import async_session, engine, init_db, sync_engine # noqa: E402
from app.core.state import state_manager # noqa: E402
from app.core.state import DiscoveryApplyResult, state_manager # noqa: E402
from app.drivers.wiz import WizResponse # noqa: E402
from app.models.api_key import ApiKeyModel # noqa: E402
from app.models.device import DeviceSchema # noqa: E402
@@ -42,6 +42,7 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
await self._reset_database()
state_manager.devices.clear()
state_manager.groups.clear()
state_manager.discovery_snapshot = None
self.client = AsyncClient(
transport=ASGITransport(app=main.app),
base_url="http://testserver",
@@ -51,6 +52,7 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
await self.client.aclose()
state_manager.devices.clear()
state_manager.groups.clear()
state_manager.discovery_snapshot = None
async def _reset_database(self):
async with async_session() as session:
@@ -107,6 +109,17 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
async def test_system_info_returns_installed_server_metadata_without_secrets(
self,
):
state_manager.record_discovery(
"manual",
DiscoveryApplyResult(
found=4,
added=1,
updated=3,
removed_offline=0,
pending_removal=0,
online=4,
),
)
with patch.dict(
os.environ,
{
@@ -148,10 +161,24 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
self.assertTrue(payload["configuration"]["public_base_url_configured"])
self.assertTrue(payload["configuration"]["build_metadata_complete"])
self.assertIn("started_at", payload)
self.assertEqual(payload["discovery"]["last_scan_mode"], "manual")
self.assertEqual(payload["discovery"]["online"], 4)
self.assertEqual(payload["discovery"]["found"], 4)
self.assertNotIn(MASTER_KEY, response.text)
self.assertNotIn("api_key", payload)
async def test_guest_key_can_read_system_info(self):
state_manager.record_discovery(
"startup",
DiscoveryApplyResult(
found=2,
added=2,
updated=0,
removed_offline=0,
pending_removal=0,
online=2,
),
)
create_response = await self.client.post(
"/api-keys",
headers=self._master_headers(),
@@ -159,22 +186,32 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
)
guest_key = create_response.json()["key"]
response = await self.client.get(
"/system/info",
headers={"X-API-Key": guest_key},
)
with patch.dict(
os.environ,
{
"IGNIS_INSTANCE_NAME": "Home Lab",
},
clear=False,
):
response = await self.client.get(
"/system/info",
headers={"X-API-Key": guest_key},
)
self.assertEqual(response.status_code, 200)
payload = response.json()
self.assertEqual(payload["app_name"], "Ignis Core")
self.assertEqual(payload["instance_name"], "Home Lab")
self.assertGreaterEqual(payload["uptime_seconds"], 0)
self.assertFalse(payload["diagnostics_visible"])
self.assertNotIn("instance_name", payload)
self.assertNotIn("timezone", payload)
self.assertNotIn("started_at", payload)
self.assertNotIn("build", payload)
self.assertNotIn("urls", payload)
self.assertNotIn("configuration", payload)
self.assertEqual(payload["discovery"]["last_scan_mode"], "startup")
self.assertEqual(payload["discovery"]["online"], 2)
self.assertNotIn("found", payload["discovery"])
async def test_master_can_create_key_and_list_endpoint_returns_public_id(self):
create_response = await self.client.post(
@@ -485,7 +522,9 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
self.assertEqual(response.status_code, 422)
async def test_stats_summary_counts_real_commands_without_requested_duplicates(self):
async def test_stats_summary_counts_real_commands_without_requested_duplicates(
self,
):
self._set_single_device_state()
with patch.object(