gabriel / musehub public
test_phase5_blast_risk_nav.py python
117 lines 3.6 KB
Raw
sha256:ef10830ce231e0a20efcb0e2586cb879471247e916616e6fdd0d51df459e2595 fix: typing audit — 0 violations, 0 untyped defs across all… Sonnet 4.6 minor ⚠ breaking 21 days ago
1 """TDD spec for Phase 5 — navigation + Intel Hub integration (issue #11).
2
3 Verifies:
4 - Back link to /intel on list page and empty-state
5 - Page title contains "Blast Risk"
6 - Detail page back link to /intel/blast-risk
7 - Detail page title contains "Blast Risk"
8
9 Layers:
10 P5_01 list page — back link to /intel present
11 P5_02 list empty-state — back link to /intel present
12 P5_03 list page — title contains "Blast Risk"
13 P5_04 detail page — back link to /intel/blast-risk present
14 P5_05 detail page — title contains "Blast Risk"
15 """
16 from __future__ import annotations
17
18 import secrets
19
20 import pytest
21 import pytest_asyncio
22 from httpx import AsyncClient
23 from sqlalchemy.dialects.postgresql import insert as pg_insert
24 from sqlalchemy.ext.asyncio import AsyncSession
25
26 from muse.core.types import fake_id, long_id
27 from musehub.db.musehub_intel_models import MusehubIntelBlastRisk
28 from musehub.db.musehub_repo_models import MusehubRepo
29 from tests.factories import create_repo
30
31
32 def _uid() -> str:
33 return fake_id(secrets.token_hex(16))
34
35
36 _OWNER = "testuser"
37 _SLUG = "brnav"
38 _REF = long_id("e" * 64)
39
40
41 async def _seed_risk(session: AsyncSession, repo_id: str, *, address: str) -> None:
42 stmt = (
43 pg_insert(MusehubIntelBlastRisk)
44 .values(
45 repo_id=repo_id,
46 address=address,
47 kind="function",
48 risk="high",
49 risk_score=60,
50 impact_score=0.5,
51 churn_score=0.5,
52 test_gap_score=1.0,
53 coupling_score=0.3,
54 ref=_REF,
55 )
56 .on_conflict_do_nothing()
57 )
58 await session.execute(stmt)
59 await session.flush()
60
61
62 @pytest_asyncio.fixture
63 async def nav_repo(db_session: AsyncSession) -> MusehubRepo:
64 return await create_repo(db_session, owner=_OWNER, slug=_SLUG)
65
66
67 @pytest_asyncio.fixture
68 async def nav_repo_with_row(db_session: AsyncSession, nav_repo: MusehubRepo) -> MusehubRepo:
69 repo_id = nav_repo.repo_id
70 await db_session.commit()
71 await _seed_risk(db_session, repo_id, address="pkg/nav.py::nav_fn")
72 await db_session.commit()
73 return nav_repo
74
75
76 class TestBlastRiskNav:
77
78 @pytest.mark.asyncio
79 async def test_P5_01_list_page_has_back_link_to_intel(
80 self, client: AsyncClient, nav_repo_with_row: MusehubRepo
81 ) -> None:
82 resp = await client.get(f"/{_OWNER}/{_SLUG}/intel/blast-risk")
83 assert "/intel" in resp.text
84
85 @pytest.mark.asyncio
86 async def test_P5_02_empty_list_has_back_link_to_intel(
87 self, client: AsyncClient, nav_repo: MusehubRepo
88 ) -> None:
89 resp = await client.get(f"/{_OWNER}/{_SLUG}/intel/blast-risk")
90 assert "/intel" in resp.text
91
92 @pytest.mark.asyncio
93 async def test_P5_03_list_page_title_contains_blast_risk(
94 self, client: AsyncClient, nav_repo: MusehubRepo
95 ) -> None:
96 resp = await client.get(f"/{_OWNER}/{_SLUG}/intel/blast-risk")
97 assert "Blast Risk" in resp.text
98
99 @pytest.mark.asyncio
100 async def test_P5_04_detail_page_has_back_link_to_blast_risk(
101 self, client: AsyncClient, nav_repo_with_row: MusehubRepo
102 ) -> None:
103 resp = await client.get(
104 f"/{_OWNER}/{_SLUG}/intel/blast-risk/detail",
105 params={"address": "pkg/nav.py::nav_fn"},
106 )
107 assert "blast-risk" in resp.text
108
109 @pytest.mark.asyncio
110 async def test_P5_05_detail_page_title_contains_blast_risk(
111 self, client: AsyncClient, nav_repo_with_row: MusehubRepo
112 ) -> None:
113 resp = await client.get(
114 f"/{_OWNER}/{_SLUG}/intel/blast-risk/detail",
115 params={"address": "pkg/nav.py::nav_fn"},
116 )
117 assert "Blast Risk" in resp.text
File History 1 commit
sha256:ef10830ce231e0a20efcb0e2586cb879471247e916616e6fdd0d51df459e2595 fix: typing audit — 0 violations, 0 untyped defs across all… Sonnet 4.6 minor 21 days ago