diff --git a/src/backend/core/choices.py b/src/backend/core/choices.py index f1a0e298..e6b97511 100644 --- a/src/backend/core/choices.py +++ b/src/backend/core/choices.py @@ -65,49 +65,22 @@ class LinkReachChoices(PriorityTextChoices): def get_select_options(cls, link_reach, link_role): """ Determines the valid select options for link reach and link role depending on the - list of ancestors' link reach/role definitions. + ancestors' link reach/role given as arguments. Returns: Dictionary mapping possible reach levels to their corresponding possible roles. """ - # If no ancestors, return all options - if not link_reach: - return { - reach: LinkRoleChoices.values if reach != cls.RESTRICTED else None - for reach in cls.values - } - - # Initialize the result for all reaches with possible roles - result = { - reach: set(LinkRoleChoices.values) if reach != cls.RESTRICTED else None - for reach in cls.values - } - - # Handle special rules directly with early returns for efficiency - - if link_role == LinkRoleChoices.EDITOR: - # Rule 1: public/editor → override everything - if link_reach == cls.PUBLIC: - return {cls.PUBLIC: [LinkRoleChoices.EDITOR]} - - # Rule 2: authenticated/editor - if link_reach == cls.AUTHENTICATED: - result[cls.AUTHENTICATED].discard(LinkRoleChoices.READER) - result.pop(cls.RESTRICTED, None) - - if link_role == LinkRoleChoices.READER: - # Rule 3: public/reader - if link_reach == cls.PUBLIC: - result.pop(cls.AUTHENTICATED, None) - result.pop(cls.RESTRICTED, None) - - # Rule 4: authenticated/reader - if link_reach == cls.AUTHENTICATED: - result.pop(cls.RESTRICTED, None) - - # Convert sets to ordered lists where applicable return { - reach: sorted(roles, key=LinkRoleChoices.get_priority) if roles else roles - for reach, roles in result.items() + reach: [ + role + for role in LinkRoleChoices.values + if LinkRoleChoices.get_priority(role) + >= LinkRoleChoices.get_priority(link_role) + ] + if reach != cls.RESTRICTED + else None + for reach in cls.values + if LinkReachChoices.get_priority(reach) + >= LinkReachChoices.get_priority(link_reach) } diff --git a/src/backend/core/tests/test_models_documents.py b/src/backend/core/tests/test_models_documents.py index 7542d375..57427fb9 100644 --- a/src/backend/core/tests/test_models_documents.py +++ b/src/backend/core/tests/test_models_documents.py @@ -1186,7 +1186,6 @@ def test_models_documents_restore_complex_bis(django_assert_num_queries): @pytest.mark.parametrize( "reach, role, select_options", [ - # One ancestor ( "public", "reader", @@ -1206,7 +1205,7 @@ def test_models_documents_restore_complex_bis(django_assert_num_queries): ( "authenticated", "editor", - {"authenticated": ["editor"], "public": ["reader", "editor"]}, + {"authenticated": ["editor"], "public": ["editor"]}, ), ( "restricted", @@ -1222,18 +1221,16 @@ def test_models_documents_restore_complex_bis(django_assert_num_queries): "editor", { "restricted": None, - "authenticated": ["reader", "editor"], - "public": ["reader", "editor"], + "authenticated": ["editor"], + "public": ["editor"], }, ), - # No ancestors (edge case) + # Edge cases ( "public", None, { "public": ["reader", "editor"], - "authenticated": ["reader", "editor"], - "restricted": None, }, ), (