feat: reconcile scheduling calendar holds
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user