Add CalDAV outbox recovery UI
This commit is contained in:
@@ -18,6 +18,7 @@ from govoplan_calendar.backend.caldav import (
|
||||
from govoplan_calendar.backend.db.models import CalendarOutboxOperation
|
||||
from govoplan_calendar.backend.outbox import (
|
||||
SqlCalendarOutboxProvider,
|
||||
calendar_outbox_operation_action_states,
|
||||
claim_next_calendar_outbox_operation,
|
||||
discard_calendar_outbox_operation,
|
||||
dispatch_calendar_outbox,
|
||||
@@ -508,6 +509,66 @@ class CalendarOutboxTests(unittest.TestCase):
|
||||
operation_id=first.id,
|
||||
)
|
||||
|
||||
def test_recovery_action_state_is_batched_and_respects_source_state(self) -> None:
|
||||
event = self.create_local_event(summary="First")
|
||||
self.session.commit()
|
||||
operation = self.session.query(CalendarOutboxOperation).one()
|
||||
|
||||
state = calendar_outbox_operation_action_states(
|
||||
self.session,
|
||||
[operation],
|
||||
)[operation.id]
|
||||
self.assertFalse(state["retry"]["allowed"])
|
||||
self.assertTrue(state["reconcile"]["allowed"])
|
||||
self.assertTrue(state["discard"]["allowed"])
|
||||
|
||||
operation.status = "conflict"
|
||||
self.source.sync_enabled = False
|
||||
self.session.flush()
|
||||
disabled = calendar_outbox_operation_action_states(
|
||||
self.session,
|
||||
[operation],
|
||||
)[operation.id]
|
||||
self.assertFalse(disabled["retry"]["allowed"])
|
||||
self.assertIn("disabled", str(disabled["retry"]["reason"]))
|
||||
self.assertFalse(disabled["reconcile"]["allowed"])
|
||||
self.assertTrue(disabled["discard"]["allowed"])
|
||||
|
||||
self.source.sync_enabled = True
|
||||
update_event(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
user_id=None,
|
||||
event_id=event.id,
|
||||
payload=CalendarEventUpdateRequest(summary="Second"),
|
||||
)
|
||||
self.session.flush()
|
||||
stale = calendar_outbox_operation_action_states(
|
||||
self.session,
|
||||
[operation],
|
||||
)[operation.id]
|
||||
self.assertFalse(any(item["allowed"] for item in stale.values()))
|
||||
self.assertIn("newer desired state", str(stale["discard"]["reason"]))
|
||||
|
||||
def test_manual_retry_cannot_be_repeated_while_pending(self) -> None:
|
||||
self.create_local_event()
|
||||
self.session.commit()
|
||||
operation = self.session.query(CalendarOutboxOperation).one()
|
||||
operation.status = "dead"
|
||||
self.session.flush()
|
||||
|
||||
retry_calendar_outbox_operation(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
operation_id=operation.id,
|
||||
)
|
||||
with self.assertRaisesRegex(ValueError, "pending"):
|
||||
retry_calendar_outbox_operation(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
operation_id=operation.id,
|
||||
)
|
||||
|
||||
def test_discard_latest_cancels_attempted_predecessor_chain(self) -> None:
|
||||
event = self.create_local_event(summary="First")
|
||||
self.session.commit()
|
||||
|
||||
Reference in New Issue
Block a user