Implement typed effective identity relationships
This commit is contained in:
@@ -12,7 +12,9 @@ from govoplan_idm.backend.assignment_lifecycle import SqlIdmAssignmentLifecycle
|
||||
from govoplan_idm.backend.db.models import (
|
||||
IdmFunctionAssignmentChange,
|
||||
IdmFunctionAssignmentChangeEvent,
|
||||
IdmIdentityRelationship,
|
||||
IdmOrganizationFunctionAssignment,
|
||||
IdmTypedGroup,
|
||||
)
|
||||
from govoplan_organizations.backend.db import models as organization_models # noqa: F401
|
||||
|
||||
@@ -26,6 +28,8 @@ class AssignmentExpiryTests(unittest.TestCase):
|
||||
IdmOrganizationFunctionAssignment.__table__,
|
||||
IdmFunctionAssignmentChange.__table__,
|
||||
IdmFunctionAssignmentChangeEvent.__table__,
|
||||
IdmTypedGroup.__table__,
|
||||
IdmIdentityRelationship.__table__,
|
||||
ChangeSequenceEntry.__table__,
|
||||
],
|
||||
)
|
||||
@@ -204,6 +208,60 @@ class AssignmentExpiryTests(unittest.TestCase):
|
||||
history = session.query(IdmFunctionAssignmentChangeEvent).all()
|
||||
self.assertEqual(["expired"], [item.action for item in history])
|
||||
|
||||
def test_sweep_emits_relationship_expiry_once(self) -> None:
|
||||
boundary = datetime(2026, 8, 2, 12, tzinfo=timezone.utc)
|
||||
with self.database.session() as session:
|
||||
session.add(
|
||||
IdmTypedGroup(
|
||||
id="group-1",
|
||||
tenant_id="tenant-1",
|
||||
key="eligible",
|
||||
name="Eligible",
|
||||
group_type="business_status",
|
||||
)
|
||||
)
|
||||
session.add(
|
||||
IdmIdentityRelationship(
|
||||
id="relationship-due",
|
||||
tenant_id="tenant-1",
|
||||
relationship_kind="member",
|
||||
subject_identity_id="identity-1",
|
||||
target_group_id="group-1",
|
||||
valid_until=boundary - timedelta(seconds=1),
|
||||
status="active",
|
||||
properties={},
|
||||
provenance={},
|
||||
)
|
||||
)
|
||||
session.commit()
|
||||
|
||||
events: list[PlatformEvent] = []
|
||||
bus = EventBus()
|
||||
bus.subscribe("idm.relationship.expired.v1", events.append)
|
||||
with self.database.SessionLocal() as session, event_bus_context(bus):
|
||||
result = self.lifecycle.process_expired(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
effective_at=boundary,
|
||||
)
|
||||
session.commit()
|
||||
repeated = self.lifecycle.process_expired(
|
||||
session,
|
||||
tenant_id="tenant-1",
|
||||
effective_at=boundary,
|
||||
)
|
||||
session.commit()
|
||||
|
||||
self.assertEqual(["relationship-due"], result["relationship_ids"])
|
||||
self.assertEqual(1, result["expired_relationships"])
|
||||
self.assertEqual(0, repeated["expired_relationships"])
|
||||
self.assertEqual(1, len(events))
|
||||
self.assertEqual("identity-1", events[0].subject.id)
|
||||
with self.database.session() as session:
|
||||
item = session.get(IdmIdentityRelationship, "relationship-due")
|
||||
self.assertEqual(2, item.revision)
|
||||
self.assertIsNotNone(item.expired_event_at)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user