Implement governed function assignment workflows
This commit is contained in:
@@ -9,7 +9,11 @@ from govoplan_core.db.base import Base
|
||||
from govoplan_core.db.session import configure_database, reset_database
|
||||
from govoplan_identity.backend.db import models as identity_models # noqa: F401
|
||||
from govoplan_idm.backend.assignment_lifecycle import SqlIdmAssignmentLifecycle
|
||||
from govoplan_idm.backend.db.models import IdmOrganizationFunctionAssignment
|
||||
from govoplan_idm.backend.db.models import (
|
||||
IdmFunctionAssignmentChange,
|
||||
IdmFunctionAssignmentChangeEvent,
|
||||
IdmOrganizationFunctionAssignment,
|
||||
)
|
||||
from govoplan_organizations.backend.db import models as organization_models # noqa: F401
|
||||
|
||||
|
||||
@@ -20,6 +24,8 @@ class AssignmentExpiryTests(unittest.TestCase):
|
||||
self.database.engine,
|
||||
tables=[
|
||||
IdmOrganizationFunctionAssignment.__table__,
|
||||
IdmFunctionAssignmentChange.__table__,
|
||||
IdmFunctionAssignmentChangeEvent.__table__,
|
||||
ChangeSequenceEntry.__table__,
|
||||
],
|
||||
)
|
||||
@@ -143,6 +149,61 @@ class AssignmentExpiryTests(unittest.TestCase):
|
||||
with self.subTest(limit=value), self.assertRaises(ValueError):
|
||||
self.lifecycle.process_expired(session, limit=value)
|
||||
|
||||
def test_sweep_expires_open_governed_changes_once(self) -> None:
|
||||
boundary = datetime(2026, 7, 31, 12, tzinfo=timezone.utc)
|
||||
with self.database.session() as session:
|
||||
session.add(
|
||||
IdmFunctionAssignmentChange(
|
||||
id="change-due",
|
||||
tenant_id="tenant-1",
|
||||
kind="request",
|
||||
state="awaiting_holder",
|
||||
profile="holder_grant",
|
||||
function_id="function-1",
|
||||
organization_unit_id="unit-1",
|
||||
candidate_identity_id="identity-1",
|
||||
initiator_account_id="account-1",
|
||||
justification="Need the function",
|
||||
evidence=[],
|
||||
assignment_source="governance",
|
||||
required_steps=["holder"],
|
||||
completed_steps=[],
|
||||
policy_decision={},
|
||||
idempotency_key="request-1",
|
||||
expires_at=boundary - timedelta(seconds=1),
|
||||
metadata_={},
|
||||
)
|
||||
)
|
||||
session.commit()
|
||||
|
||||
events: list[PlatformEvent] = []
|
||||
bus = EventBus()
|
||||
bus.subscribe("idm.function_change.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(1, result["expired_changes"])
|
||||
self.assertEqual(["change-due"], result["change_ids"])
|
||||
self.assertEqual(0, repeated["expired_changes"])
|
||||
self.assertEqual(1, len(events))
|
||||
with self.database.session() as session:
|
||||
change = session.get(IdmFunctionAssignmentChange, "change-due")
|
||||
self.assertEqual("expired", change.state)
|
||||
self.assertEqual(2, change.resource_revision)
|
||||
history = session.query(IdmFunctionAssignmentChangeEvent).all()
|
||||
self.assertEqual(["expired"], [item.action for item in history])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user