"""TDD — ui_view helpers must not read commit_meta (dropped in migration 0020). Covers: V1 _slim_commit reads agent_id from first-class column V2 _compute_code_insights SELECT doesn't reference commit_meta V3 _compute_code_insights counts agent commits via agent_id column V4 _compute_code_insights reads sem_ver_bump from column """ from __future__ import annotations import pytest from datetime import datetime, timezone from sqlalchemy.ext.asyncio import AsyncSession from musehub.db import musehub_repo_models as db from muse.core.types import blob_id def _utc() -> datetime: return datetime.now(tz=timezone.utc) async def _make_repo(session: AsyncSession, slug: str) -> str: from musehub.core.genesis import compute_identity_id, compute_repo_id owner = "gabriel" uid = compute_identity_id(owner.encode()) created_at = _utc() repo_id = compute_repo_id(uid, slug, "code", created_at.isoformat()) session.add(db.MusehubRepo( repo_id=repo_id, name=slug, owner=owner, slug=slug, visibility="public", owner_user_id=uid, description="", tags=[], created_at=created_at, )) await session.commit() return repo_id async def _add_commit( session: AsyncSession, repo_id: str, seed: str, *, agent_id: str = "", sem_ver_bump: str = "none", breaking_changes: list[str] | None = None, ) -> db.MusehubCommit: row = db.MusehubCommit( commit_id=blob_id(seed.encode()), branch="dev", parent_ids=[], message=f"feat: {seed}", author="gabriel", timestamp=_utc(), agent_id=agent_id, sem_ver_bump=sem_ver_bump, breaking_changes=breaking_changes or [], ) session.add(row) session.add(db.MusehubCommitRef(repo_id=repo_id, commit_id=row.commit_id)) await session.commit() await session.refresh(row) return row # --------------------------------------------------------------------------- # V1 — _slim_commit reads agent_id from column, not commit_meta # --------------------------------------------------------------------------- @pytest.mark.asyncio async def test_v1_slim_commit_reads_agent_id_from_column( db_session: AsyncSession, ) -> None: from musehub.api.routes.musehub.ui_view import _slim_commit repo_id = await _make_repo(db_session, "view-slim-001") row = await _add_commit(db_session, repo_id, "slim-v1", agent_id="claude-code") result = _slim_commit(row) assert result["agentId"] == "claude-code" assert result["id"] == row.commit_id # --------------------------------------------------------------------------- # V2+V3+V4 — _compute_code_insights doesn't touch commit_meta # --------------------------------------------------------------------------- @pytest.mark.asyncio async def test_v2_code_insights_no_commit_meta_error( db_session: AsyncSession, ) -> None: """_compute_code_insights must not raise AttributeError on commit_meta.""" from musehub.api.routes.musehub.ui_view import _compute_code_insights repo_id = await _make_repo(db_session, "view-insights-001") await _add_commit(db_session, repo_id, "ins-a", agent_id="claude-code", sem_ver_bump="minor") await _add_commit(db_session, repo_id, "ins-b", agent_id="", sem_ver_bump="patch") result = await _compute_code_insights(db_session, repo_id) assert result["agent_count"] == 1 assert result["semver_counts"]["minor"] == 1 assert result["semver_counts"]["patch"] == 1