Files
devplacepy/tests/unit/services/sync/healing.py
T
retoorandClaude Sonnet 5.5 02ab747cd0
DevPlace CI / test (push) Failing after 44m45s
Code Farm: per-plot auto-replant pause and crop-lock check; community sync and node work
Continuous Delivery could never be turned off once a crop was planted. Add a
one-shot per-plot "stop after harvest" flag (POST /game/plot/stop, Devii tool
game_plot_stop, game_plots.stop_after_harvest), cleared by the next plant,
autoreplant claim or Refactor. Autoreplant now also respects crop locks through
the shared _crop_lock predicate. Plan and measurements in happyplanting.md.

Also includes the pending community sync, node network and related work in the
tree; the full suite passed (4999) with all of it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-17 02:23:43 +02:00

100 lines
4.1 KiB
Python

# retoor <retoor@molodetz.nl>
import pytest
from devplacepy.database import get_table, init_db
from devplacepy.database.sync import claim_identity, claim_link
from devplacepy.services.sync.healing import AliasHealer
from devplacepy.services.sync.processors import UserProcessor
from devplacepy.utils import generate_uid
ORIGIN = "heal.example.org"
@pytest.fixture(autouse=True)
def clean(local_db):
init_db()
for table in ("sync_identities", "sync_links"):
get_table(table).delete(origin=ORIGIN)
yield
for table in ("sync_identities", "sync_links"):
get_table(table).delete(origin=ORIGIN)
def clone(source="alice", alias="Mira"):
suffix = generate_uid()[-6:]
alias = f"{alias}{suffix}"
processor = UserProcessor(ORIGIN)
result = processor.process(0, {"origin_uid": source, "username": alias, "created_at": "2026-01-01T00:00:00Z"})
claim_identity(ORIGIN, source.capitalize(), source, alias, "style", False)
return result.local_uid, alias
def synced_text(origin_uid, table, text, kind):
uid = generate_uid()
get_table(table).insert(
{"uid": uid, "user_uid": "u", "title": None, "content": text, "created_at": "2026-01-01T00:00:00+00:00", "target_uid": "x", "target_type": "post", "deleted_at": None, "deleted_by": None}
)
claim_link(ORIGIN, kind, origin_uid, uid, "fp", "2026-01-01T00:00:00+00:00")
return uid
def test_nothing_changes_when_the_clone_still_has_the_alias():
clone()
report = AliasHealer(ORIGIN).heal()
assert not report.renamed and not report.conflicts and report.rewritten == 0
def test_an_administrator_rename_moves_the_identity_and_the_stored_mentions():
uid, alias = clone()
post = synced_text("p1", "posts", f"thanks @{alias} and {alias} again, @{alias}x stays", "posts")
comment = synced_text("c1", "comments", f"@{alias.lower()} agreed", "comments")
other = synced_text("p2", "posts", "unrelated text", "posts")
renamed = f"Renamed{generate_uid()[-6:]}"
get_table("users").update({"uid": uid, "username": renamed}, ["uid"])
report = AliasHealer(ORIGIN).heal()
assert report.renamed == {alias: renamed} and report.rewritten == 2
row = get_table("sync_identities").find_one(origin=ORIGIN, source_key="alice")
assert row["our_name"] == renamed and row["our_key"] == renamed.lower()
assert get_table("posts").find_one(uid=post)["content"] == f"thanks @{renamed} and {renamed} again, @{alias}x stays"
assert get_table("comments").find_one(uid=comment)["content"] == f"@{renamed} agreed"
assert get_table("posts").find_one(uid=other)["content"] == "unrelated text"
assert not AliasHealer(ORIGIN).heal().renamed
def test_a_suffixed_clone_name_is_adopted(local_db):
uid, alias = clone("bob", "Taken")
suffixed = f"{alias}-heal"
get_table("users").update({"uid": uid, "username": suffixed}, ["uid"])
assert AliasHealer(ORIGIN).heal().renamed == {alias: suffixed}
assert get_table("sync_identities").find_one(origin=ORIGIN, source_key="bob")["our_name"] == suffixed
def test_a_name_that_belongs_to_another_identity_is_a_conflict_not_a_steal():
first_uid, first_alias = clone("alice", "Una")
_, second_alias = clone("carol", "Duo")
get_table("users").update({"uid": first_uid, "username": second_alias}, ["uid"])
report = AliasHealer(ORIGIN).heal()
assert report.conflicts == ["alice"] and not report.renamed
assert get_table("sync_identities").find_one(origin=ORIGIN, source_key="alice")["our_name"] == first_alias
def test_a_purged_clone_is_ignored():
uid, _ = clone()
get_table("users").delete(uid=uid)
assert AliasHealer(ORIGIN).heal().renamed == {}
def test_the_rewrite_work_per_run_is_bounded(monkeypatch):
from dataclasses import replace
from devplacepy.services.sync import healing
from devplacepy.services.sync.spec import ALIAS
uid, alias = clone()
for index in range(5):
synced_text(f"p{index}", "posts", f"hello @{alias}", "posts")
monkeypatch.setattr(healing, "ALIAS", replace(ALIAS, heal_rewrites_per_run=2))
get_table("users").update({"uid": uid, "username": f"Bounded{generate_uid()[-6:]}"}, ["uid"])
assert AliasHealer(ORIGIN).heal().rewritten == 2