"""TDD — ui_blame commit loading must not read commit_meta.""" from __future__ import annotations import typing from collections.abc import Mapping from datetime import datetime, timezone import pytest from httpx import AsyncClient from muse.core.types import blob_id from sqlalchemy.ext.asyncio import AsyncSession from musehub.db import musehub_repo_models as db from tests.factories import create_repo def _utc() -> datetime: return datetime.now(tz=timezone.utc) async def _add_commit(session: AsyncSession, repo_id: str, seed: str, **kwargs: typing.Any) -> db.MusehubCommit: row = db.MusehubCommit( commit_id=blob_id(seed.encode()), branch="dev", parent_ids=[], message=f"feat: {seed}", author="gabriel", timestamp=_utc(), **kwargs, ) session.add(row) session.add(db.MusehubCommitRef(repo_id=repo_id, commit_id=row.commit_id)) await session.commit() return row # --------------------------------------------------------------------------- # BL1 — blame route does not crash with AttributeError on commit_meta # --------------------------------------------------------------------------- @pytest.mark.asyncio async def test_bl1_blame_route_no_commit_meta_error( db_session: AsyncSession, client: AsyncClient, auth_headers: Mapping[str, str], ) -> None: """Blame page must not raise AttributeError on commit_meta.""" repo = await create_repo(db_session, owner="gabriel", visibility="public") commit = await _add_commit( db_session, repo.repo_id, "blame-c1", agent_id="claude-code", model_id="claude-sonnet-4-6", ) db_session.add(db.MusehubBranch( branch_id=blob_id(b"blame-branch"), repo_id=repo.repo_id, name="dev", head_commit_id=commit.commit_id, )) await db_session.commit() resp = await client.get( f"/gabriel/{repo.slug}/blame/dev/src/app.py", headers=auth_headers, follow_redirects=True, ) # 200 or 404 (no snapshot/file) — anything but 500 assert resp.status_code != 500