"""Tests for scanner REST API endpoints.""" import pytest from pathlib import Path DESIGN_DIR = "/workspace/arch-design-agent-skill-dashboard/design" @pytest.fixture def project_id(client): r = client.post("/api/projects", json={"name": "test", "design_dir": DESIGN_DIR}) return r.json()["id"] def test_trigger_scan(client, project_id): r = client.post(f"/api/projects/{project_id}/scan") assert r.status_code == 200 data = r.json() assert data["project_id"] == project_id assert "file_statuses" in data assert "summary" in data # Should NOT have entity lists in response assert "capabilities" not in data assert "modules" not in data def test_get_scan(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/scan") assert r.status_code == 200 data = r.json() assert data["project_id"] == project_id def test_get_scan_not_scanned(client, project_id): r = client.get(f"/api/projects/{project_id}/scan") assert r.status_code == 404 def test_list_capabilities(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/capabilities") assert r.status_code == 200 caps = r.json() assert len(caps) > 0 assert "capability_id" in caps[0] def test_list_modules(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/modules") assert r.status_code == 200 mods = r.json() assert len(mods) > 0 assert "module_id" in mods[0] def test_list_entities(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/entities") assert r.status_code == 200 ents = r.json() assert len(ents) > 0 def test_list_integrations(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/integrations") assert r.status_code == 200 ints = r.json() assert len(ints) > 0 # Integration should have source/target (not source_id/target_id) assert "source" in ints[0] assert "target" in ints[0] assert "source_id" not in ints[0] assert "target_id" not in ints[0] def test_list_value_flows(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/value-flows") assert r.status_code == 200 vfs = r.json() assert len(vfs) > 0 def test_list_user_journeys(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/user-journeys") assert r.status_code == 200 ujs = r.json() assert len(ujs) > 0 def test_list_data_flows(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/data-flows") assert r.status_code == 200 dfs = r.json() assert len(dfs) > 0 def test_list_external_systems(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/external-systems") assert r.status_code == 200 ess = r.json() assert len(ess) > 0 def test_list_traceability_links(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/traceability-links") assert r.status_code == 200 tls = r.json() assert len(tls) > 0 def test_list_runtime_components(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/runtime-components") assert r.status_code == 200 rcs = r.json() assert len(rcs) > 0 def test_capability_detail(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/capabilities/CAP-PROJ-REG") assert r.status_code == 200 detail = r.json() assert "capability" in detail assert "modules" in detail assert "value_flows" in detail assert detail["capability"]["capability_id"] == "CAP-PROJ-REG" def test_capability_detail_not_found(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/capabilities/NONEXISTENT") assert r.status_code == 404 def test_module_detail(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/modules/MOD-PROJECT") assert r.status_code == 200 detail = r.json() assert "module" in detail assert "entities" in detail assert "integrations" in detail assert "codebase_alignment" in detail assert detail["module"]["module_id"] == "MOD-PROJECT" def test_module_detail_not_found(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/modules/NONEXISTENT") assert r.status_code == 404 def test_entity_detail(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/entities/ENT-PROJECT") assert r.status_code == 200 detail = r.json() assert "entity" in detail assert "data_flows" in detail assert detail["entity"]["entity_id"] == "ENT-PROJECT" def test_entity_detail_not_found(client, project_id): client.post(f"/api/projects/{project_id}/scan") r = client.get(f"/api/projects/{project_id}/entities/entities/NONEXISTENT") assert r.status_code == 404 def test_entities_before_scan_returns_404(client, project_id): r = client.get(f"/api/projects/{project_id}/entities/capabilities") assert r.status_code == 404 def test_scan_summary_totals(client, project_id): r = client.post(f"/api/projects/{project_id}/scan") data = r.json() s = data["summary"] assert s["total_files"] == len(data["file_statuses"]) assert s["total_files"] == s["ok"] + s["sparse"] + s["missing"] + s["placeholder_heavy"] + s["template_residue"]