feat: reconcile scheduling calendar holds

This commit is contained in:
2026-08-20 07:44:15 +02:00
parent 4bbf80e634
commit 93fb8aeff8
3 changed files with 170 additions and 6 deletions
+76 -4
View File
@@ -1,7 +1,7 @@
from __future__ import annotations
import unittest
from datetime import datetime, timezone
from datetime import datetime, timedelta, timezone
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
@@ -28,11 +28,29 @@ from govoplan_tenancy.backend.db.models import Tenant
class CalendarSchedulingCapabilityTests(unittest.TestCase):
def test_event_request_validation_is_exposed_as_capability_error(self) -> None:
provider = SqlCalendarSchedulingProvider()
def setUp(self) -> None:
self.engine = create_engine("sqlite:///:memory:")
create_scope_tables(self.engine)
Base.metadata.create_all(bind=self.engine)
self.Session = sessionmaker(bind=self.engine)
self.session = self.Session()
self.session.add(Tenant(id="tenant-1", slug="tenant-1", name="Tenant"))
self.calendar = create_calendar(
self.session,
tenant_id="tenant-1",
user_id=None,
payload=CalendarCollectionCreateRequest(name="Scheduling"),
)
self.provider = SqlCalendarSchedulingProvider()
def tearDown(self) -> None:
self.session.close()
Base.metadata.drop_all(bind=self.engine)
self.engine.dispose()
def test_event_request_validation_is_exposed_as_capability_error(self) -> None:
with self.assertRaises(CalendarCapabilityError):
provider.create_event(
self.provider.create_event(
object(),
tenant_id="tenant-1",
user_id="user-1",
@@ -42,6 +60,60 @@ class CalendarSchedulingCapabilityTests(unittest.TestCase):
),
)
def test_hold_promotion_and_release_are_idempotent(self) -> None:
start = datetime(2026, 7, 20, 9, tzinfo=timezone.utc)
hold = self.provider.create_event(
self.session,
tenant_id="tenant-1",
user_id="user-1",
request=CalendarEventRequest(
calendar_id=self.calendar.id,
summary="Tentative hold",
status="TENTATIVE",
start_at=start,
end_at=start + timedelta(hours=1),
metadata={"scheduling_request_id": "request-1"},
),
)
promoted = self.provider.promote_event(
self.session,
tenant_id="tenant-1",
user_id="user-1",
event_id=hold.id,
request=CalendarEventRequest(
calendar_id=self.calendar.id,
summary="Confirmed meeting",
status="CONFIRMED",
start_at=start,
end_at=start + timedelta(hours=1),
metadata={"scheduling_request_id": "request-1"},
),
)
released = self.provider.release_event(
self.session,
tenant_id="tenant-1",
user_id="user-1",
event_id=promoted.id,
)
replayed = self.provider.release_event(
self.session,
tenant_id="tenant-1",
user_id="user-1",
event_id=promoted.id,
)
absent = self.provider.release_event(
self.session,
tenant_id="tenant-1",
user_id="user-1",
event_id="missing-event",
)
self.assertEqual(promoted.id, hold.id)
self.assertEqual("CONFIRMED", self.session.get(CalendarEvent, hold.id).status)
self.assertFalse(released.already_released)
self.assertTrue(replayed.already_released)
self.assertEqual("not_found", absent.external_state)
class CalendarExternalProfileCapabilityTests(unittest.TestCase):
def setUp(self) -> None: