generated from coulomb/repo-seed
52 lines
1.9 KiB
Python
52 lines
1.9 KiB
Python
from api.edge.outbox import OutboxStore, PayloadRejected
|
|
from api.services.write_idempotency import route_class_for
|
|
|
|
|
|
def test_route_classifier_matches_safe_writes():
|
|
assert route_class_for("POST", "/progress/") == "append"
|
|
assert route_class_for("PATCH", "/tasks/abc") == "replace"
|
|
assert route_class_for("DELETE", "/tasks/abc") is None
|
|
|
|
|
|
def test_outbox_scrubs_secret_fields_and_tracks_status(tmp_path):
|
|
store = OutboxStore(tmp_path / "outbox.sqlite3")
|
|
envelope = store.enqueue(
|
|
method="POST",
|
|
path="/progress/",
|
|
body={"summary": "offline", "password": "secret", "tokens_in": 12},
|
|
source_agent="pytest",
|
|
source_host="host-a",
|
|
)
|
|
|
|
assert envelope.status == "queued"
|
|
assert envelope.route_class == "append"
|
|
assert envelope.body["password"] == "[redacted]"
|
|
assert envelope.body["tokens_in"] == 12
|
|
assert store.summary()["pending_count"] == 1
|
|
|
|
store.mark_acked(envelope.id, response_status=201, response_body={"id": "central"})
|
|
acked = store.get(envelope.id)
|
|
assert acked.status == "acked"
|
|
assert acked.response_body == {"id": "central"}
|
|
assert store.summary()["pending_count"] == 0
|
|
|
|
|
|
def test_outbox_rejects_non_queueable_routes(tmp_path):
|
|
store = OutboxStore(tmp_path / "outbox.sqlite3")
|
|
try:
|
|
store.enqueue(method="DELETE", path="/tasks/abc", body={})
|
|
except PayloadRejected as exc:
|
|
assert "not queueable" in str(exc)
|
|
else:
|
|
raise AssertionError("DELETE should not be queueable")
|
|
|
|
|
|
def test_replace_writes_coalesce_superseded_queued_envelopes(tmp_path):
|
|
store = OutboxStore(tmp_path / "outbox.sqlite3")
|
|
first = store.enqueue(method="PATCH", path="/tasks/task-1", body={"status": "progress"})
|
|
second = store.enqueue(method="PATCH", path="/tasks/task-1", body={"status": "done"})
|
|
|
|
assert store.get(first.id).status == "cancelled"
|
|
assert store.get(second.id).status == "queued"
|
|
assert len(store.due()) == 1
|