diff --git a/src/documents/filters.py b/src/documents/filters.py index 6abadabc0..4c2aa1ecf 100644 --- a/src/documents/filters.py +++ b/src/documents/filters.py @@ -25,6 +25,7 @@ from django.db.models import Sum from django.db.models import Value from django.db.models import When from django.db.models.functions import Cast +from django.db.models.functions import NullIf from django.utils.translation import gettext_lazy as _ from django_filters import DateFilter from django_filters.rest_framework import BooleanFilter @@ -868,6 +869,9 @@ class DocumentFilterSet(FilterSet): if self._user is not None else getattr(self.request, "user", None) ) + queryset = queryset.alias( + nonempty_archive_checksum=NullIf("archive_checksum", Value("")), + ) visible_root_documents = Document.global_objects.filter( root_document__isnull=True, @@ -876,11 +880,12 @@ class DocumentFilterSet(FilterSet): include_deleted=True, ), ).exclude(pk=OuterRef("pk")) + # see serialisers._get_viewable_duplicates(). matching_duplicates = visible_root_documents.filter( Q(checksum=OuterRef("checksum")) - | Q(checksum=OuterRef("archive_checksum")) + | Q(checksum=OuterRef("nonempty_archive_checksum")) | Q(archive_checksum=OuterRef("checksum")) - | Q(archive_checksum=OuterRef("archive_checksum")), + | Q(archive_checksum=OuterRef("nonempty_archive_checksum")), ) return queryset.alias( diff --git a/src/documents/tests/test_api_documents.py b/src/documents/tests/test_api_documents.py index 76b43ab93..2aceb3fc9 100644 --- a/src/documents/tests/test_api_documents.py +++ b/src/documents/tests/test_api_documents.py @@ -1009,6 +1009,16 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase): checksum="second-archive-source", archive_checksum="same-archive-only", ) + first_empty_archive = Document.objects.create( + title="first empty archive", + checksum="first-empty-archive", + archive_checksum="", + ) + second_empty_archive = Document.objects.create( + title="second empty archive", + checksum="second-empty-archive", + archive_checksum="", + ) unique = Document.objects.create(title="unique", checksum="unique") version_root = Document.objects.create( title="version root", @@ -1051,9 +1061,17 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertCountEqual( [document["id"] for document in response.data["results"]], - [unique.id, version_root.id], + [ + unique.id, + version_root.id, + first_empty_archive.id, + second_empty_archive.id, + ], ) + response = self.client.get(f"/api/documents/{first_empty_archive.id}/") + self.assertEqual(response.data["duplicate_documents"], []) + def test_has_duplicates_filter_respects_document_permissions(self) -> None: owner = User.objects.create_user(username="duplicate-owner") requester = User.objects.create_user(username="duplicate-requester")