diff --git a/src/openforms/registrations/contrib/objects_api/registration_variables.py b/src/openforms/registrations/contrib/objects_api/registration_variables.py index c4b069ccc1..c9d680f285 100644 --- a/src/openforms/registrations/contrib/objects_api/registration_variables.py +++ b/src/openforms/registrations/contrib/objects_api/registration_variables.py @@ -11,6 +11,8 @@ from openforms.variables.base import BaseStaticVariable from openforms.variables.constants import FormVariableDataTypes +from .models import ObjectsAPISubmissionAttachment + if TYPE_CHECKING: from openforms.submissions.models import Submission @@ -60,6 +62,18 @@ def get_initial_value(self, submission: Submission | None = None): return submission.objects_api_registration_data.csv_url +@register("attachment_urls") +class AttachmentUrls(BaseStaticVariable): + name = _("Attachment URLs") + data_type = FormVariableDataTypes.array + + def get_initial_value(self, submission: Submission | None = None) -> list[str]: + attachments = ObjectsAPISubmissionAttachment.objects.filter( + submission_file_attachment__submission_step__submission=submission + ) + return list(attachments.values_list("document_url", flat=True)) + + @register("payment_completed") class PaymentCompleted(BaseStaticVariable): name = _("Payment completed") diff --git a/src/openforms/registrations/contrib/objects_api/tests/files/vcr_cassettes/ObjectsAPIBackendV2Tests/ObjectsAPIBackendV2Tests.test_submission_with_file_components_container_variable.yaml b/src/openforms/registrations/contrib/objects_api/tests/files/vcr_cassettes/ObjectsAPIBackendV2Tests/ObjectsAPIBackendV2Tests.test_submission_with_file_components_container_variable.yaml new file mode 100644 index 0000000000..e885536ddb --- /dev/null +++ b/src/openforms/registrations/contrib/objects_api/tests/files/vcr_cassettes/ObjectsAPIBackendV2Tests/ObjectsAPIBackendV2Tests.test_submission_with_file_components_container_variable.yaml @@ -0,0 +1,210 @@ +interactions: +- request: + body: '{"informatieobjecttype": "http://localhost:8003/catalogi/api/v1/informatieobjecttypen/531f6c1a-97f7-478c-85f0-67d2f23661c7", + "bronorganisatie": "000000000", "creatiedatum": "2024-03-19", "titel": "Form + 000", "auteur": "Aanvrager", "taal": "nld", "formaat": "text/xml", "inhoud": + "Y29udGVudA==", "status": "definitief", "bestandsnaam": "attachment1.jpg", "ontvangstdatum": + "2024-03-02", "beschrijving": "Bijgevoegd document", "indicatieGebruiksrecht": + false, "bestandsomvang": 7}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Authorization: + - Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0X2NsaWVudF9pZCIsImlhdCI6MTcxMDg1NTYzNCwiY2xpZW50X2lkIjoidGVzdF9jbGllbnRfaWQiLCJ1c2VyX2lkIjoiIiwidXNlcl9yZXByZXNlbnRhdGlvbiI6IiJ9.NJjZEPSwh9eGzntjwUB7rFAiaq_5DqYgVylWuKdtdMA + Connection: + - keep-alive + Content-Length: + - '478' + Content-Type: + - application/json + User-Agent: + - python-requests/2.32.2 + method: POST + uri: http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten + response: + body: + string: '{"url":"http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten/fe8ee354-2965-43c5-926e-803242704984","identificatie":"DOCUMENT-2024-0000000085","bronorganisatie":"000000000","creatiedatum":"2024-03-19","titel":"Form + 000","vertrouwelijkheidaanduiding":"openbaar","auteur":"Aanvrager","status":"definitief","formaat":"text/xml","taal":"nld","versie":1,"beginRegistratie":"2024-11-20T22:05:00.402914Z","bestandsnaam":"attachment1.jpg","inhoud":"http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten/fe8ee354-2965-43c5-926e-803242704984/download?versie=1","bestandsomvang":7,"link":"","beschrijving":"Bijgevoegd + document","ontvangstdatum":"2024-03-02","verzenddatum":null,"indicatieGebruiksrecht":false,"verschijningsvorm":"","ondertekening":{"soort":"","datum":null},"integriteit":{"algoritme":"","waarde":"","datum":null},"informatieobjecttype":"http://localhost:8003/catalogi/api/v1/informatieobjecttypen/531f6c1a-97f7-478c-85f0-67d2f23661c7","locked":false,"bestandsdelen":[],"trefwoorden":[],"lock":""}' + headers: + API-version: + - 1.4.2 + Allow: + - GET, POST, HEAD, OPTIONS + Content-Length: + - '1034' + Content-Type: + - application/json + Cross-Origin-Opener-Policy: + - same-origin + Location: + - http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten/fe8ee354-2965-43c5-926e-803242704984 + Referrer-Policy: + - same-origin + Vary: + - origin + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + status: + code: 201 + message: Created +- request: + body: '{"informatieobjecttype": "http://localhost:8003/catalogi/api/v1/informatieobjecttypen/531f6c1a-97f7-478c-85f0-67d2f23661c7", + "bronorganisatie": "000000000", "creatiedatum": "2024-03-19", "titel": "Form + 000", "auteur": "Aanvrager", "taal": "nld", "formaat": "multipart/form-data", + "inhoud": "Y29udGVudA==", "status": "definitief", "bestandsnaam": "attachment2_1.jpg", + "ontvangstdatum": "2024-03-02", "beschrijving": "Bijgevoegd document", "indicatieGebruiksrecht": + false, "bestandsomvang": 7}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Authorization: + - Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ0ZXN0X2NsaWVudF9pZCIsImlhdCI6MTcxMDg1NTYzNCwiY2xpZW50X2lkIjoidGVzdF9jbGllbnRfaWQiLCJ1c2VyX2lkIjoiIiwidXNlcl9yZXByZXNlbnRhdGlvbiI6IiJ9.NJjZEPSwh9eGzntjwUB7rFAiaq_5DqYgVylWuKdtdMA + Connection: + - keep-alive + Content-Length: + - '491' + Content-Type: + - application/json + User-Agent: + - python-requests/2.32.2 + method: POST + uri: http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten + response: + body: + string: '{"url":"http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten/7ebd51ec-e4a9-4cba-b395-7963f53b2291","identificatie":"DOCUMENT-2024-0000000086","bronorganisatie":"000000000","creatiedatum":"2024-03-19","titel":"Form + 000","vertrouwelijkheidaanduiding":"openbaar","auteur":"Aanvrager","status":"definitief","formaat":"multipart/form-data","taal":"nld","versie":1,"beginRegistratie":"2024-11-20T22:05:00.499151Z","bestandsnaam":"attachment2_1.jpg","inhoud":"http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten/7ebd51ec-e4a9-4cba-b395-7963f53b2291/download?versie=1","bestandsomvang":7,"link":"","beschrijving":"Bijgevoegd + document","ontvangstdatum":"2024-03-02","verzenddatum":null,"indicatieGebruiksrecht":false,"verschijningsvorm":"","ondertekening":{"soort":"","datum":null},"integriteit":{"algoritme":"","waarde":"","datum":null},"informatieobjecttype":"http://localhost:8003/catalogi/api/v1/informatieobjecttypen/531f6c1a-97f7-478c-85f0-67d2f23661c7","locked":false,"bestandsdelen":[],"trefwoorden":[],"lock":""}' + headers: + API-version: + - 1.4.2 + Allow: + - GET, POST, HEAD, OPTIONS + Content-Length: + - '1047' + Content-Type: + - application/json + Cross-Origin-Opener-Policy: + - same-origin + Location: + - http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten/7ebd51ec-e4a9-4cba-b395-7963f53b2291 + Referrer-Policy: + - same-origin + Vary: + - origin + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + status: + code: 201 + message: Created +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Authorization: + - Token 171be5abaf41e7856b423ad513df1ef8f867ff48 + Connection: + - keep-alive + User-Agent: + - python-requests/2.32.2 + method: GET + uri: http://localhost:8001/api/v2/objecttypes/527b8408-7421-4808-a744-43ccb7bdaaa2 + response: + body: + string: '{"url":"http://objecttypes-web:8000/api/v2/objecttypes/527b8408-7421-4808-a744-43ccb7bdaaa2","uuid":"527b8408-7421-4808-a744-43ccb7bdaaa2","name":"File + Uploads","namePlural":"File Uploads","description":"","dataClassification":"confidential","maintainerOrganization":"","maintainerDepartment":"","contactPerson":"","contactEmail":"","source":"","updateFrequency":"unknown","providerOrganization":"","documentationUrl":"","labels":{},"createdAt":"2024-02-08","modifiedAt":"2024-02-08","allowGeometry":true,"versions":["http://objecttypes-web:8000/api/v2/objecttypes/527b8408-7421-4808-a744-43ccb7bdaaa2/versions/1"]}' + headers: + Allow: + - GET, PUT, PATCH, DELETE, HEAD, OPTIONS + Connection: + - keep-alive + Content-Length: + - '615' + Content-Type: + - application/json + Cross-Origin-Opener-Policy: + - same-origin + Date: + - Wed, 20 Nov 2024 22:05:00 GMT + Referrer-Policy: + - same-origin + Server: + - nginx/1.27.1 + Vary: + - origin + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + status: + code: 200 + message: OK +- request: + body: '{"type": "http://objecttypes-web:8000/api/v2/objecttypes/527b8408-7421-4808-a744-43ccb7bdaaa2", + "record": {"typeVersion": 1, "data": {"multiple_files": ["http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten/fe8ee354-2965-43c5-926e-803242704984", + "http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten/7ebd51ec-e4a9-4cba-b395-7963f53b2291"]}, + "startAt": "2024-03-19"}}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate, br + Authorization: + - Token 7657474c3d75f56ae0abd0d1bf7994b09964dca9 + Connection: + - keep-alive + Content-Crs: + - EPSG:4326 + Content-Length: + - '400' + Content-Type: + - application/json + User-Agent: + - python-requests/2.32.2 + method: POST + uri: http://localhost:8002/api/v2/objects + response: + body: + string: '{"url":"http://objects-web:8000/api/v2/objects/90701509-7a26-4ead-aa32-d664f10806df","uuid":"90701509-7a26-4ead-aa32-d664f10806df","type":"http://objecttypes-web:8000/api/v2/objecttypes/527b8408-7421-4808-a744-43ccb7bdaaa2","record":{"index":1,"typeVersion":1,"data":{"multiple_files":["http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten/fe8ee354-2965-43c5-926e-803242704984","http://localhost:8003/documenten/api/v1/enkelvoudiginformatieobjecten/7ebd51ec-e4a9-4cba-b395-7963f53b2291"]},"geometry":null,"startAt":"2024-03-19","endAt":null,"registrationAt":"2024-11-20","correctionFor":null,"correctedBy":null}}' + headers: + Allow: + - GET, POST, HEAD, OPTIONS + Connection: + - keep-alive + Content-Crs: + - EPSG:4326 + Content-Length: + - '629' + Content-Type: + - application/json + Cross-Origin-Opener-Policy: + - same-origin + Date: + - Wed, 20 Nov 2024 22:05:02 GMT + Location: + - http://localhost:8002/api/v2/objects/90701509-7a26-4ead-aa32-d664f10806df + Referrer-Policy: + - same-origin + Server: + - nginx/1.27.1 + Vary: + - origin + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + status: + code: 201 + message: Created +version: 1 diff --git a/src/openforms/registrations/contrib/objects_api/tests/test_backend_v2.py b/src/openforms/registrations/contrib/objects_api/tests/test_backend_v2.py index 54f8a9dc69..ae1a1b4dc6 100644 --- a/src/openforms/registrations/contrib/objects_api/tests/test_backend_v2.py +++ b/src/openforms/registrations/contrib/objects_api/tests/test_backend_v2.py @@ -319,6 +319,108 @@ def test_submission_with_file_components(self): self.assertIsInstance(result["record"]["data"]["multiple_files"], list) self.assertEqual(len(result["record"]["data"]["multiple_files"]), 1) + def test_submission_with_file_components_container_variable(self): + submission = SubmissionFactory.from_components( + [ + { + "key": "single_file", + "type": "file", + }, + { + "key": "multiple_files", + "type": "file", + "multiple": True, + }, + ], + completed=True, + ) + submission_step = submission.steps[0] + SubmissionFileAttachmentFactory.create( + submission_step=submission_step, + file_name="attachment1.jpg", + form_key="single_file", + ) + SubmissionFileAttachmentFactory.create( + submission_step=submission_step, + file_name="attachment2_1.jpg", + form_key="multiple_files", + ) + + v2_options: RegistrationOptionsV2 = { + "version": 2, + "objects_api_group": self.objects_api_group, + # See the docker compose fixtures for more info on these values: + "objecttype": UUID("527b8408-7421-4808-a744-43ccb7bdaaa2"), + "objecttype_version": 1, + "upload_submission_csv": False, + "update_existing_object": False, + "informatieobjecttype_attachment": "http://localhost:8003/catalogi/api/v1/informatieobjecttypen/531f6c1a-97f7-478c-85f0-67d2f23661c7", + "organisatie_rsin": "000000000", + "variables_mapping": [ + { + "variable_key": "attachment_urls", + "target_path": ["multiple_files"], + }, + ], + "iot_attachment": "", + "iot_submission_csv": "", + "iot_submission_report": "", + } + + plugin = ObjectsAPIRegistration(PLUGIN_IDENTIFIER) + + # Run the registration + result = plugin.register_submission(submission, v2_options) + assert result is not None + + self.assertIsInstance(result["record"]["data"]["multiple_files"], list) + self.assertEqual(len(result["record"]["data"]["multiple_files"]), 2) + + def test_submission_with_empty_optional_file(self): + submission = SubmissionFactory.from_components( + [ + { + "key": "single_file", + "type": "file", + }, + ], + completed=True, + ) + SubmissionValueVariableFactory.create( + submission=submission, + form_variable=submission.form.formvariable_set.get(key="single_file"), + key="single_file", + value=[], + ) + v2_options: RegistrationOptionsV2 = { + "version": 2, + "objects_api_group": self.objects_api_group, + # See the docker compose fixtures for more info on these values: + "objecttype": UUID("527b8408-7421-4808-a744-43ccb7bdaaa2"), + "objecttype_version": 1, + "upload_submission_csv": False, + "update_existing_object": False, + "informatieobjecttype_attachment": "http://localhost:8003/catalogi/api/v1/informatieobjecttypen/531f6c1a-97f7-478c-85f0-67d2f23661c7", + "organisatie_rsin": "000000000", + "variables_mapping": [ + # fmt: off + { + "variable_key": "single_file", + "target_path": ["single_file"], + }, + # fmt: on + ], + "iot_attachment": "", + "iot_submission_csv": "", + "iot_submission_report": "", + } + plugin = ObjectsAPIRegistration(PLUGIN_IDENTIFIER) + + # Run the registration + result = plugin.register_submission(submission, v2_options) + + assert result is not None + class V2HandlerTests(TestCase): """ diff --git a/src/openforms/registrations/contrib/objects_api/tests/test_registration_variables.py b/src/openforms/registrations/contrib/objects_api/tests/test_registration_variables.py index 9963e5ec5f..f9b3d22916 100644 --- a/src/openforms/registrations/contrib/objects_api/tests/test_registration_variables.py +++ b/src/openforms/registrations/contrib/objects_api/tests/test_registration_variables.py @@ -1,9 +1,9 @@ -from django.test import SimpleTestCase +from django.test import TestCase from ..registration_variables import register -class RegistrationVariableTests(SimpleTestCase): +class RegistrationVariableTests(TestCase): def test_variables_handle_None_submission(self): for variable in register: