refactor: stage effective view resolution
This commit is contained in:
@@ -128,12 +128,14 @@ class ViewsServiceTests(unittest.TestCase):
|
||||
*,
|
||||
name: str,
|
||||
scope_type: str = "tenant",
|
||||
scope_id: str | None = None,
|
||||
visible_surface_ids: list[str] | None = None,
|
||||
):
|
||||
definition = create_definition(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
scope_type=scope_type,
|
||||
scope_id=scope_id,
|
||||
definition_key=None,
|
||||
name=name,
|
||||
description=None,
|
||||
@@ -154,6 +156,30 @@ class ViewsServiceTests(unittest.TestCase):
|
||||
)
|
||||
return definition
|
||||
|
||||
def assign(
|
||||
self,
|
||||
definition,
|
||||
*,
|
||||
scope_type: str,
|
||||
scope_id: str | None,
|
||||
mode: str = "default",
|
||||
priority: int = 0,
|
||||
):
|
||||
return create_assignment(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
scope_type=scope_type,
|
||||
scope_id=scope_id,
|
||||
definition=definition,
|
||||
revision_id=None,
|
||||
mode=mode,
|
||||
priority=priority,
|
||||
is_active=True,
|
||||
metadata={},
|
||||
catalogue=self.catalogue,
|
||||
actor_id="account-admin",
|
||||
)
|
||||
|
||||
def test_normalization_adds_required_surfaces_and_ancestors(self) -> None:
|
||||
normalized = normalize_visible_surface_ids(
|
||||
ordinary_surface_ids(),
|
||||
@@ -311,6 +337,157 @@ class ViewsServiceTests(unittest.TestCase):
|
||||
{option.id for option in state.available_views},
|
||||
)
|
||||
|
||||
def test_scope_precedence_is_system_tenant_group_user(self) -> None:
|
||||
definitions = {
|
||||
"system": self.create_published_definition(
|
||||
name="System",
|
||||
scope_type="system",
|
||||
),
|
||||
"tenant": self.create_published_definition(name="Tenant"),
|
||||
"group": self.create_published_definition(
|
||||
name="Group",
|
||||
scope_type="group",
|
||||
scope_id="group-1",
|
||||
),
|
||||
"user": self.create_published_definition(
|
||||
name="User",
|
||||
scope_type="user",
|
||||
scope_id="account-user",
|
||||
),
|
||||
}
|
||||
self.assign(
|
||||
definitions["system"],
|
||||
scope_type="system",
|
||||
scope_id=None,
|
||||
priority=1000,
|
||||
)
|
||||
self.assign(
|
||||
definitions["tenant"],
|
||||
scope_type="tenant",
|
||||
scope_id=None,
|
||||
priority=100,
|
||||
)
|
||||
self.assign(
|
||||
definitions["group"],
|
||||
scope_type="group",
|
||||
scope_id="group-1",
|
||||
priority=10,
|
||||
)
|
||||
self.assign(
|
||||
definitions["user"],
|
||||
scope_type="user",
|
||||
scope_id="account-user",
|
||||
priority=0,
|
||||
)
|
||||
|
||||
cases = (
|
||||
("account-outsider", (), "tenant"),
|
||||
("account-member", ("group-1",), "group"),
|
||||
("account-user", ("group-1",), "user"),
|
||||
)
|
||||
for account_id, group_ids, expected_scope in cases:
|
||||
with self.subTest(account_id=account_id):
|
||||
state = resolve_effective_view(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
account_id=account_id,
|
||||
group_ids=group_ids,
|
||||
)
|
||||
self.assertEqual(
|
||||
definitions[expected_scope].id,
|
||||
state.effective.view_id,
|
||||
)
|
||||
|
||||
def test_required_then_workflow_then_user_and_default_precedence(self) -> None:
|
||||
default = self.create_published_definition(name="Default")
|
||||
workflow = self.create_published_definition(name="Workflow")
|
||||
required = self.create_published_definition(
|
||||
name="Required",
|
||||
visible_surface_ids=lockout_safe_surface_ids(),
|
||||
)
|
||||
self.assign(
|
||||
default,
|
||||
scope_type="tenant",
|
||||
scope_id=None,
|
||||
mode="default",
|
||||
)
|
||||
self.assign(
|
||||
workflow,
|
||||
scope_type="tenant",
|
||||
scope_id=None,
|
||||
mode="available",
|
||||
)
|
||||
|
||||
workflow_state = resolve_effective_view(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
account_id="account-user",
|
||||
workflow_view_id=workflow.id,
|
||||
)
|
||||
self.assertEqual(workflow.id, workflow_state.effective.view_id)
|
||||
self.assertEqual(
|
||||
"workflow_selection",
|
||||
workflow_state.effective.provenance[0]["source"],
|
||||
)
|
||||
|
||||
self.assign(
|
||||
required,
|
||||
scope_type="tenant",
|
||||
scope_id=None,
|
||||
mode="required",
|
||||
)
|
||||
required_state = resolve_effective_view(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
account_id="account-user",
|
||||
catalogue=self.catalogue,
|
||||
workflow_view_id=workflow.id,
|
||||
)
|
||||
self.assertEqual(required.id, required_state.effective.view_id)
|
||||
self.assertTrue(required_state.effective.locked)
|
||||
self.assertEqual(
|
||||
"required_assignment",
|
||||
required_state.effective.provenance[0]["source"],
|
||||
)
|
||||
|
||||
def test_resolution_invalidation_token_tracks_inputs(self) -> None:
|
||||
definition = self.create_published_definition(name="Files")
|
||||
self.assign(
|
||||
definition,
|
||||
scope_type="tenant",
|
||||
scope_id=None,
|
||||
mode="available",
|
||||
)
|
||||
baseline = resolve_effective_view(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
account_id="account-user",
|
||||
catalogue=self.catalogue,
|
||||
)
|
||||
workflow = resolve_effective_view(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
account_id="account-user",
|
||||
catalogue=self.catalogue,
|
||||
workflow_view_id=definition.id,
|
||||
)
|
||||
reduced_catalogue = resolve_effective_view(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
account_id="account-user",
|
||||
catalogue=self.catalogue[:-1],
|
||||
)
|
||||
|
||||
self.assertIsNotNone(baseline.invalidation_token)
|
||||
self.assertNotEqual(
|
||||
baseline.invalidation_token,
|
||||
workflow.invalidation_token,
|
||||
)
|
||||
self.assertNotEqual(
|
||||
baseline.invalidation_token,
|
||||
reduced_catalogue.invalidation_token,
|
||||
)
|
||||
|
||||
def test_more_specific_available_assignment_cannot_override_required_mode(
|
||||
self,
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user