Complete effective assignment expiry lifecycle

This commit is contained in:
2026-07-31 18:07:36 +02:00
parent d1c5738ca8
commit f025b0c25b
13 changed files with 619 additions and 59 deletions
+108 -4
View File
@@ -14,17 +14,48 @@ from govoplan_organizations.backend.db import models as organization_models # n
class StubIdentityDirectory:
def __init__(self, identities: tuple[IdentityRef, ...] = ()) -> None:
self.identities = identities
def get_identity(self, identity_id: str) -> IdentityRef | None:
return None
return next(
(item for item in self.identities if item.id == identity_id),
None,
)
def identity_for_account(self, account_id: str) -> IdentityRef | None:
return None
return next(
(
item
for item in self.identities
if account_id in item.account_ids
or item.primary_account_id == account_id
),
None,
)
def identities_for_accounts(self, account_ids: tuple[str, ...]) -> tuple[IdentityRef, ...]:
return ()
requested = set(account_ids)
return tuple(
item
for item in self.identities
if requested.intersection(item.account_ids)
or item.primary_account_id in requested
)
def accounts_for_identity(self, identity_id: str) -> tuple[IdentityAccountLinkRef, ...]:
return ()
identity = self.get_identity(identity_id)
if identity is None:
return ()
return tuple(
IdentityAccountLinkRef(
id=f"{identity_id}:{account_id}",
identity_id=identity_id,
account_id=account_id,
is_primary=account_id == identity.primary_account_id,
)
for account_id in identity.account_ids
)
class StubOrganizationDirectory:
@@ -227,6 +258,79 @@ class IdmDirectoryDelegationTests(unittest.TestCase):
tenant_id="tenant-2",
)
def test_batch_accounts_preserve_account_and_subunit_provenance(self) -> None:
self.directory = SqlIdmDirectory(
identities=StubIdentityDirectory(
(
IdentityRef(
id="identity-shared",
primary_account_id="account-1",
account_ids=("account-1", "account-2"),
),
)
), # type: ignore[arg-type]
organizations=StubOrganizationDirectory(), # type: ignore[arg-type]
)
broad = IdmOrganizationFunctionAssignment(
id="broad",
tenant_id="tenant-1",
identity_id="identity-shared",
account_id=None,
function_id="function-1",
organization_unit_id="unit-1",
applies_to_subunits=True,
source="direct",
is_active=True,
settings={},
)
account_specific = IdmOrganizationFunctionAssignment(
id="account-specific",
tenant_id="tenant-1",
identity_id="identity-shared",
account_id="account-2",
function_id="function-2",
organization_unit_id="unit-1",
source="governance",
is_active=True,
settings={},
)
simultaneous = IdmOrganizationFunctionAssignment(
id="second-incumbent",
tenant_id="tenant-1",
identity_id="identity-second",
function_id="function-1",
organization_unit_id="unit-1",
source="direct",
is_active=True,
settings={},
)
with self.database.session() as session:
session.add_all((broad, account_specific, simultaneous))
session.commit()
resolved = self.directory.organization_function_assignments_for_accounts(
("account-1", "account-2", "missing"),
tenant_id="tenant-1",
)
self.assertEqual(("broad",), tuple(item.id for item in resolved["account-1"]))
self.assertEqual(
("broad", "account-specific"),
tuple(item.id for item in resolved["account-2"]),
)
self.assertEqual((), resolved["missing"])
self.assertTrue(resolved["account-1"][0].applies_to_subunits)
self.assertEqual("governance", resolved["account-2"][1].source)
incumbency = self.directory.organization_function_incumbencies(
("function-1",),
tenant_id="tenant-1",
)["function-1"]
self.assertEqual(
("broad", "second-incumbent"),
tuple(item.id for item in incumbency.assignments),
)
self.assertFalse(incumbency.vacant)
if __name__ == "__main__":
unittest.main()