generated from coulomb/repo-seed
edit()/overlay()/apply_overlay() on InformationSpace. edit() unifies the write path through one principled route — draft overlay then apply: write-through-capable target fast-forwards (APPLIED), read-only target keeps the draft as local truth (KEPT_DRAFT), external drift refuses (no clobber). Integration tests cover all four. 64 tests green, pyflakes clean. Flips WP-0008 done. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
59 lines
2.3 KiB
Python
59 lines
2.3 KiB
Python
"""End-to-end write-path test (SHARD-WP-0008 T6)."""
|
|
|
|
from shard_wiki import InformationSpace
|
|
from shard_wiki.adapters import FolderAdapter
|
|
from shard_wiki.coordination import ApplyStatus
|
|
from shard_wiki.provenance import OverlayState
|
|
|
|
|
|
def _folder(tmp_path, name, files, writable=False):
|
|
root = tmp_path / name
|
|
root.mkdir(parents=True, exist_ok=True)
|
|
for rel, text in files.items():
|
|
(root / rel).write_text(text, encoding="utf-8")
|
|
return FolderAdapter(name, root, writable=writable)
|
|
|
|
|
|
def test_edit_writethrough_on_writable_shard(tmp_path):
|
|
space = InformationSpace("team")
|
|
space.attach(_folder(tmp_path, "wikiW", {"Home.md": "old"}, writable=True))
|
|
|
|
result = space.edit("Home", "new content")
|
|
assert result.status is ApplyStatus.APPLIED
|
|
assert space.read("Home").body == "new content" # persisted to the shard
|
|
assert space.read("Home").envelope.overlay_state is OverlayState.NONE # overlay closed
|
|
|
|
|
|
def test_edit_on_readonly_shard_keeps_local_draft(tmp_path):
|
|
space = InformationSpace("team")
|
|
space.attach(_folder(tmp_path, "wikiRO", {"Home.md": "canon"}))
|
|
|
|
result = space.edit("Home", "my local edit")
|
|
assert result.status is ApplyStatus.KEPT_DRAFT
|
|
# source untouched; union shows the draft as local truth, clearly flagged
|
|
page = space.read("Home")
|
|
assert page.body == "my local edit"
|
|
assert page.envelope.overlay_state is OverlayState.DRAFT
|
|
|
|
|
|
def test_explicit_overlay_then_apply(tmp_path):
|
|
space = InformationSpace("team")
|
|
space.attach(_folder(tmp_path, "wikiW", {"Doc.md": "v1"}, writable=True))
|
|
ov = space.overlay("Doc", "v2")
|
|
assert space.read("Doc").envelope.overlay_state is OverlayState.DRAFT # pending
|
|
result = space.apply_overlay(ov.overlay_id)
|
|
assert result.status is ApplyStatus.APPLIED
|
|
assert space.read("Doc").body == "v2"
|
|
|
|
|
|
def test_stale_overlay_refuses_after_external_change(tmp_path):
|
|
space = InformationSpace("team")
|
|
shard = _folder(tmp_path, "wikiW", {"Doc.md": "v1"}, writable=True)
|
|
space.attach(shard)
|
|
ov = space.overlay("Doc", "from-v1")
|
|
# an external write moves the shard under the overlay
|
|
shard.write("Doc", "v1-prime")
|
|
result = space.apply_overlay(ov.overlay_id)
|
|
assert result.status is ApplyStatus.REFUSED_DRIFT
|
|
assert space.union.shard("wikiW").read("Doc").body == "v1-prime" # not clobbered
|