gabriel / musehub public
test_ui_blob_no_commit_meta.py python
147 lines 4.9 KB
Raw
sha256:34035d72cef530c1ab9d6a6f53be18d803dde705fc3157617d70352a96d0747b Merge branch 'fix/wire-push-external-parent-manifest' into dev Human 8 days ago
1 """TDD — ui_blob helpers must not read commit_meta (dropped in migration 0020).
2
3 Covers:
4 B1 _fetch_file_history reads agent_id/model_id/sem_ver_bump/breaking_changes
5 from first-class ORM columns, not commit_meta
6 B2 blob route provenance block reads from first-class columns
7 """
8 from __future__ import annotations
9
10 import msgpack
11 import pytest
12 from datetime import datetime, timezone
13 from sqlalchemy.ext.asyncio import AsyncSession
14
15 from musehub.db import musehub_repo_models as db
16 from muse.core.types import blob_id
17
18
19 def _utc() -> datetime:
20 return datetime.now(tz=timezone.utc)
21
22
23 async def _make_repo(session: AsyncSession, slug: str) -> str:
24 from musehub.core.genesis import compute_identity_id, compute_repo_id
25 owner = "gabriel"
26 uid = compute_identity_id(owner.encode())
27 created_at = _utc()
28 repo_id = compute_repo_id(uid, slug, "code", created_at.isoformat())
29 session.add(db.MusehubRepo(
30 repo_id=repo_id, name=slug, owner=owner, slug=slug,
31 visibility="public", owner_user_id=uid,
32 description="", tags=[], created_at=created_at,
33 ))
34 await session.commit()
35 return repo_id
36
37
38 async def _add_snapshot(session: AsyncSession, repo_id: str, seed: str, path: str) -> str:
39 snap_id = blob_id(f"snap-{seed}".encode())
40 oid = blob_id(f"blob-{seed}".encode())
41 manifest = {path: oid}
42 session.add(db.MusehubSnapshot(
43 snapshot_id=snap_id,
44 directories=[],
45 manifest_blob=msgpack.packb(manifest, use_bin_type=True),
46 entry_count=1,
47 created_at=_utc(),
48 ))
49 session.add(db.MusehubSnapshotRef(repo_id=repo_id, snapshot_id=snap_id))
50 await session.commit()
51 return snap_id
52
53
54 async def _add_commit(
55 session: AsyncSession,
56 repo_id: str,
57 seed: str,
58 snapshot_id: str,
59 *,
60 agent_id: str = "",
61 model_id: str = "",
62 sem_ver_bump: str = "none",
63 breaking_changes: list[str] | None = None,
64 ) -> db.MusehubCommit:
65 commit_id = blob_id(seed.encode())
66 row = db.MusehubCommit(
67 commit_id=commit_id,
68 branch="dev",
69 parent_ids=[],
70 message=f"feat: {seed}",
71 author="gabriel",
72 timestamp=_utc(),
73 snapshot_id=snapshot_id,
74 agent_id=agent_id,
75 model_id=model_id,
76 sem_ver_bump=sem_ver_bump,
77 breaking_changes=breaking_changes or [],
78 )
79 session.add(row)
80 session.add(db.MusehubCommitRef(repo_id=repo_id, commit_id=commit_id))
81 await session.commit()
82 return row
83
84
85 # ---------------------------------------------------------------------------
86 # B1 — _fetch_file_history reads from first-class columns
87 # ---------------------------------------------------------------------------
88
89 @pytest.mark.asyncio
90 async def test_b1_file_history_reads_first_class_columns(
91 db_session: AsyncSession,
92 ) -> None:
93 from musehub.api.routes.musehub.ui_blob import _fetch_file_history
94
95 repo_id = await _make_repo(db_session, "blob-hist-001")
96 path = "src/app.py"
97 snap_id = await _add_snapshot(db_session, repo_id, "h1", path)
98 commit = await _add_commit(
99 db_session, repo_id, "blob-hist-commit-1", snap_id,
100 agent_id="claude-code", model_id="claude-sonnet-4-6",
101 sem_ver_bump="minor", breaking_changes=[],
102 )
103
104 history = await _fetch_file_history(db_session, repo_id, path, commit.commit_id)
105
106 assert len(history) == 1
107 entry = history[0]
108 assert entry["is_agent"] is True
109 assert entry["model_label"] != ""
110 assert entry["sem_ver_bump"] == "minor"
111 assert entry["breaking"] is False
112
113
114 # ---------------------------------------------------------------------------
115 # B2 — blob route provenance block reads from first-class columns
116 # ---------------------------------------------------------------------------
117
118 @pytest.mark.asyncio
119 async def test_b2_blob_route_provenance_no_commit_meta(
120 db_session: AsyncSession,
121 ) -> None:
122 """The blob route's Phase 1 provenance extraction must not touch commit_meta."""
123 from musehub.api.routes.musehub import ui_blob
124
125 repo_id = await _make_repo(db_session, "blob-prov-001")
126 path = "src/main.py"
127 snap_id = await _add_snapshot(db_session, repo_id, "p1", path)
128 commit = await _add_commit(
129 db_session, repo_id, "blob-prov-commit-1", snap_id,
130 agent_id="claude-code", model_id="claude-sonnet-4-6",
131 sem_ver_bump="patch",
132 )
133
134 # last_commit is a full MusehubCommit row — directly test the attribute reads
135 # that Phase 1 performs (no commit_meta access)
136 last_commit = commit
137 assert not hasattr(last_commit, "commit_meta"), "commit_meta must not exist on ORM row"
138
139 commit_agent_id: str = last_commit.agent_id or ""
140 commit_model_id: str = last_commit.model_id or ""
141 commit_sem_ver_bump: str = last_commit.sem_ver_bump or "none"
142 commit_breaking: bool = bool(last_commit.breaking_changes)
143
144 assert commit_agent_id == "claude-code"
145 assert commit_model_id == "claude-sonnet-4-6"
146 assert commit_sem_ver_bump == "patch"
147 assert commit_breaking is False
File History 15 commits
sha256:34035d72cef530c1ab9d6a6f53be18d803dde705fc3157617d70352a96d0747b Merge branch 'fix/wire-push-external-parent-manifest' into dev Human 8 days ago
sha256:fc04e4cae9e1774d6a21b65c45daeed0e6787eb581d13aa1b03bfe9384a34226 Merge branch 'fix/two-column-scroll-layout' into dev Human 8 days ago
sha256:408916fc5973ba59c6e4eebaa80ebdcc801c0a63205651e25009d11548f79454 chore: bump version to 0.2.0.dev2 — nightly.2, matching muse Sonnet 4.6 patch 11 days ago
sha256:d035733f21ccff27735fddebfbbe0ed24565a32a22db8de5885402262671ecd2 chore: bump version to 0.2.0rc15 for musehub#113 fix release Sonnet 4.6 patch 14 days ago
sha256:0032d6cfa33bc3c8367436ad768e7dd0e339b4332153160247da8266cb5fa352 Merge branch 'task/version-tags-phase3-server' into dev Human 17 days ago
sha256:4669620efda9ff41c55bdefd1f7bfe1c239d468428744c84ead9957e5a003a53 merge: rescue snapshot-recovery hardening (c00aa21d) into d… Opus 4.8 minor 29 days ago
sha256:a59da49c4611b970fc4b6ae48678ce4943261c213a07ddbd73ce9201df869b4a fix: remove false-positive proposal_comments index drop fro… Sonnet 4.6 patch 33 days ago
sha256:0a240d6dbff234f07d98a28a4a9a68db702f3f9ff9260196f24219bdb1c0b6f3 feat: render markdown mists as HTML with heading anchor links Sonnet 4.6 patch 34 days ago
sha256:24a7d47486ebc4ebd1832830580e177ec6f877b48dced8c000e198cdec4ce9d6 Merge 'task/bump-version-rc12' into 'dev' — proposal: Bump … Human 35 days ago
sha256:b9ff931d147e0114a1f17060f415b89ed551c170a91ff226c70437aa5c85f9ee Merge 'task/bump-version-rc12' into 'dev' — proposal: Bump … Human 35 days ago
sha256:d1122d21e73471879b460037b22c0b50fded7c423444a176f248428f75dac39c Merge 'task/fix-issue-pagination-cursor' into 'dev' — propo… Human 35 days ago
sha256:01e18975e73d2b3cd5b6db7929c895bef9aa6e0d4391dc5b2adfc548b41318dd Merge 'feat/adding-debug-logs-to-staging' into 'dev' — prop… Human 35 days ago
sha256:6b1949fc2797ca4c1936a637a4cbfec828ef56cf52398a2e74ca3c4f494e728f fix: use wire_bytes not mpack_bytes_raw in compute_object_b… Sonnet 4.6 patch 48 days ago
sha256:b99f2455dc346966d040133f5203297e6e3ef5803a93728a2c30568d0a0f7583 rename: delta_add → delta_upsert across wire format, models… Sonnet 4.6 patch 50 days ago
sha256:4aed3d8601c8dd3ed37074de35f11f4a9699a0a4b99d43727048fd3f8e6fd13d chore: doc sweep, ignore wrangler build state, misc fixes Sonnet 4.6 minor 50 days ago