From dd02b9d94040c14997af6ff1a837826ab1999084 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Wed, 14 Jan 2026 10:02:33 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F(backend)=20include=20sub=20d?= =?UTF-8?q?ocuments=20in=20the=20favorite=5Flist=20route?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The favorite_list route was returning all the favorite with depth=0. We also want to see favorited document with a depth > 0 --- CHANGELOG.md | 1 + src/backend/core/api/viewsets.py | 19 +++++++++++- .../test_api_documents_favorite_list.py | 31 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb4e3d53..b0561170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to - ✅(e2e) fix e2e test for other browsers #1799 - 🐛(frontend) add fallback for unsupported Blocknote languages #1810 - 🐛(frontend) fix emojipicker closing in tree #1808 +- 🐛(frontend) display children in favorite #1782 ### Changed diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index c4a137ee..3b62b893 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -628,12 +628,29 @@ class DocumentViewSet( """Get list of favorite documents for the current user.""" user = request.user + queryset = self.get_queryset() + + # Among the results, we may have documents that are ancestors/descendants + # of each other. In this case we want to keep only the highest ancestors. + root_paths = utils.filter_root_paths( + queryset.order_by("path").values_list("path", flat=True), + skip_sorting=True, + ) + + path_list = db.Q() + for path in root_paths: + path_list |= db.Q(path__startswith=path) + favorite_documents_ids = models.DocumentFavorite.objects.filter( user=user ).values_list("document_id", flat=True) - queryset = self.filter_queryset(self.get_queryset()) + queryset = self.queryset.filter(path_list) queryset = queryset.filter(id__in=favorite_documents_ids) + queryset = queryset.annotate_user_roles(user) + queryset = queryset.annotate( + is_favorite=db.Value(True, output_field=db.BooleanField()) + ) return self.get_response_for_queryset(queryset) @drf.decorators.action( 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 f93e95e0..d5bfe3c1 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 @@ -83,3 +83,34 @@ def test_api_document_favorite_list_authenticated_with_favorite(): } ], } + + +def test_api_document_favorite_list_with_favorite_children(): + """Authenticated users should receive their favorite documents, including children.""" + + user = factories.UserFactory() + client = APIClient() + client.force_login(user) + + root = factories.DocumentFactory(creator=user, users=[user]) + children = factories.DocumentFactory.create_batch( + 2, parent=root, favorited_by=[user] + ) + + access = factories.UserDocumentAccessFactory( + user=user, role=models.RoleChoices.READER, document__favorited_by=[user] + ) + + other_root = factories.DocumentFactory(creator=user, users=[user]) + factories.DocumentFactory.create_batch(2, parent=other_root) + + response = client.get("/api/v1.0/documents/favorite_list/") + + assert response.status_code == 200 + assert response.json()["count"] == 3 + + content = response.json()["results"] + + assert content[0]["id"] == str(children[0].id) + assert content[1]["id"] == str(children[1].id) + assert content[2]["id"] == str(access.document.id)