[claude] Mnemosyne entry update + content deduplication (#1239) (#1241)
Some checks failed
Deploy Nexus / deploy (push) Failing after 4s
Staging Verification Gate / verify-staging (push) Failing after 4s

This commit was merged in pull request #1241.
This commit is contained in:
2026-04-11 23:44:57 +00:00
parent 217ffd7147
commit a14bf80631
3 changed files with 262 additions and 2 deletions

View File

@@ -491,3 +491,178 @@ def test_tag_persistence_across_reload():
fresh = a2.get(e.id)
assert "beta" in fresh.topics
assert "alpha" not in fresh.topics
# --- content_hash and updated_at field tests ---
def test_entry_has_content_hash():
e = ArchiveEntry(title="Hello", content="world")
assert e.content_hash is not None
assert len(e.content_hash) == 64 # SHA-256 hex
def test_entry_content_hash_deterministic():
e1 = ArchiveEntry(title="Hello", content="world")
e2 = ArchiveEntry(title="Hello", content="world")
assert e1.content_hash == e2.content_hash
def test_entry_content_hash_differs_on_different_content():
e1 = ArchiveEntry(title="Hello", content="world")
e2 = ArchiveEntry(title="Hello", content="different")
assert e1.content_hash != e2.content_hash
def test_entry_updated_at_defaults_none():
e = ArchiveEntry(title="T", content="c")
assert e.updated_at is None
def test_entry_roundtrip_includes_new_fields():
e = ArchiveEntry(title="T", content="c")
d = e.to_dict()
assert "content_hash" in d
assert "updated_at" in d
e2 = ArchiveEntry.from_dict(d)
assert e2.content_hash == e.content_hash
assert e2.updated_at == e.updated_at
# --- content deduplication tests ---
def test_add_deduplication_same_content():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
e1 = ingest_event(archive, title="Dup", content="Same content here")
e2 = ingest_event(archive, title="Dup", content="Same content here")
# Should NOT have created a second entry
assert archive.count == 1
assert e1.id == e2.id
def test_add_deduplication_different_content():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
ingest_event(archive, title="A", content="Content one")
ingest_event(archive, title="B", content="Content two")
assert archive.count == 2
def test_find_duplicate_returns_existing():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
e1 = ingest_event(archive, title="Dup", content="Same content here")
probe = ArchiveEntry(title="Dup", content="Same content here")
dup = archive.find_duplicate(probe)
assert dup is not None
assert dup.id == e1.id
def test_find_duplicate_returns_none_for_unique():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
ingest_event(archive, title="A", content="Some content")
probe = ArchiveEntry(title="B", content="Totally different content")
assert archive.find_duplicate(probe) is None
def test_find_duplicate_empty_archive():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
probe = ArchiveEntry(title="X", content="y")
assert archive.find_duplicate(probe) is None
# --- update_entry tests ---
def test_update_entry_title():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
e = ingest_event(archive, title="Old title", content="Some content")
archive.update_entry(e.id, title="New title")
fresh = archive.get(e.id)
assert fresh.title == "New title"
assert fresh.content == "Some content"
def test_update_entry_content():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
e = ingest_event(archive, title="T", content="Old content")
archive.update_entry(e.id, content="New content")
fresh = archive.get(e.id)
assert fresh.content == "New content"
def test_update_entry_metadata():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
e = ingest_event(archive, title="T", content="c")
archive.update_entry(e.id, metadata={"key": "value"})
fresh = archive.get(e.id)
assert fresh.metadata["key"] == "value"
def test_update_entry_bumps_updated_at():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
e = ingest_event(archive, title="T", content="c")
assert e.updated_at is None
archive.update_entry(e.id, title="Updated")
fresh = archive.get(e.id)
assert fresh.updated_at is not None
def test_update_entry_refreshes_content_hash():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
e = ingest_event(archive, title="T", content="Original content")
old_hash = e.content_hash
archive.update_entry(e.id, content="Completely new content")
fresh = archive.get(e.id)
assert fresh.content_hash != old_hash
def test_update_entry_missing_raises():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
try:
archive.update_entry("nonexistent-id", title="X")
assert False, "Expected KeyError"
except KeyError:
pass
def test_update_entry_persists_across_reload():
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
a1 = MnemosyneArchive(archive_path=path)
e = ingest_event(a1, title="Before", content="Before content")
a1.update_entry(e.id, title="After", content="After content")
a2 = MnemosyneArchive(archive_path=path)
fresh = a2.get(e.id)
assert fresh.title == "After"
assert fresh.content == "After content"
assert fresh.updated_at is not None
def test_update_entry_no_change_no_crash():
"""Calling update_entry with all None args should not fail."""
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "test_archive.json"
archive = MnemosyneArchive(archive_path=path)
e = ingest_event(archive, title="T", content="c")
result = archive.update_entry(e.id)
assert result.title == "T"