From c1fc1bd52fa7bf0c9ddd31b3dac57eafaac7876f Mon Sep 17 00:00:00 2001 From: Samuel Paccoud - DINUM Date: Mon, 28 Apr 2025 21:43:59 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(backend)=20add=20computed=20link=20re?= =?UTF-8?q?ach=20and=20role=20to=20document=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On a document, we need to display the status of the link (reach and role) taking into account the ancestors link reach/role as well as the current document. --- src/backend/core/api/serializers.py | 8 ++ src/backend/core/models.py | 28 +++++++ .../test_api_documents_children_list.py | 28 +++++++ .../test_api_documents_descendants.py | 42 ++++++++++ .../test_api_documents_favorite_list.py | 2 + .../documents/test_api_documents_list.py | 2 + .../documents/test_api_documents_retrieve.py | 18 +++++ .../documents/test_api_documents_trashbin.py | 2 + .../documents/test_api_documents_tree.py | 78 ++++++++++++++++++- .../documents/test_api_documents_update.py | 4 + 10 files changed, 208 insertions(+), 4 deletions(-) diff --git a/src/backend/core/api/serializers.py b/src/backend/core/api/serializers.py index 701733e6..1e1a6ab7 100644 --- a/src/backend/core/api/serializers.py +++ b/src/backend/core/api/serializers.py @@ -181,6 +181,8 @@ class ListDocumentSerializer(serializers.ModelSerializer): "abilities", "ancestors_link_reach", "ancestors_link_role", + "computed_link_reach", + "computed_link_role", "created_at", "creator", "depth", @@ -201,6 +203,8 @@ class ListDocumentSerializer(serializers.ModelSerializer): "abilities", "ancestors_link_reach", "ancestors_link_role", + "computed_link_reach", + "computed_link_role", "created_at", "creator", "depth", @@ -258,6 +262,8 @@ class DocumentSerializer(ListDocumentSerializer): "abilities", "ancestors_link_reach", "ancestors_link_role", + "computed_link_reach", + "computed_link_role", "content", "created_at", "creator", @@ -280,6 +286,8 @@ class DocumentSerializer(ListDocumentSerializer): "abilities", "ancestors_link_reach", "ancestors_link_role", + "computed_link_reach", + "computed_link_role", "created_at", "creator", "depth", diff --git a/src/backend/core/models.py b/src/backend/core/models.py index 64979b46..5ef0fd7a 100644 --- a/src/backend/core/models.py +++ b/src/backend/core/models.py @@ -493,6 +493,7 @@ class Document(MP_Node, BaseModel): """Initialize cache property.""" super().__init__(*args, **kwargs) self._ancestors_link_definition = None + self._computed_link_definition = None def save(self, *args, **kwargs): """Write content to object storage only if _content has changed.""" @@ -716,6 +717,11 @@ class Document(MP_Node, BaseModel): return paths_links_mapping + @property + def link_definition(self): + """Returns link reach/role as a definition in dictionary format.""" + return {"link_reach": self.link_reach, "link_role": self.link_role} + @property def ancestors_link_definition(self): """Link defintion equivalent to all document's ancestors.""" @@ -746,6 +752,28 @@ class Document(MP_Node, BaseModel): """Link role equivalent to all document's ancestors.""" return self.ancestors_link_definition["link_role"] + @property + def computed_link_definition(self): + """ + Link reach/role on the document, combining inherited ancestors' link + definitions and the document's own link definition. + """ + if getattr(self, "_computed_link_definition", None) is None: + self._computed_link_definition = get_equivalent_link_definition( + [self.ancestors_link_definition, self.link_definition] + ) + return self._computed_link_definition + + @property + def computed_link_reach(self): + """Actual link reach on the document.""" + return self.computed_link_definition["link_reach"] + + @property + def computed_link_role(self): + """Actual link role on the document.""" + return self.computed_link_definition["link_role"] + def get_abilities(self, user): """ Compute and return abilities for a given user on the document. diff --git a/src/backend/core/tests/documents/test_api_documents_children_list.py b/src/backend/core/tests/documents/test_api_documents_children_list.py index 26c41204..19bcfd19 100644 --- a/src/backend/core/tests/documents/test_api_documents_children_list.py +++ b/src/backend/core/tests/documents/test_api_documents_children_list.py @@ -37,6 +37,8 @@ def test_api_documents_children_list_anonymous_public_standalone( "abilities": child1.get_abilities(AnonymousUser()), "ancestors_link_reach": "public", "ancestors_link_role": document.link_role, + "computed_link_reach": "public", + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 2, @@ -57,6 +59,8 @@ def test_api_documents_children_list_anonymous_public_standalone( "abilities": child2.get_abilities(AnonymousUser()), "ancestors_link_reach": "public", "ancestors_link_role": document.link_role, + "computed_link_reach": "public", + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 2, @@ -107,6 +111,8 @@ def test_api_documents_children_list_anonymous_public_parent(django_assert_num_q "abilities": child1.get_abilities(AnonymousUser()), "ancestors_link_reach": child1.ancestors_link_reach, "ancestors_link_role": child1.ancestors_link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 4, @@ -127,6 +133,8 @@ def test_api_documents_children_list_anonymous_public_parent(django_assert_num_q "abilities": child2.get_abilities(AnonymousUser()), "ancestors_link_reach": child2.ancestors_link_reach, "ancestors_link_role": child2.ancestors_link_role, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 4, @@ -196,6 +204,8 @@ def test_api_documents_children_list_authenticated_unrelated_public_or_authentic "abilities": child1.get_abilities(user), "ancestors_link_reach": reach, "ancestors_link_role": document.link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 2, @@ -216,6 +226,8 @@ def test_api_documents_children_list_authenticated_unrelated_public_or_authentic "abilities": child2.get_abilities(user), "ancestors_link_reach": reach, "ancestors_link_role": document.link_role, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 2, @@ -271,6 +283,8 @@ def test_api_documents_children_list_authenticated_public_or_authenticated_paren "abilities": child1.get_abilities(user), "ancestors_link_reach": child1.ancestors_link_reach, "ancestors_link_role": child1.ancestors_link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 4, @@ -291,6 +305,8 @@ def test_api_documents_children_list_authenticated_public_or_authenticated_paren "abilities": child2.get_abilities(user), "ancestors_link_reach": child2.ancestors_link_reach, "ancestors_link_role": child2.ancestors_link_role, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 4, @@ -373,6 +389,8 @@ def test_api_documents_children_list_authenticated_related_direct( "abilities": child1.get_abilities(user), "ancestors_link_reach": document.link_reach, "ancestors_link_role": link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 2, @@ -393,6 +411,8 @@ def test_api_documents_children_list_authenticated_related_direct( "abilities": child2.get_abilities(user), "ancestors_link_reach": document.link_reach, "ancestors_link_role": link_role, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 2, @@ -451,6 +471,8 @@ def test_api_documents_children_list_authenticated_related_parent( "abilities": child1.get_abilities(user), "ancestors_link_reach": "restricted", "ancestors_link_role": None, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 4, @@ -471,6 +493,8 @@ def test_api_documents_children_list_authenticated_related_parent( "abilities": child2.get_abilities(user), "ancestors_link_reach": "restricted", "ancestors_link_role": None, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 4, @@ -581,6 +605,8 @@ def test_api_documents_children_list_authenticated_related_team_members( "abilities": child1.get_abilities(user), "ancestors_link_reach": "restricted", "ancestors_link_role": None, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 2, @@ -601,6 +627,8 @@ def test_api_documents_children_list_authenticated_related_team_members( "abilities": child2.get_abilities(user), "ancestors_link_reach": "restricted", "ancestors_link_role": None, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 2, diff --git a/src/backend/core/tests/documents/test_api_documents_descendants.py b/src/backend/core/tests/documents/test_api_documents_descendants.py index fdfd7258..bd2785a7 100644 --- a/src/backend/core/tests/documents/test_api_documents_descendants.py +++ b/src/backend/core/tests/documents/test_api_documents_descendants.py @@ -34,6 +34,8 @@ def test_api_documents_descendants_list_anonymous_public_standalone(): "abilities": child1.get_abilities(AnonymousUser()), "ancestors_link_reach": "public", "ancestors_link_role": document.link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 2, @@ -56,6 +58,8 @@ def test_api_documents_descendants_list_anonymous_public_standalone(): "ancestors_link_role": "editor" if (child1.link_reach == "public" and child1.link_role == "editor") else document.link_role, + "computed_link_reach": "public", + "computed_link_role": grand_child.computed_link_role, "created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"), "creator": str(grand_child.creator.id), "depth": 3, @@ -76,6 +80,8 @@ def test_api_documents_descendants_list_anonymous_public_standalone(): "abilities": child2.get_abilities(AnonymousUser()), "ancestors_link_reach": "public", "ancestors_link_role": document.link_role, + "computed_link_reach": "public", + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 2, @@ -125,6 +131,8 @@ def test_api_documents_descendants_list_anonymous_public_parent(): "abilities": child1.get_abilities(AnonymousUser()), "ancestors_link_reach": "public", "ancestors_link_role": grand_parent.link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 4, @@ -145,6 +153,8 @@ def test_api_documents_descendants_list_anonymous_public_parent(): "abilities": grand_child.get_abilities(AnonymousUser()), "ancestors_link_reach": "public", "ancestors_link_role": grand_child.ancestors_link_role, + "computed_link_reach": "public", + "computed_link_role": grand_child.computed_link_role, "created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"), "creator": str(grand_child.creator.id), "depth": 5, @@ -165,6 +175,8 @@ def test_api_documents_descendants_list_anonymous_public_parent(): "abilities": child2.get_abilities(AnonymousUser()), "ancestors_link_reach": "public", "ancestors_link_role": grand_parent.link_role, + "computed_link_reach": "public", + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 4, @@ -235,6 +247,8 @@ def test_api_documents_descendants_list_authenticated_unrelated_public_or_authen "abilities": child1.get_abilities(user), "ancestors_link_reach": reach, "ancestors_link_role": document.link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 2, @@ -255,6 +269,8 @@ def test_api_documents_descendants_list_authenticated_unrelated_public_or_authen "abilities": grand_child.get_abilities(user), "ancestors_link_reach": reach, "ancestors_link_role": document.link_role, + "computed_link_reach": grand_child.computed_link_reach, + "computed_link_role": grand_child.computed_link_role, "created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"), "creator": str(grand_child.creator.id), "depth": 3, @@ -275,6 +291,8 @@ def test_api_documents_descendants_list_authenticated_unrelated_public_or_authen "abilities": child2.get_abilities(user), "ancestors_link_reach": reach, "ancestors_link_role": document.link_role, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 2, @@ -330,6 +348,8 @@ def test_api_documents_descendants_list_authenticated_public_or_authenticated_pa "abilities": child1.get_abilities(user), "ancestors_link_reach": reach, "ancestors_link_role": grand_parent.link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 4, @@ -350,6 +370,8 @@ def test_api_documents_descendants_list_authenticated_public_or_authenticated_pa "abilities": grand_child.get_abilities(user), "ancestors_link_reach": reach, "ancestors_link_role": grand_parent.link_role, + "computed_link_reach": grand_child.computed_link_reach, + "computed_link_role": grand_child.computed_link_role, "created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"), "creator": str(grand_child.creator.id), "depth": 5, @@ -370,6 +392,8 @@ def test_api_documents_descendants_list_authenticated_public_or_authenticated_pa "abilities": child2.get_abilities(user), "ancestors_link_reach": reach, "ancestors_link_role": grand_parent.link_role, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 4, @@ -446,6 +470,8 @@ def test_api_documents_descendants_list_authenticated_related_direct(): "abilities": child1.get_abilities(user), "ancestors_link_reach": child1.ancestors_link_reach, "ancestors_link_role": child1.ancestors_link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 2, @@ -466,6 +492,8 @@ def test_api_documents_descendants_list_authenticated_related_direct(): "abilities": grand_child.get_abilities(user), "ancestors_link_reach": grand_child.ancestors_link_reach, "ancestors_link_role": grand_child.ancestors_link_role, + "computed_link_reach": grand_child.computed_link_reach, + "computed_link_role": grand_child.computed_link_role, "created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"), "creator": str(grand_child.creator.id), "depth": 3, @@ -486,6 +514,8 @@ def test_api_documents_descendants_list_authenticated_related_direct(): "abilities": child2.get_abilities(user), "ancestors_link_reach": child2.ancestors_link_reach, "ancestors_link_role": child2.ancestors_link_role, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 2, @@ -542,6 +572,8 @@ def test_api_documents_descendants_list_authenticated_related_parent(): "abilities": child1.get_abilities(user), "ancestors_link_reach": child1.ancestors_link_reach, "ancestors_link_role": child1.ancestors_link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 4, @@ -562,6 +594,8 @@ def test_api_documents_descendants_list_authenticated_related_parent(): "abilities": grand_child.get_abilities(user), "ancestors_link_reach": grand_child.ancestors_link_reach, "ancestors_link_role": grand_child.ancestors_link_role, + "computed_link_reach": grand_child.computed_link_reach, + "computed_link_role": grand_child.computed_link_role, "created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"), "creator": str(grand_child.creator.id), "depth": 5, @@ -582,6 +616,8 @@ def test_api_documents_descendants_list_authenticated_related_parent(): "abilities": child2.get_abilities(user), "ancestors_link_reach": child2.ancestors_link_reach, "ancestors_link_role": child2.ancestors_link_role, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 4, @@ -684,6 +720,8 @@ def test_api_documents_descendants_list_authenticated_related_team_members( "abilities": child1.get_abilities(user), "ancestors_link_reach": child1.ancestors_link_reach, "ancestors_link_role": child1.ancestors_link_role, + "computed_link_reach": child1.computed_link_reach, + "computed_link_role": child1.computed_link_role, "created_at": child1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child1.creator.id), "depth": 2, @@ -704,6 +742,8 @@ def test_api_documents_descendants_list_authenticated_related_team_members( "abilities": grand_child.get_abilities(user), "ancestors_link_reach": grand_child.ancestors_link_reach, "ancestors_link_role": grand_child.ancestors_link_role, + "computed_link_reach": grand_child.computed_link_reach, + "computed_link_role": grand_child.computed_link_role, "created_at": grand_child.created_at.isoformat().replace("+00:00", "Z"), "creator": str(grand_child.creator.id), "depth": 3, @@ -724,6 +764,8 @@ def test_api_documents_descendants_list_authenticated_related_team_members( "abilities": child2.get_abilities(user), "ancestors_link_reach": child2.ancestors_link_reach, "ancestors_link_role": child2.ancestors_link_role, + "computed_link_reach": child2.computed_link_reach, + "computed_link_role": child2.computed_link_role, "created_at": child2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(child2.creator.id), "depth": 2, diff --git a/src/backend/core/tests/documents/test_api_documents_favorite_list.py b/src/backend/core/tests/documents/test_api_documents_favorite_list.py index 8b732753..7b9f5ec0 100644 --- a/src/backend/core/tests/documents/test_api_documents_favorite_list.py +++ b/src/backend/core/tests/documents/test_api_documents_favorite_list.py @@ -61,6 +61,8 @@ def test_api_document_favorite_list_authenticated_with_favorite(): "abilities": document.get_abilities(user), "ancestors_link_reach": None, "ancestors_link_role": None, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), "content": document.content, diff --git a/src/backend/core/tests/documents/test_api_documents_list.py b/src/backend/core/tests/documents/test_api_documents_list.py index 6a173f3c..cfaa3e0a 100644 --- a/src/backend/core/tests/documents/test_api_documents_list.py +++ b/src/backend/core/tests/documents/test_api_documents_list.py @@ -65,6 +65,8 @@ def test_api_documents_list_format(): "abilities": document.get_abilities(user), "ancestors_link_reach": None, "ancestors_link_role": None, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), "depth": 1, diff --git a/src/backend/core/tests/documents/test_api_documents_retrieve.py b/src/backend/core/tests/documents/test_api_documents_retrieve.py index 11501332..b229adb5 100644 --- a/src/backend/core/tests/documents/test_api_documents_retrieve.py +++ b/src/backend/core/tests/documents/test_api_documents_retrieve.py @@ -63,6 +63,8 @@ def test_api_documents_retrieve_anonymous_public_standalone(): }, "ancestors_link_reach": None, "ancestors_link_role": None, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "content": document.content, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), @@ -133,6 +135,8 @@ def test_api_documents_retrieve_anonymous_public_parent(): }, "ancestors_link_reach": "public", "ancestors_link_role": grand_parent.link_role, + "computed_link_reach": "public", + "computed_link_role": grand_parent.link_role, "content": document.content, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), @@ -236,6 +240,8 @@ def test_api_documents_retrieve_authenticated_unrelated_public_or_authenticated( }, "ancestors_link_reach": None, "ancestors_link_role": None, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "content": document.content, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), @@ -313,6 +319,8 @@ def test_api_documents_retrieve_authenticated_public_or_authenticated_parent(rea }, "ancestors_link_reach": reach, "ancestors_link_role": grand_parent.link_role, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "content": document.content, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), @@ -425,6 +433,8 @@ def test_api_documents_retrieve_authenticated_related_direct(): "abilities": document.get_abilities(user), "ancestors_link_reach": None, "ancestors_link_role": None, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "content": document.content, "creator": str(document.creator.id), "created_at": document.created_at.isoformat().replace("+00:00", "Z"), @@ -502,6 +512,8 @@ def test_api_documents_retrieve_authenticated_related_parent(): }, "ancestors_link_reach": "restricted", "ancestors_link_role": None, + "computed_link_reach": "restricted", + "computed_link_role": None, "content": document.content, "creator": str(document.creator.id), "created_at": document.created_at.isoformat().replace("+00:00", "Z"), @@ -656,6 +668,8 @@ def test_api_documents_retrieve_authenticated_related_team_members( "abilities": document.get_abilities(user), "ancestors_link_reach": None, "ancestors_link_role": None, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "content": document.content, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), @@ -720,6 +734,8 @@ def test_api_documents_retrieve_authenticated_related_team_administrators( "abilities": document.get_abilities(user), "ancestors_link_reach": None, "ancestors_link_role": None, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "content": document.content, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), @@ -784,6 +800,8 @@ def test_api_documents_retrieve_authenticated_related_team_owners( "abilities": document.get_abilities(user), "ancestors_link_reach": None, "ancestors_link_role": None, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "content": document.content, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), diff --git a/src/backend/core/tests/documents/test_api_documents_trashbin.py b/src/backend/core/tests/documents/test_api_documents_trashbin.py index 2e4c9c13..9e805397 100644 --- a/src/backend/core/tests/documents/test_api_documents_trashbin.py +++ b/src/backend/core/tests/documents/test_api_documents_trashbin.py @@ -105,6 +105,8 @@ def test_api_documents_trashbin_format(): }, "ancestors_link_reach": None, "ancestors_link_role": None, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), "depth": 1, diff --git a/src/backend/core/tests/documents/test_api_documents_tree.py b/src/backend/core/tests/documents/test_api_documents_tree.py index ad79d8b9..0124b507 100644 --- a/src/backend/core/tests/documents/test_api_documents_tree.py +++ b/src/backend/core/tests/documents/test_api_documents_tree.py @@ -43,6 +43,8 @@ def test_api_documents_tree_list_anonymous_public_standalone(django_assert_num_q "ancestors_link_reach": child.ancestors_link_reach, "ancestors_link_role": child.ancestors_link_role, "children": [], + "computed_link_reach": child.computed_link_reach, + "computed_link_role": child.computed_link_role, "created_at": child.created_at.isoformat().replace( "+00:00", "Z" ), @@ -66,6 +68,8 @@ def test_api_documents_tree_list_anonymous_public_standalone(django_assert_num_q ], "ancestors_link_reach": document.ancestors_link_reach, "ancestors_link_role": document.ancestors_link_role, + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), "depth": 2, @@ -87,6 +91,8 @@ def test_api_documents_tree_list_anonymous_public_standalone(django_assert_num_q "ancestors_link_reach": sibling1.ancestors_link_reach, "ancestors_link_role": sibling1.ancestors_link_role, "children": [], + "computed_link_reach": sibling1.computed_link_reach, + "computed_link_role": sibling1.computed_link_role, "created_at": sibling1.created_at.isoformat().replace("+00:00", "Z"), "creator": str(sibling1.creator.id), "depth": 2, @@ -108,6 +114,8 @@ def test_api_documents_tree_list_anonymous_public_standalone(django_assert_num_q "ancestors_link_reach": sibling2.ancestors_link_reach, "ancestors_link_role": sibling2.ancestors_link_role, "children": [], + "computed_link_reach": sibling2.computed_link_reach, + "computed_link_role": sibling2.computed_link_role, "created_at": sibling2.created_at.isoformat().replace("+00:00", "Z"), "creator": str(sibling2.creator.id), "depth": 2, @@ -125,6 +133,8 @@ def test_api_documents_tree_list_anonymous_public_standalone(django_assert_num_q "user_role": None, }, ], + "computed_link_reach": parent.computed_link_reach, + "computed_link_role": parent.computed_link_role, "created_at": parent.created_at.isoformat().replace("+00:00", "Z"), "creator": str(parent.creator.id), "depth": 1, @@ -193,6 +203,8 @@ def test_api_documents_tree_list_anonymous_public_parent(): "ancestors_link_reach": child.ancestors_link_reach, "ancestors_link_role": child.ancestors_link_role, "children": [], + "computed_link_reach": child.computed_link_reach, + "computed_link_role": child.computed_link_role, "created_at": child.created_at.isoformat().replace( "+00:00", "Z" ), @@ -214,6 +226,8 @@ def test_api_documents_tree_list_anonymous_public_parent(): "user_role": None, }, ], + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "created_at": document.created_at.isoformat().replace( "+00:00", "Z" ), @@ -236,9 +250,11 @@ def test_api_documents_tree_list_anonymous_public_parent(): }, { "abilities": document_sibling.get_abilities(AnonymousUser()), - "ancestors_link_reach": document.ancestors_link_reach, - "ancestors_link_role": document.ancestors_link_role, + "ancestors_link_reach": document_sibling.ancestors_link_reach, + "ancestors_link_role": document_sibling.ancestors_link_role, "children": [], + "computed_link_reach": document_sibling.computed_link_reach, + "computed_link_role": document_sibling.computed_link_role, "created_at": document_sibling.created_at.isoformat().replace( "+00:00", "Z" ), @@ -260,6 +276,8 @@ def test_api_documents_tree_list_anonymous_public_parent(): "user_role": None, }, ], + "computed_link_reach": parent.computed_link_reach, + "computed_link_role": parent.computed_link_role, "created_at": parent.created_at.isoformat().replace("+00:00", "Z"), "creator": str(parent.creator.id), "depth": 3, @@ -281,6 +299,8 @@ def test_api_documents_tree_list_anonymous_public_parent(): "ancestors_link_reach": parent_sibling.ancestors_link_reach, "ancestors_link_role": parent_sibling.ancestors_link_role, "children": [], + "computed_link_reach": parent_sibling.computed_link_reach, + "computed_link_role": parent_sibling.computed_link_role, "created_at": parent_sibling.created_at.isoformat().replace( "+00:00", "Z" ), @@ -302,6 +322,8 @@ def test_api_documents_tree_list_anonymous_public_parent(): "user_role": None, }, ], + "computed_link_reach": grand_parent.computed_link_reach, + "computed_link_role": grand_parent.computed_link_role, "created_at": grand_parent.created_at.isoformat().replace("+00:00", "Z"), "creator": str(grand_parent.creator.id), "depth": 2, @@ -377,6 +399,8 @@ def test_api_documents_tree_list_authenticated_unrelated_public_or_authenticated "ancestors_link_reach": child.ancestors_link_reach, "ancestors_link_role": child.ancestors_link_role, "children": [], + "computed_link_reach": child.computed_link_reach, + "computed_link_role": child.computed_link_role, "created_at": child.created_at.isoformat().replace( "+00:00", "Z" ), @@ -398,6 +422,8 @@ def test_api_documents_tree_list_authenticated_unrelated_public_or_authenticated "user_role": None, }, ], + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), "depth": 2, @@ -419,6 +445,8 @@ def test_api_documents_tree_list_authenticated_unrelated_public_or_authenticated "ancestors_link_reach": sibling.ancestors_link_reach, "ancestors_link_role": sibling.ancestors_link_role, "children": [], + "computed_link_reach": sibling.computed_link_reach, + "computed_link_role": sibling.computed_link_role, "created_at": sibling.created_at.isoformat().replace("+00:00", "Z"), "creator": str(sibling.creator.id), "depth": 2, @@ -436,6 +464,8 @@ def test_api_documents_tree_list_authenticated_unrelated_public_or_authenticated "user_role": None, }, ], + "computed_link_reach": parent.computed_link_reach, + "computed_link_role": parent.computed_link_role, "created_at": parent.created_at.isoformat().replace("+00:00", "Z"), "creator": str(parent.creator.id), "depth": 1, @@ -509,6 +539,8 @@ def test_api_documents_tree_list_authenticated_public_or_authenticated_parent( "ancestors_link_reach": child.ancestors_link_reach, "ancestors_link_role": child.ancestors_link_role, "children": [], + "computed_link_reach": child.computed_link_reach, + "computed_link_role": child.computed_link_role, "created_at": child.created_at.isoformat().replace( "+00:00", "Z" ), @@ -530,6 +562,8 @@ def test_api_documents_tree_list_authenticated_public_or_authenticated_parent( "user_role": None, }, ], + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "created_at": document.created_at.isoformat().replace( "+00:00", "Z" ), @@ -555,6 +589,8 @@ def test_api_documents_tree_list_authenticated_public_or_authenticated_parent( "ancestors_link_reach": document_sibling.ancestors_link_reach, "ancestors_link_role": document_sibling.ancestors_link_role, "children": [], + "computed_link_reach": document_sibling.computed_link_reach, + "computed_link_role": document_sibling.computed_link_role, "created_at": document_sibling.created_at.isoformat().replace( "+00:00", "Z" ), @@ -576,6 +612,8 @@ def test_api_documents_tree_list_authenticated_public_or_authenticated_parent( "user_role": None, }, ], + "computed_link_reach": parent.computed_link_reach, + "computed_link_role": parent.computed_link_role, "created_at": parent.created_at.isoformat().replace("+00:00", "Z"), "creator": str(parent.creator.id), "depth": 3, @@ -594,9 +632,11 @@ def test_api_documents_tree_list_authenticated_public_or_authenticated_parent( }, { "abilities": parent_sibling.get_abilities(user), - "ancestors_link_reach": parent.ancestors_link_reach, - "ancestors_link_role": parent.ancestors_link_role, + "ancestors_link_reach": parent_sibling.ancestors_link_reach, + "ancestors_link_role": parent_sibling.ancestors_link_role, "children": [], + "computed_link_reach": parent_sibling.computed_link_reach, + "computed_link_role": parent_sibling.computed_link_role, "created_at": parent_sibling.created_at.isoformat().replace( "+00:00", "Z" ), @@ -618,6 +658,8 @@ def test_api_documents_tree_list_authenticated_public_or_authenticated_parent( "user_role": None, }, ], + "computed_link_reach": grand_parent.computed_link_reach, + "computed_link_role": grand_parent.computed_link_role, "created_at": grand_parent.created_at.isoformat().replace("+00:00", "Z"), "creator": str(grand_parent.creator.id), "depth": 2, @@ -695,6 +737,8 @@ def test_api_documents_tree_list_authenticated_related_direct(): "ancestors_link_reach": child.ancestors_link_reach, "ancestors_link_role": child.ancestors_link_role, "children": [], + "computed_link_reach": child.computed_link_reach, + "computed_link_role": child.computed_link_role, "created_at": child.created_at.isoformat().replace( "+00:00", "Z" ), @@ -716,6 +760,8 @@ def test_api_documents_tree_list_authenticated_related_direct(): "user_role": access.role, }, ], + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), "depth": 2, @@ -737,6 +783,8 @@ def test_api_documents_tree_list_authenticated_related_direct(): "ancestors_link_reach": sibling.ancestors_link_reach, "ancestors_link_role": sibling.ancestors_link_role, "children": [], + "computed_link_reach": sibling.computed_link_reach, + "computed_link_role": sibling.computed_link_role, "created_at": sibling.created_at.isoformat().replace("+00:00", "Z"), "creator": str(sibling.creator.id), "depth": 2, @@ -754,6 +802,8 @@ def test_api_documents_tree_list_authenticated_related_direct(): "user_role": access.role, }, ], + "computed_link_reach": parent.computed_link_reach, + "computed_link_role": parent.computed_link_role, "created_at": parent.created_at.isoformat().replace("+00:00", "Z"), "creator": str(parent.creator.id), "depth": 1, @@ -830,7 +880,9 @@ def test_api_documents_tree_list_authenticated_related_parent(): "abilities": child.get_abilities(user), "ancestors_link_reach": child.ancestors_link_reach, "ancestors_link_role": child.ancestors_link_role, + "computed_link_reach": child.computed_link_reach, "children": [], + "computed_link_role": child.computed_link_role, "created_at": child.created_at.isoformat().replace( "+00:00", "Z" ), @@ -852,6 +904,8 @@ def test_api_documents_tree_list_authenticated_related_parent(): "user_role": access.role, }, ], + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "created_at": document.created_at.isoformat().replace( "+00:00", "Z" ), @@ -877,6 +931,8 @@ def test_api_documents_tree_list_authenticated_related_parent(): "ancestors_link_reach": document_sibling.ancestors_link_reach, "ancestors_link_role": document_sibling.ancestors_link_role, "children": [], + "computed_link_reach": document_sibling.computed_link_reach, + "computed_link_role": document_sibling.computed_link_role, "created_at": document_sibling.created_at.isoformat().replace( "+00:00", "Z" ), @@ -898,6 +954,8 @@ def test_api_documents_tree_list_authenticated_related_parent(): "user_role": access.role, }, ], + "computed_link_reach": parent.computed_link_reach, + "computed_link_role": parent.computed_link_role, "created_at": parent.created_at.isoformat().replace("+00:00", "Z"), "creator": str(parent.creator.id), "depth": 3, @@ -919,6 +977,8 @@ def test_api_documents_tree_list_authenticated_related_parent(): "ancestors_link_reach": parent_sibling.ancestors_link_reach, "ancestors_link_role": parent_sibling.ancestors_link_role, "children": [], + "computed_link_reach": parent_sibling.computed_link_reach, + "computed_link_role": parent_sibling.computed_link_role, "created_at": parent_sibling.created_at.isoformat().replace( "+00:00", "Z" ), @@ -940,6 +1000,8 @@ def test_api_documents_tree_list_authenticated_related_parent(): "user_role": access.role, }, ], + "computed_link_reach": grand_parent.computed_link_reach, + "computed_link_role": grand_parent.computed_link_role, "created_at": grand_parent.created_at.isoformat().replace("+00:00", "Z"), "creator": str(grand_parent.creator.id), "depth": 2, @@ -1025,6 +1087,8 @@ def test_api_documents_tree_list_authenticated_related_team_members( "ancestors_link_reach": "restricted", "ancestors_link_role": None, "children": [], + "computed_link_reach": child.computed_link_reach, + "computed_link_role": child.computed_link_role, "created_at": child.created_at.isoformat().replace( "+00:00", "Z" ), @@ -1046,6 +1110,8 @@ def test_api_documents_tree_list_authenticated_related_team_members( "user_role": access.role, }, ], + "computed_link_reach": document.computed_link_reach, + "computed_link_role": document.computed_link_role, "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), "depth": 2, @@ -1067,6 +1133,8 @@ def test_api_documents_tree_list_authenticated_related_team_members( "ancestors_link_reach": "restricted", "ancestors_link_role": None, "children": [], + "computed_link_reach": sibling.computed_link_reach, + "computed_link_role": sibling.computed_link_role, "created_at": sibling.created_at.isoformat().replace("+00:00", "Z"), "creator": str(sibling.creator.id), "depth": 2, @@ -1084,6 +1152,8 @@ def test_api_documents_tree_list_authenticated_related_team_members( "user_role": access.role, }, ], + "computed_link_reach": parent.computed_link_reach, + "computed_link_role": parent.computed_link_role, "created_at": parent.created_at.isoformat().replace("+00:00", "Z"), "creator": str(parent.creator.id), "depth": 1, diff --git a/src/backend/core/tests/documents/test_api_documents_update.py b/src/backend/core/tests/documents/test_api_documents_update.py index b4c6e2dc..a92354db 100644 --- a/src/backend/core/tests/documents/test_api_documents_update.py +++ b/src/backend/core/tests/documents/test_api_documents_update.py @@ -162,6 +162,8 @@ def test_api_documents_update_anonymous_or_authenticated_unrelated( "id", "ancestors_link_reach", "ancestors_link_role", + "computed_link_reach", + "computed_link_role", "accesses", "created_at", "creator", @@ -281,6 +283,8 @@ def test_api_documents_update_authenticated_editor_administrator_or_owner( "id", "ancestors_link_reach", "ancestors_link_role", + "computed_link_reach", + "computed_link_role", "created_at", "creator", "depth",