49981e2d6e
apply_values, EntryGitState, read_entry_from_git, write_entry_files, sidecar_path_for. Plus the SLICE-4 implementation plan. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
109 lines
3.6 KiB
Python
109 lines
3.6 KiB
Python
"""SLICE-4 — git-aware sidecar read/write helpers.
|
|
|
|
Uses the FakeGitea from the propose-vertical fixtures (no network).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
|
|
import yaml
|
|
|
|
from app import gitea as gitea_mod, metadata
|
|
from app.config import load_config
|
|
|
|
from test_propose_vertical import app_with_fake_gitea, tmp_env # noqa: F401
|
|
|
|
LEGACY = """---
|
|
slug: alpha
|
|
title: Alpha
|
|
state: active
|
|
owners:
|
|
- ben.stull
|
|
tags:
|
|
- one
|
|
priority: P1
|
|
---
|
|
|
|
Alpha body.
|
|
"""
|
|
|
|
MIGRATED_MD = "Alpha body.\n"
|
|
MIGRATED_SIDECAR = """slug: alpha
|
|
title: Alpha
|
|
state: active
|
|
owners:
|
|
- ben.stull
|
|
tags:
|
|
- one
|
|
priority: P1
|
|
"""
|
|
|
|
|
|
def _gitea():
|
|
return gitea_mod.Gitea(load_config())
|
|
|
|
|
|
def test_read_entry_from_git_legacy(app_with_fake_gitea):
|
|
_app, fake = app_with_fake_gitea
|
|
fake.files[("wiggleverse", "meta", "main", "rfcs/alpha.md")] = {
|
|
"content": LEGACY, "sha": "s1"}
|
|
st = asyncio.run(metadata.read_entry_from_git(
|
|
_gitea(), "wiggleverse", "meta", "rfcs/alpha.md"))
|
|
assert st is not None
|
|
assert st.entry.slug == "alpha"
|
|
assert st.entry.extra["priority"] == "P1"
|
|
assert st.sidecar_sha is None # no sidecar yet
|
|
assert st.malformed is False
|
|
|
|
|
|
def test_read_entry_from_git_migrated(app_with_fake_gitea):
|
|
_app, fake = app_with_fake_gitea
|
|
fake.files[("wiggleverse", "meta", "main", "rfcs/alpha.md")] = {
|
|
"content": MIGRATED_MD, "sha": "s1"}
|
|
fake.files[("wiggleverse", "meta", "main", "rfcs/alpha.meta.yaml")] = {
|
|
"content": MIGRATED_SIDECAR, "sha": "s2"}
|
|
st = asyncio.run(metadata.read_entry_from_git(
|
|
_gitea(), "wiggleverse", "meta", "rfcs/alpha.md"))
|
|
assert st.entry.extra["priority"] == "P1" # from sidecar
|
|
assert st.entry.body == "Alpha body.\n"
|
|
assert st.sidecar_sha == "s2"
|
|
|
|
|
|
def test_read_entry_from_git_missing(app_with_fake_gitea):
|
|
st = asyncio.run(metadata.read_entry_from_git(
|
|
_gitea(), "wiggleverse", "meta", "rfcs/nope.md"))
|
|
assert st is None
|
|
|
|
|
|
def test_write_entry_files_lazy_migrates_legacy(app_with_fake_gitea):
|
|
_app, fake = app_with_fake_gitea
|
|
fake.files[("wiggleverse", "meta", "main", "rfcs/alpha.md")] = {
|
|
"content": LEGACY, "sha": "s1"}
|
|
st = asyncio.run(metadata.read_entry_from_git(
|
|
_gitea(), "wiggleverse", "meta", "rfcs/alpha.md"))
|
|
e2 = metadata.apply_values(st.entry, {"priority": "P0"})
|
|
ops = metadata.write_entry_files("rfcs/alpha.md", e2, st)
|
|
paths = {o["path"]: o for o in ops}
|
|
# sidecar created, .md rewritten body-only
|
|
assert "rfcs/alpha.meta.yaml" in paths
|
|
assert paths["rfcs/alpha.meta.yaml"]["operation"] == "create"
|
|
assert paths["rfcs/alpha.md"]["operation"] == "update"
|
|
assert "---" not in paths["rfcs/alpha.md"]["content"] # INV-2 clean body
|
|
assert yaml.safe_load(paths["rfcs/alpha.meta.yaml"]["content"])["priority"] == "P0"
|
|
|
|
|
|
def test_write_entry_files_already_migrated_touches_sidecar_only(app_with_fake_gitea):
|
|
_app, fake = app_with_fake_gitea
|
|
fake.files[("wiggleverse", "meta", "main", "rfcs/alpha.md")] = {
|
|
"content": MIGRATED_MD, "sha": "s1"}
|
|
fake.files[("wiggleverse", "meta", "main", "rfcs/alpha.meta.yaml")] = {
|
|
"content": MIGRATED_SIDECAR, "sha": "s2"}
|
|
st = asyncio.run(metadata.read_entry_from_git(
|
|
_gitea(), "wiggleverse", "meta", "rfcs/alpha.md"))
|
|
e2 = metadata.apply_values(st.entry, {"priority": "P0"})
|
|
ops = metadata.write_entry_files("rfcs/alpha.md", e2, st)
|
|
paths = {o["path"]: o for o in ops}
|
|
assert set(paths) == {"rfcs/alpha.meta.yaml"} # .md untouched
|
|
assert paths["rfcs/alpha.meta.yaml"]["operation"] == "update"
|
|
assert paths["rfcs/alpha.meta.yaml"]["sha"] == "s2"
|