repo-manager/tests/test_e2e_vertical_slice.py

117 lines
3.7 KiB
Python
Raw Normal View History

"""E2E vertical slice: observe → index → command → git evidence → rebuild."""
from __future__ import annotations
import json
import subprocess
from pathlib import Path
from repo_manager.commands.task_status import update_task_status
from repo_manager.gitops import head_sha
from repo_manager.index_store import default_index_path, load_index
from repo_manager.observe import observe_repository
WORKPLAN = """---
id: DEMO-WP-0001
type: workplan
title: "Demo workplan"
status: active
---
# Demo workplan
## First task
```task
id: DEMO-WP-0001-T01
status: todo
priority: high
```
Do the thing.
"""
def _git(repo: Path, *args: str) -> None:
subprocess.run(["git", *args], cwd=repo, check=True, capture_output=True)
def _init_fixture(tmp_path: Path) -> Path:
repo = tmp_path / "demo-repo"
repo.mkdir()
_git(repo, "init")
_git(repo, "config", "user.email", "test@example.com")
_git(repo, "config", "user.name", "Test")
(repo / "workplans").mkdir()
(repo / "workplans" / "DEMO-WP-0001-demo.md").write_text(WORKPLAN, encoding="utf-8")
(repo / ".repo-classification.yaml").write_text(
"repo_classification:\n category: experimental\n domain: infotech\n",
encoding="utf-8",
)
(repo / "INTENT.md").write_text("# INTENT\n\nDemo fixture repository.\n", encoding="utf-8")
_git(repo, "add", ".")
_git(repo, "commit", "-m", "seed")
return repo
def test_e2e_vertical_slice(tmp_path: Path):
repo = _init_fixture(tmp_path)
before = head_sha(repo)
assert before
# 12. Observe + index declared work
snap, index = observe_repository(repo, slug="demo-repo")
assert snap["slug"] == "demo-repo"
assert snap["classification"]["category"] == "experimental"
assert snap["index"]["workplan_count"] == 1
assert snap["index"]["task_count"] == 1
tasks = [r for r in index.work_records if r.kind == "task"]
assert tasks[0].id == "DEMO-WP-0001-T01"
assert tasks[0].status == "todo"
# 34. Apply governed file-backed transition + git evidence
result = update_task_status(
repo,
"DEMO-WP-0001-T01",
"progress",
correlation_id="00000000-0000-4000-8000-000000000001",
reason="e2e proof",
)
assert result.status == "applied", result
assert result.evidence.get("git_sha")
assert result.evidence["git_sha"] != before
assert result.evidence["files_touched"] == ["workplans/DEMO-WP-0001-demo.md"]
# File content updated
text = (repo / "workplans" / "DEMO-WP-0001-demo.md").read_text(encoding="utf-8")
assert "status: progress" in text
# 5. Rebuilt projection
snap2, index2 = observe_repository(repo, slug="demo-repo")
task2 = next(r for r in index2.work_records if r.id == "DEMO-WP-0001-T01")
assert task2.status == "progress"
assert snap2["revision"]["head_sha"] == result.evidence["git_sha"]
# Index on disk includes command event (normalized change)
idx_path = default_index_path(repo)
assert idx_path.is_file()
stored = load_index(idx_path)
types = [e.get("type") for e in stored.events]
assert "repo.command.applied" in types
applied = next(e for e in stored.events if e.get("type") == "repo.command.applied")
assert applied["correlation_id"] == "00000000-0000-4000-8000-000000000001"
assert applied["git_sha"] == result.evidence["git_sha"]
# Proof artifact for humans
proof = {
"slice": "RMGR-WP-0001-T05",
"repo_slug": "demo-repo",
"before_sha": before,
"after_sha": result.evidence["git_sha"],
"command": result.to_dict(),
"snapshot_after": snap2,
}
proof_path = tmp_path / "e2e-proof.json"
proof_path.write_text(json.dumps(proof, indent=2), encoding="utf-8")
assert proof_path.stat().st_size > 0