From a24e9d83a5d2575b7fc2ca81fa47dfdef9aaceb9 Mon Sep 17 00:00:00 2001 From: Bevan Kay Date: Wed, 3 Jan 2024 15:10:23 +1100 Subject: [PATCH] Feature: add `storage_path` parameter to post_document API --- docs/api.md | 1 + src/documents/serialisers.py | 14 ++++++++ src/documents/tests/test_api_documents.py | 44 +++++++++++++++++++++++ src/documents/views.py | 2 ++ 4 files changed, 61 insertions(+) diff --git a/docs/api.md b/docs/api.md index 82244936f..f8aa0cb0f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -274,6 +274,7 @@ The endpoint supports the following optional form fields: - `correspondent`: Specify the ID of a correspondent that the consumer should use for the document. - `document_type`: Similar to correspondent. +- `storage_path`: Similar to correspondent. - `tags`: Similar to correspondent. Specify this multiple times to have multiple tags added to the document. - `archive_serial_number`: An optional archive serial number to set. diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index c65d4d2ff..95be6fcf6 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -964,6 +964,14 @@ class PostDocumentSerializer(serializers.Serializer): required=False, ) + storage_path = serializers.PrimaryKeyRelatedField( + queryset=StoragePath.objects.all(), + label="Storage path", + allow_null=True, + write_only=True, + required=False, + ) + tags = serializers.PrimaryKeyRelatedField( many=True, queryset=Tag.objects.all(), @@ -1002,6 +1010,12 @@ class PostDocumentSerializer(serializers.Serializer): return document_type.id else: return None + + def validate_storage_path(self, storage_path): + if storage_path: + return storage_path.id + else: + return None def validate_tags(self, tags): if tags: diff --git a/src/documents/tests/test_api_documents.py b/src/documents/tests/test_api_documents.py index 8415b9a71..2e6ad5529 100644 --- a/src/documents/tests/test_api_documents.py +++ b/src/documents/tests/test_api_documents.py @@ -958,6 +958,7 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase): self.assertIsNone(overrides.title) self.assertIsNone(overrides.tag_ids) + def test_upload_with_invalid_document_type(self): self.consume_file_mock.return_value = celery.result.AsyncResult( id=str(uuid.uuid4()), @@ -975,6 +976,49 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase): self.consume_file_mock.assert_not_called() + def test_upload_with_storage_path(self): + self.consume_file_mock.return_value = celery.result.AsyncResult( + id=str(uuid.uuid4()), + ) + + sp = StoragePath.objects.create(name="invoices") + with open( + os.path.join(os.path.dirname(__file__), "samples", "simple.pdf"), + "rb", + ) as f: + response = self.client.post( + "/api/documents/post_document/", + {"document": f, "storage_path": sp.id}, + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + self.consume_file_mock.assert_called_once() + + _, overrides = self.get_last_consume_delay_call_args() + + self.assertEqual(overrides.storage_path_id, sp.id) + self.assertIsNone(overrides.correspondent_id) + self.assertIsNone(overrides.title) + self.assertIsNone(overrides.tag_ids) + + + def test_upload_with_invalid_storage_path(self): + self.consume_file_mock.return_value = celery.result.AsyncResult( + id=str(uuid.uuid4()), + ) + + with open( + os.path.join(os.path.dirname(__file__), "samples", "simple.pdf"), + "rb", + ) as f: + response = self.client.post( + "/api/documents/post_document/", + {"document": f, "storage_path": 34578}, + ) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + + self.consume_file_mock.assert_not_called() + def test_upload_with_tags(self): self.consume_file_mock.return_value = celery.result.AsyncResult( id=str(uuid.uuid4()), diff --git a/src/documents/views.py b/src/documents/views.py index e8c6db0de..8a223f76f 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -839,6 +839,7 @@ class PostDocumentView(GenericAPIView): doc_name, doc_data = serializer.validated_data.get("document") correspondent_id = serializer.validated_data.get("correspondent") document_type_id = serializer.validated_data.get("document_type") + storage_path_id = serializer.validated_data.get("storage_path") tag_ids = serializer.validated_data.get("tags") title = serializer.validated_data.get("title") created = serializer.validated_data.get("created") @@ -865,6 +866,7 @@ class PostDocumentView(GenericAPIView): title=title, correspondent_id=correspondent_id, document_type_id=document_type_id, + storage_path_id=storage_path_id, tag_ids=tag_ids, created=created, asn=archive_serial_number,