diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index 3fd349b3..7919033e 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -948,33 +948,34 @@ class DocumentViewSet( **link_kwargs, ) - # Always add the logged-in user as OWNER - accesses_to_create = [ - models.DocumentAccess( - document=duplicated_document, - user=request.user, - role=models.RoleChoices.OWNER, - ) - ] - - # If accesses should be duplicated, add other users' accesses as per original document - if with_accesses and is_owner_or_admin: - original_accesses = models.DocumentAccess.objects.filter( - document=document - ).exclude(user=request.user) - - accesses_to_create.extend( + # Always add the logged-in user as OWNER for root documents + if document.is_root(): + accesses_to_create = [ models.DocumentAccess( document=duplicated_document, - user_id=access.user_id, - team=access.team, - role=access.role, + user=request.user, + role=models.RoleChoices.OWNER, ) - for access in original_accesses - ) + ] - # Bulk create all the duplicated accesses - models.DocumentAccess.objects.bulk_create(accesses_to_create) + # If accesses should be duplicated, add other users' accesses as per original document + if with_accesses and is_owner_or_admin: + original_accesses = models.DocumentAccess.objects.filter( + document=document + ).exclude(user=request.user) + + accesses_to_create.extend( + models.DocumentAccess( + document=duplicated_document, + user_id=access.user_id, + team=access.team, + role=access.role, + ) + for access in original_accesses + ) + + # Bulk create all the duplicated accesses + models.DocumentAccess.objects.bulk_create(accesses_to_create) return drf_response.Response( {"id": str(duplicated_document.id)}, status=status.HTTP_201_CREATED diff --git a/src/backend/core/tests/documents/test_api_documents_duplicate.py b/src/backend/core/tests/documents/test_api_documents_duplicate.py index 8ce7b78a..3a781bb8 100644 --- a/src/backend/core/tests/documents/test_api_documents_duplicate.py +++ b/src/backend/core/tests/documents/test_api_documents_duplicate.py @@ -252,3 +252,44 @@ def test_api_documents_duplicate_with_accesses_non_admin(role): duplicated_accesses = duplicated_document.accesses assert duplicated_accesses.count() == 1 assert duplicated_accesses.get(user=user).role == "owner" + + +@pytest.mark.parametrize("role", ["editor", "reader"]) +def test_api_documents_duplicate_non_root_document(role): + """ + Non-root documents can be duplicated but without accesses. + """ + user = factories.UserFactory() + client = APIClient() + client.force_login(user) + + document = factories.DocumentFactory(users=[(user, "owner")]) + child = factories.DocumentFactory( + parent=document, users=[(user, role)], title="document with accesses" + ) + + assert child.accesses.count() == 1 + + # Duplicate the document via the API endpoint requesting to duplicate accesses + response = client.post( + f"/api/v1.0/documents/{child.id!s}/duplicate/", + {"with_accesses": True}, + format="json", + ) + + assert response.status_code == 201 + + duplicated_document = models.Document.objects.get(id=response.json()["id"]) + assert duplicated_document.title == "Copy of document with accesses" + assert duplicated_document.content == child.content + assert duplicated_document.link_reach == child.link_reach + assert duplicated_document.link_role == child.link_role + assert duplicated_document.creator == user + assert duplicated_document.duplicated_from == child + assert duplicated_document.attachments == [] + + # No access should be created for non root documents + duplicated_accesses = duplicated_document.accesses + assert duplicated_accesses.count() == 0 + assert duplicated_document.is_sibling_of(child) + assert duplicated_document.is_child_of(document)