From 51d4746435ece6b0462bd6f587f04c3a9848bdc0 Mon Sep 17 00:00:00 2001 From: Manuel Raynaud Date: Fri, 3 Apr 2026 17:50:55 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5(backend)=20remove=20content=20in?= =?UTF-8?q?=20document=20responses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The content was always loaded in the document reponse. We remove this behavior in order to not make an http call to the s3 storage. To get the document content it is needed now to use the new endpoint dedicated to retrive the document content. --- CHANGELOG.md | 1 + src/backend/core/api/serializers.py | 68 ---------- .../test_api_documents_favorite_list.py | 1 - .../documents/test_api_documents_retrieve.py | 54 -------- .../documents/test_api_documents_update.py | 118 ++++-------------- 5 files changed, 23 insertions(+), 219 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 536cf53bd..aaa498e95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ and this project adheres to ### Removed - 🔥(backend) remove deprecated descendants endpoint #2243 +- 🔥(backend) remove content in document responses ## [v4.8.6] - 2026-04-08 diff --git a/src/backend/core/api/serializers.py b/src/backend/core/api/serializers.py index cb5b10e03..d8a2efce4 100644 --- a/src/backend/core/api/serializers.py +++ b/src/backend/core/api/serializers.py @@ -178,7 +178,6 @@ class DocumentLightSerializer(serializers.ModelSerializer): class DocumentSerializer(ListDocumentSerializer): """Serialize documents with all fields for display in detail views.""" - content = serializers.CharField(required=False) websocket = serializers.BooleanField(required=False, write_only=True) file = serializers.FileField( required=False, write_only=True, allow_null=True, max_length=255 @@ -193,7 +192,6 @@ class DocumentSerializer(ListDocumentSerializer): "ancestors_link_role", "computed_link_reach", "computed_link_role", - "content", "created_at", "creator", "deleted_at", @@ -242,13 +240,6 @@ class DocumentSerializer(ListDocumentSerializer): if request: if request.method == "POST": fields["id"].read_only = False - if ( - serializers.BooleanField().to_internal_value( - request.query_params.get("without_content", False) - ) - is True - ): - del fields["content"] return fields @@ -265,18 +256,6 @@ class DocumentSerializer(ListDocumentSerializer): return value - def validate_content(self, value): - """Validate the content field.""" - if not value: - return None - - try: - b64decode(value, validate=True) - except binascii.Error as err: - raise serializers.ValidationError("Invalid base64 content.") from err - - return value - def validate_file(self, file): """Add file size and type constraints as defined in settings.""" if not file: @@ -310,53 +289,6 @@ class DocumentSerializer(ListDocumentSerializer): return instance # No data provided, skip the update return super().update(instance, validated_data) - def save(self, **kwargs): - """ - Process the content field to extract attachment keys and update the document's - "attachments" field for access control. - """ - content = self.validated_data.get("content", "") - extracted_attachments = set(utils.extract_attachments(content)) - - existing_attachments = ( - set(self.instance.attachments or []) if self.instance else set() - ) - new_attachments = extracted_attachments - existing_attachments - - if new_attachments: - attachments_documents = ( - models.Document.objects.filter( - attachments__overlap=list(new_attachments) - ) - .only("path", "attachments") - .order_by("path") - ) - - user = self.context["request"].user - readable_per_se_paths = ( - models.Document.objects.readable_per_se(user) - .order_by("path") - .values_list("path", flat=True) - ) - readable_attachments_paths = utils.filter_descendants( - [doc.path for doc in attachments_documents], - readable_per_se_paths, - skip_sorting=True, - ) - - readable_attachments = set() - for document in attachments_documents: - if document.path not in readable_attachments_paths: - continue - readable_attachments.update(set(document.attachments) & new_attachments) - - # Update attachments with readable keys - self.validated_data["attachments"] = list( - existing_attachments | readable_attachments - ) - - return super().save(**kwargs) - class DocumentContentSerializer(serializers.Serializer): """Serializer for updating only the raw content of a document stored in S3.""" 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 eb9bdefce..e28e0f777 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 @@ -70,7 +70,6 @@ def test_api_document_favorite_list_authenticated_with_favorite(): "created_at": document.created_at.isoformat().replace("+00:00", "Z"), "creator": str(document.creator.id), "deleted_at": None, - "content": document.content, "depth": document.depth, "excerpt": document.excerpt, "id": str(document.id), 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 48c6911ff..5698b37ae 100644 --- a/src/backend/core/tests/documents/test_api_documents_retrieve.py +++ b/src/backend/core/tests/documents/test_api_documents_retrieve.py @@ -71,7 +71,6 @@ def test_api_documents_retrieve_anonymous_public_standalone(): "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), "deleted_at": None, @@ -150,7 +149,6 @@ def test_api_documents_retrieve_anonymous_public_parent(): "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), "deleted_at": None, @@ -262,7 +260,6 @@ def test_api_documents_retrieve_authenticated_unrelated_public_or_authenticated( "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), "depth": 1, @@ -348,7 +345,6 @@ def test_api_documents_retrieve_authenticated_public_or_authenticated_parent(rea "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), "depth": 3, @@ -463,7 +459,6 @@ def test_api_documents_retrieve_authenticated_related_direct(): "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"), "deleted_at": None, @@ -549,7 +544,6 @@ def test_api_documents_retrieve_authenticated_related_parent(): "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"), "depth": 3, @@ -706,7 +700,6 @@ def test_api_documents_retrieve_authenticated_related_team_members( "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), "deleted_at": None, @@ -773,7 +766,6 @@ def test_api_documents_retrieve_authenticated_related_team_administrators( "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), "deleted_at": None, @@ -840,7 +832,6 @@ def test_api_documents_retrieve_authenticated_related_team_owners( "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), "deleted_at": None, @@ -1072,48 +1063,3 @@ def test_api_documents_retrieve_permanently_deleted_related(role, depth): assert response.status_code == 404 assert response.json() == {"detail": "Not found."} - - -def test_api_documents_retrieve_without_content(): - """ - Test retrieve using without_content query string should remove the content in the response - """ - - user = factories.UserFactory() - - document = factories.DocumentFactory(creator=user, users=[(user, "owner")]) - - client = APIClient() - client.force_login(user) - - with mock.patch("core.models.Document.content") as mock_document_content: - response = client.get( - f"/api/v1.0/documents/{document.id!s}/?without_content=true" - ) - - assert response.status_code == 200 - - payload = response.json() - assert "content" not in payload - mock_document_content.assert_not_called() - - -def test_api_documents_retrieve_without_content_invalid_value(): - """ - Test retrieve using without_content query string but an invalid value - should return a 400 - """ - - user = factories.UserFactory() - - document = factories.DocumentFactory(creator=user, users=[(user, "owner")]) - - client = APIClient() - client.force_login(user) - - response = client.get( - f"/api/v1.0/documents/{document.id!s}/?without_content=invalid-value" - ) - assert response.status_code == 400 - - assert response.json() == ["Must be a valid boolean."] 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 1e25ac520..27ac8cc3c 100644 --- a/src/backend/core/tests/documents/test_api_documents_update.py +++ b/src/backend/core/tests/documents/test_api_documents_update.py @@ -19,25 +19,6 @@ from core.tests.conftest import TEAM, USER, VIA pytestmark = pytest.mark.django_db -# A valid Yjs document derived from YDOC_HELLO_WORLD_BASE64 with "Hello" replaced by "World", -# used in PATCH tests to guarantee a real content change distinct from what DocumentFactory -# produces. -YDOC_UPDATED_CONTENT_BASE64 = ( - "AR717vLVDgAHAQ5kb2N1bWVudC1zdG9yZQMKYmxvY2tHcm91cAcA9e7y1Q4AAw5ibG9ja0NvbnRh" - "aW5lcgcA9e7y1Q4BAwdoZWFkaW5nBwD17vLVDgIGBgD17vLVDgMGaXRhbGljAnt9hPXu8tUOBAVX" - "b3JsZIb17vLVDgkGaXRhbGljBG51bGwoAPXu8tUOAg10ZXh0QWxpZ25tZW50AXcEbGVmdCgA9e7y" - "1Q4CBWxldmVsAX0BKAD17vLVDgECaWQBdyQwNGQ2MjM0MS04MzI2LTQyMzYtYTA4My00ODdlMjZm" - "YWQyMzAoAPXu8tUOAQl0ZXh0Q29sb3IBdwdkZWZhdWx0KAD17vLVDgEPYmFja2dyb3VuZENvbG9y" - "AXcHZGVmYXVsdIf17vLVDgEDDmJsb2NrQ29udGFpbmVyBwD17vLVDhADDmJ1bGxldExpc3RJdGVt" - "BwD17vLVDhEGBAD17vLVDhIBd4b17vLVDhMEYm9sZAJ7fYT17vLVDhQCb3KG9e7y1Q4WBGJvbGQE" - "bnVsbIT17vLVDhcCbGQoAPXu8tUOEQ10ZXh0QWxpZ25tZW50AXcEbGVmdCgA9e7y1Q4QAmlkAXck" - "ZDM1MWUwNjgtM2U1NS00MjI2LThlYTUtYWJiMjYzMTk4ZTJhKAD17vLVDhAJdGV4dENvbG9yAXcH" - "ZGVmYXVsdCgA9e7y1Q4QD2JhY2tncm91bmRDb2xvcgF3B2RlZmF1bHSH9e7y1Q4QAw5ibG9ja0Nv" - "bnRhaW5lcgcA9e7y1Q4eAwlwYXJhZ3JhcGgoAPXu8tUOHw10ZXh0QWxpZ25tZW50AXcEbGVmdCgA" - "9e7y1Q4eAmlkAXckODk3MDBjMDctZTBlMS00ZmUwLWFjYTItODQ5MzIwOWE3ZTQyKAD17vLVDh4J" - "dGV4dENvbG9yAXcHZGVmYXVsdCgA9e7y1Q4eD2JhY2tncm91bmRDb2xvcgF3B2RlZmF1bHQA" -) - @pytest.mark.parametrize("via_parent", [True, False]) @pytest.mark.parametrize( @@ -736,25 +717,6 @@ def test_api_documents_update_administrator_or_owner_of_another(via, mock_user_t assert other_document_values == old_document_values -def test_api_documents_update_invalid_content(): - """ - Updating a document with a non base64 encoded content should raise a validation error. - """ - user = factories.UserFactory(with_owned_document=True) - client = APIClient() - client.force_login(user) - - document = factories.DocumentFactory(users=[[user, "owner"]]) - - response = client.put( - f"/api/v1.0/documents/{document.id!s}/", - {"content": "invalid content"}, - format="json", - ) - assert response.status_code == 400 - assert response.json() == {"content": ["Invalid base64 content."]} - - # ============================================================================= # PATCH tests # ============================================================================= @@ -784,11 +746,10 @@ def test_api_documents_patch_anonymous_forbidden(reach, role, via_parent): document = factories.DocumentFactory(link_reach=reach, link_role=role) old_document_values = serializers.DocumentSerializer(instance=document).data - new_content = YDOC_UPDATED_CONTENT_BASE64 response = APIClient().patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) assert response.status_code == 401 @@ -828,11 +789,10 @@ def test_api_documents_patch_authenticated_unrelated_forbidden(reach, role, via_ document = factories.DocumentFactory(link_reach=reach, link_role=role) old_document_values = serializers.DocumentSerializer(instance=document).data - new_content = YDOC_UPDATED_CONTENT_BASE64 response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) @@ -876,11 +836,10 @@ def test_api_documents_patch_anonymous_or_authenticated_unrelated( old_document_values = serializers.DocumentSerializer(instance=document).data old_path = document.path - new_content = YDOC_UPDATED_CONTENT_BASE64 response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content, "websocket": True}, + {"title": "new title", "websocket": True}, format="json", ) assert response.status_code == 200 @@ -889,11 +848,10 @@ def test_api_documents_patch_anonymous_or_authenticated_unrelated( # Force reloading it by fetching the document in the database. document = models.Document.objects.get(id=document.id) assert document.path == old_path - assert document.content == new_content + assert document.title == "new title" document_values = serializers.DocumentSerializer(instance=document).data for key in [ "id", - "title", "link_reach", "link_role", "creator", @@ -933,11 +891,10 @@ def test_api_documents_patch_authenticated_reader(via, via_parent, mock_user_tea ) old_document_values = serializers.DocumentSerializer(instance=document).data - new_content = YDOC_UPDATED_CONTENT_BASE64 response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) @@ -983,11 +940,10 @@ def test_api_documents_patch_authenticated_editor_administrator_or_owner( old_document_values = serializers.DocumentSerializer(instance=document).data old_path = document.path - new_content = YDOC_UPDATED_CONTENT_BASE64 response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content, "websocket": True}, + {"title": "new title", "websocket": True}, format="json", ) assert response.status_code == 200 @@ -996,11 +952,10 @@ def test_api_documents_patch_authenticated_editor_administrator_or_owner( # Force reloading it by fetching the document in the database. document = models.Document.objects.get(id=document.id) assert document.path == old_path - assert document.content == new_content + assert document.title == "new title" document_values = serializers.DocumentSerializer(instance=document).data for key in [ "id", - "title", "link_reach", "link_role", "creator", @@ -1025,7 +980,6 @@ def test_api_documents_patch_authenticated_no_websocket(settings): session_key = client.session.session_key document = factories.DocumentFactory(users=[(user, "editor")]) - new_content = YDOC_UPDATED_CONTENT_BASE64 settings.COLLABORATION_API_URL = "http://example.com/" settings.COLLABORATION_SERVER_SECRET = "secret-token" @@ -1041,7 +995,7 @@ def test_api_documents_patch_authenticated_no_websocket(settings): response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) assert response.status_code == 200 @@ -1050,7 +1004,7 @@ def test_api_documents_patch_authenticated_no_websocket(settings): # Force reloading it by fetching the document from the database. document = models.Document.objects.get(id=document.id) assert document.path == old_path - assert document.content == new_content + assert document.title == "new title" assert cache.get(f"docs:no-websocket:{document.id}") == session_key assert ws_resp.call_count == 1 @@ -1067,7 +1021,6 @@ def test_api_documents_patch_authenticated_no_websocket_user_already_editing(set session_key = client.session.session_key document = factories.DocumentFactory(users=[(user, "editor")]) - new_content = YDOC_UPDATED_CONTENT_BASE64 settings.COLLABORATION_API_URL = "http://example.com/" settings.COLLABORATION_SERVER_SECRET = "secret-token" @@ -1082,7 +1035,7 @@ def test_api_documents_patch_authenticated_no_websocket_user_already_editing(set response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) assert response.status_code == 403 @@ -1103,7 +1056,6 @@ def test_api_documents_patch_no_websocket_other_user_connected_to_websocket(sett session_key = client.session.session_key document = factories.DocumentFactory(users=[(user, "editor")]) - new_content = YDOC_UPDATED_CONTENT_BASE64 settings.COLLABORATION_API_URL = "http://example.com/" settings.COLLABORATION_SERVER_SECRET = "secret-token" @@ -1118,7 +1070,7 @@ def test_api_documents_patch_no_websocket_other_user_connected_to_websocket(sett response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) assert response.status_code == 403 @@ -1139,7 +1091,6 @@ def test_api_documents_patch_user_connected_to_websocket(settings): session_key = client.session.session_key document = factories.DocumentFactory(users=[(user, "editor")]) - new_content = YDOC_UPDATED_CONTENT_BASE64 settings.COLLABORATION_API_URL = "http://example.com/" settings.COLLABORATION_SERVER_SECRET = "secret-token" @@ -1155,7 +1106,7 @@ def test_api_documents_patch_user_connected_to_websocket(settings): response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) assert response.status_code == 200 @@ -1164,7 +1115,7 @@ def test_api_documents_patch_user_connected_to_websocket(settings): # Force reloading it by fetching the document in the database. document = models.Document.objects.get(id=document.id) assert document.path == old_path - assert document.content == new_content + assert document.title == "new title" assert cache.get(f"docs:no-websocket:{document.id}") is None assert ws_resp.call_count == 1 @@ -1183,7 +1134,6 @@ def test_api_documents_patch_websocket_server_unreachable_fallback_to_no_websock session_key = client.session.session_key document = factories.DocumentFactory(users=[(user, "editor")]) - new_content = YDOC_UPDATED_CONTENT_BASE64 settings.COLLABORATION_API_URL = "http://example.com/" settings.COLLABORATION_SERVER_SECRET = "secret-token" @@ -1199,7 +1149,7 @@ def test_api_documents_patch_websocket_server_unreachable_fallback_to_no_websock response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) assert response.status_code == 200 @@ -1208,7 +1158,7 @@ def test_api_documents_patch_websocket_server_unreachable_fallback_to_no_websock # Force reloading it by fetching the document from the database. document = models.Document.objects.get(id=document.id) assert document.path == old_path - assert document.content == new_content + assert document.title == "new title" assert cache.get(f"docs:no-websocket:{document.id}") == session_key assert ws_resp.call_count == 1 @@ -1227,7 +1177,6 @@ def test_api_documents_patch_websocket_server_unreachable_fallback_to_no_websock session_key = client.session.session_key document = factories.DocumentFactory(users=[(user, "editor")]) - new_content = YDOC_UPDATED_CONTENT_BASE64 settings.COLLABORATION_API_URL = "http://example.com/" settings.COLLABORATION_SERVER_SECRET = "secret-token" @@ -1242,7 +1191,7 @@ def test_api_documents_patch_websocket_server_unreachable_fallback_to_no_websock response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) assert response.status_code == 403 @@ -1265,7 +1214,6 @@ def test_api_documents_patch_websocket_server_room_not_found_fallback_to_no_webs session_key = client.session.session_key document = factories.DocumentFactory(users=[(user, "editor")]) - new_content = YDOC_UPDATED_CONTENT_BASE64 settings.COLLABORATION_API_URL = "http://example.com/" settings.COLLABORATION_SERVER_SECRET = "secret-token" @@ -1280,7 +1228,7 @@ def test_api_documents_patch_websocket_server_room_not_found_fallback_to_no_webs response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) assert response.status_code == 403 @@ -1300,7 +1248,6 @@ def test_api_documents_patch_force_websocket_param_to_true(settings): session_key = client.session.session_key document = factories.DocumentFactory(users=[(user, "editor")]) - new_content = YDOC_UPDATED_CONTENT_BASE64 settings.COLLABORATION_API_URL = "http://example.com/" settings.COLLABORATION_SERVER_SECRET = "secret-token" @@ -1315,7 +1262,7 @@ def test_api_documents_patch_force_websocket_param_to_true(settings): response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content, "websocket": True}, + {"title": "new title", "websocket": True}, format="json", ) assert response.status_code == 200 @@ -1324,7 +1271,7 @@ def test_api_documents_patch_force_websocket_param_to_true(settings): # Force reloading it by fetching the document from the database. document = models.Document.objects.get(id=document.id) assert document.path == old_path - assert document.content == new_content + assert document.title == "new title" assert cache.get(f"docs:no-websocket:{document.id}") is None assert ws_resp.call_count == 0 @@ -1340,7 +1287,6 @@ def test_api_documents_patch_feature_flag_disabled(settings): session_key = client.session.session_key document = factories.DocumentFactory(users=[(user, "editor")]) - new_content = YDOC_UPDATED_CONTENT_BASE64 settings.COLLABORATION_API_URL = "http://example.com/" settings.COLLABORATION_SERVER_SECRET = "secret-token" @@ -1356,7 +1302,7 @@ def test_api_documents_patch_feature_flag_disabled(settings): response = client.patch( f"/api/v1.0/documents/{document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) assert response.status_code == 200 @@ -1365,7 +1311,7 @@ def test_api_documents_patch_feature_flag_disabled(settings): # Force reloading it by fetching the document from the database. document = models.Document.objects.get(id=document.id) assert document.path == old_path - assert document.content == new_content + assert document.title == "new title" assert cache.get(f"docs:no-websocket:{document.id}") is None assert ws_resp.call_count == 0 @@ -1396,11 +1342,10 @@ def test_api_documents_patch_administrator_or_owner_of_another(via, mock_user_te other_document = factories.DocumentFactory(title="Old title", link_role="reader") old_document_values = serializers.DocumentSerializer(instance=other_document).data - new_content = YDOC_UPDATED_CONTENT_BASE64 response = client.patch( f"/api/v1.0/documents/{other_document.id!s}/", - {"content": new_content}, + {"title": "new title"}, format="json", ) @@ -1413,25 +1358,6 @@ def test_api_documents_patch_administrator_or_owner_of_another(via, mock_user_te ) -def test_api_documents_patch_invalid_content(): - """ - Patching a document with a non base64 encoded content should raise a validation error. - """ - user = factories.UserFactory(with_owned_document=True) - client = APIClient() - client.force_login(user) - - document = factories.DocumentFactory(users=[[user, "owner"]]) - - response = client.patch( - f"/api/v1.0/documents/{document.id!s}/", - {"content": "invalid content"}, - format="json", - ) - assert response.status_code == 400 - assert response.json() == {"content": ["Invalid base64 content."]} - - @responses.activate def test_api_documents_patch_empty_body(settings): """