Files
devplacepy/tests/api/sync/posts.py
T
retoor 6f80a820da
DevPlace CI / test (push) Failing after 3m13s
Zo doen wijdat in oost
2026-10-16 07:20:44 +02:00

119 lines
5.5 KiB
Python

# retoor <retoor@molodetz.nl>
from devplacepy.database import get_table
from tests.api.sync.conftest import post_record, sync_ok, unique, user_record
def seed_author(client, admin, origin, uid="u1"):
body = sync_ok(client, admin, "users", origin, [user_record(uid, unique("author"))])
return body["results"][0]["local_uid"]
def test_unknown_author_is_rejected_with_reason(client, admin, origin):
body = sync_ok(client, admin, "posts", origin, [post_record(author="missing")])
result = body["results"][0]
assert result["status"] == "rejected" and result["reason"] == "unknown_author"
assert get_table("sync_links").count(origin=origin) == 0
def test_create_normalizes_and_has_no_side_effects(client, admin, origin):
author = seed_author(client, admin, origin)
notifications_before = get_table("notifications").count()
body = sync_ok(
client, admin, "posts", origin,
[post_record("p1", title=" Hello World ", content="line one\r\nline two ok", topic="nonsense", stars=50)],
)
result = body["results"][0]
assert result["status"] == "created" and result["ignored"] == ["stars"]
row = get_table("posts").find_one(uid=result["local_uid"])
assert row["user_uid"] == author
assert row["title"] == "Hello World"
assert row["content"] == "line one\nline two ok"
assert row["topic"] == "random"
assert row["stars"] == 0
assert row["created_at"] == "2025-01-02T00:00:00+00:00"
assert row["slug"].endswith("hello-world")
assert row["deleted_at"] is None
assert get_table("notifications").count() == notifications_before
assert get_table("users").find_one(uid=author)["xp"] == 0
def test_replay_update_stale_and_tombstone(client, admin, origin):
seed_author(client, admin, origin)
created = sync_ok(client, admin, "posts", origin, [post_record("p1")])["results"][0]
assert sync_ok(client, admin, "posts", origin, [post_record("p1")])["results"][0]["status"] == "unchanged"
edited = sync_ok(
client, admin, "posts", origin,
[post_record("p1", content="edited synced content", updated_at="2025-03-01T00:00:00Z")],
)["results"][0]
assert edited["status"] == "updated" and edited["local_uid"] == created["local_uid"]
assert get_table("posts").find_one(uid=created["local_uid"])["content"] == "edited synced content"
stale = sync_ok(
client, admin, "posts", origin,
[post_record("p1", content="older content here", updated_at="2025-01-05T00:00:00Z")],
)["results"][0]
assert stale["status"] == "stale"
deleted = sync_ok(
client, admin, "posts", origin,
[post_record("p1", content="edited synced content", updated_at="2025-04-01T00:00:00Z", deleted=True)],
)["results"][0]
assert deleted["status"] == "updated"
row = get_table("posts").find_one(uid=created["local_uid"])
assert row["deleted_at"] and row["deleted_by"] == "sync"
revived = sync_ok(
client, admin, "posts", origin,
[post_record("p1", content="edited synced content", updated_at="2025-05-01T00:00:00Z")],
)["results"][0]
assert revived["status"] == "updated"
assert get_table("posts").find_one(uid=created["local_uid"])["deleted_at"] is None
def test_locally_moderated_post_is_not_resurrected(client, admin, origin):
seed_author(client, admin, origin)
created = sync_ok(client, admin, "posts", origin, [post_record("p1")])["results"][0]
get_table("posts").update(
{"uid": created["local_uid"], "deleted_at": "2025-02-01T00:00:00+00:00", "deleted_by": admin["uid"]},
["uid"],
)
again = sync_ok(
client, admin, "posts", origin,
[post_record("p1", content="remote edit arrives", updated_at="2025-03-01T00:00:00Z")],
)["results"][0]
assert again["status"] == "unchanged" and again["reason"] == "locally_deleted"
assert get_table("posts").find_one(uid=created["local_uid"])["content"] != "remote edit arrives"
def test_purged_local_copy_is_not_recreated(client, admin, origin):
seed_author(client, admin, origin)
created = sync_ok(client, admin, "posts", origin, [post_record("p1")])["results"][0]
get_table("posts").delete(uid=created["local_uid"])
again = sync_ok(
client, admin, "posts", origin,
[post_record("p1", content="changed after purge", updated_at="2025-03-01T00:00:00Z")],
)["results"][0]
assert again["status"] == "rejected" and again["reason"] == "purged_locally"
assert get_table("posts").count(uid=created["local_uid"]) == 0
def test_invalid_post_reports_field_errors(client, admin, origin):
seed_author(client, admin, origin)
body = sync_ok(client, admin, "posts", origin, [post_record("p1", content="short")])
result = body["results"][0]
assert result["status"] == "rejected" and result["reason"] == "invalid"
assert any(error.startswith("content:") for error in result["errors"])
def test_future_timestamps_are_clamped(client, admin, origin):
seed_author(client, admin, origin)
body = sync_ok(client, admin, "posts", origin, [post_record("p1", created_at="2999-01-01T00:00:00Z")])
row = get_table("posts").find_one(uid=body["results"][0]["local_uid"])
assert row["created_at"] < "2100"
def test_post_shows_up_on_its_detail_page(client, admin, origin):
seed_author(client, admin, origin)
body = sync_ok(client, admin, "posts", origin, [post_record("p1", title="Visible synced post")])
slug = get_table("posts").find_one(uid=body["results"][0]["local_uid"])["slug"]
page = client.get(f"/posts/{slug}")
assert page.status_code == 200 and "Visible synced post" in page.text