def test_besluittype_external_iotype_external_success(self): catalogus = f"{self.base}catalogussen/1c8e36be-338c-4c07-ac5e-1adf55bec04a" besluittype = f"{self.base}besluittypen/b71f72ef-198d-44d8-af64-ae1932df830a" besluit = BesluitFactory.create(besluittype=besluittype) besluit_url = f"http://openbesluit.nl{reverse(besluit)}" informatieobjecttype = f"{self.base}informatieobjecttypen/{uuid.uuid4()}" besluittype_data = get_besluittype_response(catalogus, besluittype) besluittype_data["informatieobjecttypen"] = [informatieobjecttype] with requests_mock.Mocker(real_http=True) as m: mock_service_oas_get(m, APITypes.drc, self.base) m.get(besluittype, json=besluittype_data) m.get( informatieobjecttype, json=get_informatieobjecttype_response(catalogus, informatieobjecttype), ) m.get( self.document, json=get_eio_response( self.document, informatieobjecttype=informatieobjecttype ), ) m.post( f"{self.base}objectinformatieobjecten", json=get_oio_response(self.document, besluit_url), status_code=201, ) response = self.client.post( self.list_url, {"besluit": besluit_url, "informatieobject": self.document}, HTTP_HOST="openbesluit.nl", ) self.assertEqual(response.status_code, status.HTTP_201_CREATED)
def test_besluittype_external_iotype_internal(self): catalogus = f"{self.base}catalogussen/1c8e36be-338c-4c07-ac5e-1adf55bec04a" besluittype = f"{self.base}besluittypen/b71f72ef-198d-44d8-af64-ae1932df830a" besluit = BesluitFactory.create(besluittype=besluittype) besluit_url = f"http://openbesluit.nl{reverse(besluit)}" informatieobjecttype = InformatieObjectTypeFactory.create() eio_response = get_eio_response( self.document, informatieobjecttype=f"http://openbesluit.nl{reverse(informatieobjecttype)}", ) with requests_mock.Mocker(real_http=True) as m: m.get(besluittype, json=get_besluittype_response(catalogus, besluittype)) m.get(self.document, json=eio_response) response = self.client.post( self.list_url, {"besluit": besluit_url, "informatieobject": self.document}, HTTP_HOST="openbesluit.nl", ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) error = get_validation_errors(response, "nonFieldErrors") self.assertEqual( error["code"], "missing-besluittype-informatieobjecttype-relation" )
def test_eindstatus_with_informatieobject_lock(self, m): REMOTE_DOCUMENT = "https://external.nl/documenten/123" m.get( REMOTE_DOCUMENT, json=get_eio_response(REMOTE_DOCUMENT, locked=True), ) zaak = ZaakFactory.create(zaaktype=self.zaaktype) zaak_url = reverse(zaak) ZaakInformatieObjectFactory.create(zaak=zaak, informatieobject=REMOTE_DOCUMENT) resultaattype = ResultaatTypeFactory.create( archiefactietermijn="P10Y", archiefnominatie=Archiefnominatie.blijvend_bewaren, brondatum_archiefprocedure_afleidingswijze= BrondatumArchiefprocedureAfleidingswijze.afgehandeld, zaaktype=self.zaaktype, ) ResultaatFactory.create(zaak=zaak, resultaattype=resultaattype) list_url = reverse("status-list") response = self.client.post( list_url, { "zaak": zaak_url, "statustype": f"http://testserver{self.statustype_end_url}", "datumStatusGezet": isodatetime(2019, 7, 22, 13, 00, 00), }, ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) validation_error = get_validation_errors(response, "nonFieldErrors") self.assertEqual(validation_error["code"], "informatieobject-locked")
def test_zaak_delete_oio_removed(self, m): mock_service_oas_get(m, APITypes.drc, self.base) document = f"{self.base}enkelvoudiginformatieobjecten/{uuid.uuid4()}" eio_response = get_eio_response( document, informatieobjecttype="http://testserver/catalogi/api/v1/iot/dummy", ) m.get(document, json=eio_response) zaak = ZaakFactory.create() zio = ZaakInformatieObjectFactory.create( zaak=zaak, informatieobject=document, _objectinformatieobject_url=f"{self.base}_objectinformatieobjecten/{uuid.uuid4()}", ) m.delete(zio._objectinformatieobject_url, status_code=204) zaak_delete_url = get_operation_url("zaak_delete", uuid=zaak.uuid) with capture_on_commit_callbacks(execute=True): response = self.client.delete(zaak_delete_url, **ZAAK_WRITE_KWARGS) self.assertEqual( response.status_code, status.HTTP_204_NO_CONTENT, response.data ) delete_call = next((req for req in m.request_history if req.method == "DELETE")) self.assertEqual(delete_call.url, zio._objectinformatieobject_url)
def test_zaaktype_internal_iotype_internal_fail(self): zaak = ZaakFactory.create() zaak_url = f"http://openzaak.nl{reverse(zaak)}" informatieobjecttype = InformatieObjectTypeFactory.create() eio_response = get_eio_response( self.document, informatieobjecttype= f"http://openzaak.nl{reverse(informatieobjecttype)}", ) with requests_mock.Mocker(real_http=True) as m: m.get(self.document, json=eio_response) response = self.client.post( self.list_url, { "zaak": zaak_url, "informatieobject": self.document }, HTTP_HOST="openzaak.nl", ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) error = get_validation_errors(response, "nonFieldErrors") self.assertEqual(error["code"], "missing-zaaktype-informatieobjecttype-relation")
def test_zaaktype_internal_iotype_external(self): zaak = ZaakFactory.create() zaak_url = f"http://openzaak.nl{reverse(zaak)}" informatieobjecttype = f"{self.base}informatieobjecttypen/{uuid.uuid4()}" catalogus = f"{self.base}catalogussen/1c8e36be-338c-4c07-ac5e-1adf55bec04a" with requests_mock.Mocker(real_http=True) as m: m.get( informatieobjecttype, json=get_informatieobjecttype_response(catalogus, informatieobjecttype), ) m.get(catalogus, json=get_catalogus_response(catalogus, informatieobjecttype)) m.get( self.document, json=get_eio_response( self.document, informatieobjecttype=informatieobjecttype), ) response = self.client.post( self.list_url, { "zaak": zaak_url, "informatieobject": self.document }, HTTP_HOST="openzaak.nl", ) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) error = get_validation_errors(response, "nonFieldErrors") self.assertEqual(error["code"], "missing-zaaktype-informatieobjecttype-relation")
def test_destroy_with_external_informatieobject_fail_send(self): oio = f"{self.base}objectinformatieobjecten/{uuid.uuid4()}" informatieobjecttype = InformatieObjectTypeFactory.create() with requests_mock.Mocker(real_http=True) as m: mock_service_oas_get(m, APITypes.drc, self.base) m.get( self.document, json=get_eio_response( self.document, informatieobjecttype=f"http://openzaak.nl{reverse(informatieobjecttype)}", ), ) m.delete(oio, status_code=404, text="Not found") bio = BesluitInformatieObjectFactory.create( informatieobject=self.document, _objectinformatieobject_url=oio ) bio_url = reverse(bio) response = self.client.delete(bio_url, HTTP_HOST="openzaak.nl") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) error = get_validation_errors(response, "informatieobject") self.assertEqual(error["code"], "pending-relations")
def test_destroy_with_external_informatieobject(self): oio = f"{self.base}objectinformatieobjecten/{uuid.uuid4()}" informatieobjecttype = InformatieObjectTypeFactory.create() with requests_mock.Mocker(real_http=True) as m: mock_service_oas_get(m, APITypes.drc, self.base) m.get( self.document, json=get_eio_response( self.document, informatieobjecttype=f"http://openzaak.nl{reverse(informatieobjecttype)}", ), ) m.delete(oio, status_code=204) bio = BesluitInformatieObjectFactory.create( informatieobject=self.document, _objectinformatieobject_url=oio ) bio_url = reverse(bio) response = self.client.delete(bio_url, HTTP_HOST="openzaak.nl") self.assertEqual( response.status_code, status.HTTP_204_NO_CONTENT, response.data ) self.assertEqual(BesluitInformatieObject.objects.count(), 0) history_delete = [ req for req in m.request_history if req.method == "DELETE" and req.url == oio ] self.assertEqual(len(history_delete), 1)
def test_delete_document_fail_exising_relations_zaak(self): eio = EnkelvoudigInformatieObjectFactory.create() eio_uuid = eio.uuid eio_path = reverse(eio) eio_url = f"https://external.documenten.nl/{eio_path}" self.adapter.register_uri( "GET", eio_url, json=get_eio_response(eio_path), ) self.create_zaak_besluit_services() zaak = self.create_zaak() ZaakInformatieObjectFactory.create(informatieobject=eio_url, zaak=zaak) informatieobject_delete_url = get_operation_url( "enkelvoudiginformatieobject_delete", uuid=eio_uuid, ) response = self.client.delete(informatieobject_delete_url) self.assertEqual( response.status_code, status.HTTP_400_BAD_REQUEST, response.data ) error = get_validation_errors(response, "nonFieldErrors") self.assertEqual(error["code"], "pending-relations")
def test_bio_visibility_outside_transaction(self): self.setUpTestData() document = f"{self.base}enkelvoudiginformatieobjecten/{uuid.uuid4()}" besluit = BesluitFactory.create(besluittype__concept=False) besluit_url = f"http://openzaak.nl{reverse(besluit)}" informatieobjecttype = InformatieObjectTypeFactory.create( catalogus=besluit.besluittype.catalogus, concept=False ) informatieobjecttype_url = f"http://openzaak.nl{reverse(informatieobjecttype)}" informatieobjecttype.besluittypen.add(besluit.besluittype) eio_response = get_eio_response( document, informatieobjecttype=informatieobjecttype_url ) def worker(besluit_id: int): """ Worker to run in a thread. When this worker runs, there should be one ZIO visible in the database - it must have been committed so that the remote DRC can view this record too. """ bios = BesluitInformatieObject.objects.filter(besluit__id=besluit_id) self.assertEqual(bios.count(), 1) close_old_connections() def mock_create_remote_oio(*args, **kwargs): with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: future = executor.submit(worker, besluit.id) future.result() # raises any exceptions, such as assertionerrors return {"url": f"{self.base}objectinformatieobjecten/{uuid.uuid4()}"} with patch( "openzaak.components.besluiten.api.serializers.create_remote_oio", side_effect=mock_create_remote_oio, ): with requests_mock.Mocker() as m: mock_service_oas_get( m, APITypes.drc, self.base, oas_url=settings.DRC_API_SPEC ) m.get(document, json=eio_response) response = self.client.post( self.list_url, {"besluit": besluit_url, "informatieobject": document}, ) self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data)
def test_filter_by_external_informatieobject(self): base = "https://external.documenten.nl/api/v1/" document = f"{base}enkelvoudiginformatieobjecten/{uuid.uuid4()}" Service.objects.create( api_type=APITypes.drc, api_root=base, label="external documents", auth_type=AuthTypes.no_auth, ) zio_type = ZaakTypeInformatieObjectTypeFactory.create( informatieobjecttype__concept=False, zaaktype__concept=False) zaak = ZaakFactory.create(zaaktype=zio_type.zaaktype) zaak_url = f"http://openzaak.nl{reverse(zaak)}" eio_response = get_eio_response( document, informatieobjecttype= f"http://openzaak.nl{reverse(zio_type.informatieobjecttype)}", ) with requests_mock.Mocker(real_http=True) as m: mock_service_oas_get(m, APITypes.drc, base) m.get(document, json=eio_response) m.post( "https://external.documenten.nl/api/v1/objectinformatieobjecten", json=get_oio_response(document, zaak_url), status_code=201, ) response = self.client.post( reverse(ZaakInformatieObject), { "zaak": zaak_url, "informatieobject": document }, HTTP_HOST="openzaak.nl", ) io_url = response.data["informatieobject"] zio_list_url = reverse("zaakinformatieobject-list") response = self.client.get(zio_list_url, {"informatieobject": io_url}, HTTP_HOST="openzaak.nl") self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]["informatieobject"], io_url)
def test_destroy_with_relations_not_allowed(self): """ Assert that destroying is not possible when there are relations. """ eio = EnkelvoudigInformatieObjectFactory.create() eio_path = reverse(eio) eio_url = f"https://external.documenten.nl/{eio_path}" self.adapter.register_uri( "GET", eio_url, json=get_eio_response(eio_path), ) self.create_zaak_besluit_services() zaak = self.create_zaak() ZaakInformatieObjectFactory.create(informatieobject=eio_url, zaak=zaak) response = self.client.delete(eio_path) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) error = get_validation_errors(response, "nonFieldErrors") self.assertEqual(error["code"], "pending-relations")
def test_update_zio_metadata(self, m): mock_service_oas_get(m, APITypes.drc, self.base, oas_url=settings.DRC_API_SPEC) document = f"{self.base}enkelvoudiginformatieobjecten/{uuid.uuid4()}" zio_type = ZaakTypeInformatieObjectTypeFactory.create( informatieobjecttype__concept=False, zaaktype__concept=False) zaak = ZaakFactory.create(zaaktype=zio_type.zaaktype) zaak_url = f"http://openzaak.nl{reverse(zaak)}" eio_response = get_eio_response( document, informatieobjecttype= f"http://testserver{reverse(zio_type.informatieobjecttype)}", ) m.get(document, json=eio_response) zio = ZaakInformatieObjectFactory.create(zaak=zaak, informatieobject=document) zio_detail_url = reverse(zio) response = self.client.put( zio_detail_url, { "zaak": zaak_url, "informatieobject": document, "titel": "updated title", "beschrijving": "same", }, ) self.assertEqual(response.status_code, status.HTTP_200_OK, response.data) self.assertEqual(response.data["titel"], "updated title") self.assertEqual(response.data["beschrijving"], "same") zio.refresh_from_db() self.assertEqual(zio.titel, "updated title") self.assertEqual(zio.beschrijving, "same")
def test_cannot_set_archiefstatus_when_not_all_documents_are_gearchiveerd( self, m): REMOTE_DOCUMENT = "https://external.nl/documenten/123" m.get( REMOTE_DOCUMENT, json=get_eio_response(REMOTE_DOCUMENT, status=Statussen.ter_vaststelling), ) zaak = ZaakFactory.create( archiefnominatie=Archiefnominatie.vernietigen, archiefactiedatum=date.today(), ) ZaakInformatieObjectFactory.create(zaak=zaak, informatieobject=REMOTE_DOCUMENT) zaak_patch_url = get_operation_url("zaak_partial_update", uuid=zaak.uuid) data = {"archiefstatus": Archiefstatus.gearchiveerd} response = self.client.patch(zaak_patch_url, data, **ZAAK_WRITE_KWARGS) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, response.data)
def test_cannot_read_without_correct_scope(self): eio = EnkelvoudigInformatieObjectFactory.create() eio_url = f"http://testserver{reverse(eio)}" gebruiksrechten = GebruiksrechtenCMISFactory.create( informatieobject=eio_url) self.adapter.get(eio_url, json=get_eio_response(reverse(eio))) self.create_zaak_besluit_services() zaak = self.create_zaak() ZaakInformatieObjectFactory.create(informatieobject=eio_url, zaak=zaak) oio = ObjectInformatieObject.objects.get() urls = [ reverse("enkelvoudiginformatieobject-list"), reverse("enkelvoudiginformatieobject-detail", kwargs={"uuid": eio.uuid}), reverse("gebruiksrechten-list"), reverse(gebruiksrechten), reverse("objectinformatieobject-list"), reverse(oio), ] for url in urls: with self.subTest(url=url): self.assertForbidden(url, method="get")
def test_create_bio_external_document(self): document = f"{self.base}enkelvoudiginformatieobjecten/{uuid.uuid4()}" besluit = BesluitFactory.create(besluittype__concept=False) besluit_url = f"http://openzaak.nl{reverse(besluit)}" informatieobjecttype = InformatieObjectTypeFactory.create( catalogus=besluit.besluittype.catalogus, concept=False ) informatieobjecttype_url = f"http://openzaak.nl{reverse(informatieobjecttype)}" informatieobjecttype.besluittypen.add(besluit.besluittype) eio_response = get_eio_response( document, informatieobjecttype=informatieobjecttype_url ) oio_response = get_oio_response(document, besluit_url, "besluit") with self.subTest(section="bio-create"): with requests_mock.Mocker(real_http=True) as m: mock_service_oas_get(m, APITypes.drc, self.base) m.get(document, json=eio_response) m.post( "https://external.documenten.nl/api/v1/objectinformatieobjecten", json=oio_response, status_code=201, ) response = self.client.post( self.list_url, {"besluit": besluit_url, "informatieobject": document}, ) self.assertEqual( response.status_code, status.HTTP_201_CREATED, response.data ) posts = [req for req in m.request_history if req.method == "POST"] self.assertEqual(len(posts), 1) request = posts[0] self.assertEqual( request.url, "https://external.documenten.nl/api/v1/objectinformatieobjecten", ) self.assertEqual( request.json(), { "informatieobject": document, "object": besluit_url, "objectType": "besluit", }, ) self.assertFalse(ObjectInformatieObject.objects.exists()) bio = BesluitInformatieObject.objects.get() self.assertEqual(bio._objectinformatieobject_url, oio_response["url"]) with self.subTest(section="bio-list"): list_response = self.client.get( self.list_url, {"besluit": besluit_url}, HTTP_HOST="openzaak.nl", ) self.assertEqual( list_response.status_code, status.HTTP_200_OK, response.data ) data = list_response.json() self.assertEqual(len(data), 1) self.assertEqual(data[0]["informatieobject"], document)
def test_relate_external_document(self): document = f"{self.base}enkelvoudiginformatieobjecten/{uuid.uuid4()}" zio_type = ZaakTypeInformatieObjectTypeFactory.create( informatieobjecttype__concept=False, zaaktype__concept=False) zaak = ZaakFactory.create(zaaktype=zio_type.zaaktype) zaak_url = f"http://openzaak.nl{reverse(zaak)}" eio_response = get_eio_response( document, informatieobjecttype= f"http://testserver{reverse(zio_type.informatieobjecttype)}", ) oio_response = get_oio_response(document, zaak_url) with self.subTest(section="zio-create"): with requests_mock.Mocker() as m: mock_service_oas_get(m, APITypes.drc, self.base) m.get(document, json=eio_response) m.post( "https://external.documenten.nl/api/v1/objectinformatieobjecten", json=oio_response, status_code=201, ) response = self.client.post( reverse(ZaakInformatieObject), { "zaak": zaak_url, "informatieobject": document }, ) self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data) posts = [req for req in m.request_history if req.method == "POST"] self.assertEqual(len(posts), 1) request = posts[0] self.assertEqual( request.url, "https://external.documenten.nl/api/v1/objectinformatieobjecten", ) self.assertEqual( request.json(), { "informatieobject": document, "object": zaak_url, "objectType": "zaak", }, ) self.assertFalse(ObjectInformatieObject.objects.exists()) zio = ZaakInformatieObject.objects.get() self.assertEqual(zio._objectinformatieobject_url, oio_response["url"]) with self.subTest(section="zio-list"): list_response = self.client.get( reverse(ZaakInformatieObject), {"zaak": zaak_url}, HTTP_HOST="openzaak.nl", ) self.assertEqual(list_response.status_code, status.HTTP_200_OK) data = list_response.json() self.assertEqual(len(data), 1) self.assertEqual(data[0]["informatieobject"], document)
def test_zio_visibility_outside_transaction(self): """ Test that the ZIO being created is visible to an external DRC. This is a regression test for #819 - because of the DB transaction wrapping, API calls requesting ZIO don't actually see the object yet, leading to validation errors. We simulate this by using threading to get a different DB connection, outside of the possible current transaction. """ document = f"{self.base}enkelvoudiginformatieobjecten/{uuid.uuid4()}" zio_type = ZaakTypeInformatieObjectTypeFactory.create( informatieobjecttype__concept=False, zaaktype__concept=False) zaak = ZaakFactory.create(zaaktype=zio_type.zaaktype) zaak_url = f"http://openzaak.nl{reverse(zaak)}" eio_response = get_eio_response( document, informatieobjecttype= f"http://testserver{reverse(zio_type.informatieobjecttype)}", ) def worker(zaak_id: int): """ Worker to run in a thread. When this worker runs, there should be one ZIO visible in the database - it must have been committed so that the remote DRC can view this record too. """ zios = ZaakInformatieObject.objects.filter(zaak__id=zaak_id) self.assertEqual(zios.count(), 1) close_old_connections() def mock_create_remote_oio(*args, **kwargs): with concurrent.futures.ThreadPoolExecutor( max_workers=1) as executor: future = executor.submit(worker, zaak.id) future.result( ) # raises any exceptions, such as assertionerrors return { "url": f"{self.base}objectinformatieobjecten/{uuid.uuid4()}" } with patch( "openzaak.components.zaken.api.serializers.zaken.create_remote_oio", side_effect=mock_create_remote_oio, ): with requests_mock.Mocker() as m: mock_service_oas_get(m, APITypes.drc, self.base, oas_url=settings.DRC_API_SPEC) m.get(document, json=eio_response) response = self.client.post( reverse(ZaakInformatieObject), { "zaak": zaak_url, "informatieobject": document }, ) self.assertEqual(response.status_code, status.HTTP_201_CREATED)