Skip to content

Commit

Permalink
Merge pull request #821 from open-zaak/issue/820-filtering-ZIOs
Browse files Browse the repository at this point in the history
Fixes #820 - Filtering ZIOs on informatieobject with CMIS enabled
  • Loading branch information
sergei-maertens committed Mar 11, 2021
2 parents 57acef8 + 69a8803 commit a60d2d4
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 21 deletions.
35 changes: 34 additions & 1 deletion src/openzaak/components/zaken/api/filters.py
@@ -1,7 +1,12 @@
# SPDX-License-Identifier: EUPL-1.2
# Copyright (C) 2019 - 2020 Dimpact
from urllib.parse import urlparse

from django.conf import settings

from django_filters import filters
from django_loose_fk.filters import FkOrUrlFieldFilter
from django_loose_fk.utils import get_resource_for_path
from vng_api_common.filtersets import FilterSet
from vng_api_common.utils import get_help_text

Expand Down Expand Up @@ -123,8 +128,36 @@ class Meta:
fields = ("zaak", "resultaattype")


class FkOrUrlOrCMISFieldFilter(FkOrUrlFieldFilter):
def filter(self, qs, value):
if not value:
return qs

parsed = urlparse(value)
host = self.parent.request.get_host()

local = parsed.netloc == host
if settings.CMIS_ENABLED:
local = False

# introspect field to build filter
model_field = self.model._meta.get_field(self.field_name)

if local:
local_object = get_resource_for_path(parsed.path)
if self.instance_path:
for bit in self.instance_path.split("."):
local_object = getattr(local_object, bit)
filters = {f"{model_field.fk_field}__{self.lookup_expr}": local_object}
else:
filters = {f"{model_field.url_field}__{self.lookup_expr}": value}

qs = self.get_method(qs)(**filters)
return qs.distinct() if self.distinct else qs


class ZaakInformatieObjectFilter(FilterSet):
informatieobject = FkOrUrlFieldFilter(
informatieobject = FkOrUrlOrCMISFieldFilter(
queryset=ZaakInformatieObject.objects.all(),
instance_path="canonical",
help_text=get_help_text("zaken.ZaakInformatieObject", "informatieobject"),
Expand Down
50 changes: 36 additions & 14 deletions src/openzaak/components/zaken/tests/test_zaakinformatieobjecten.py
Expand Up @@ -211,25 +211,29 @@ def test_filter_by_zaak(self):
self.assertEqual(response.data[0]["zaak"], f"http://openzaak.nl{zaak_url}")

def test_filter_by_local_informatieobject(self):
zio = ZaakInformatieObjectFactory.create()
io_url = reverse(zio.informatieobject.latest_version)
zio_list_url = reverse("zaakinformatieobject-list")

zio1 = ZaakInformatieObjectFactory.create()
io1_url = reverse(zio1.informatieobject.latest_version)

ZaakInformatieObjectFactory.create()

response = self.client.get(
zio_list_url,
{"informatieobject": f"http://openzaak.nl{io_url}"},
{"informatieobject": f"http://openzaak.nl{io1_url}"},
HTTP_HOST="openzaak.nl",
)

self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
self.assertEqual(
response.data[0]["informatieobject"], f"http://openzaak.nl{io_url}"
response.data[0]["informatieobject"], f"http://openzaak.nl{io1_url}"
)

def test_filter_by_external_informatieobject(self):
base = "https://external.documenten.nl/api/v1/"
document = f"{base}enkelvoudiginformatieobjecten/{uuid.uuid4()}"
document1 = f"{base}enkelvoudiginformatieobjecten/{uuid.uuid4()}"
document2 = f"{base}enkelvoudiginformatieobjecten/{uuid.uuid4()}"

Service.objects.create(
api_type=APITypes.drc,
Expand All @@ -242,36 +246,54 @@ def test_filter_by_external_informatieobject(self):
)
zaak = ZaakFactory.create(zaaktype=zio_type.zaaktype)
zaak_url = f"http://openzaak.nl{reverse(zaak)}"
eio_response = get_eio_response(
document,

eio1_response = get_eio_response(
document1,
informatieobjecttype=f"http://openzaak.nl{reverse(zio_type.informatieobjecttype)}",
)
eio2_response = get_eio_response(
document2,
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.get(document1, json=eio1_response)
m.post(
"https://external.documenten.nl/api/v1/objectinformatieobjecten",
json=get_oio_response(document, zaak_url),
json=get_oio_response(document1, zaak_url),
status_code=201,
)

response = self.client.post(
m.get(document2, json=eio2_response)
m.post(
"https://external.documenten.nl/api/v1/objectinformatieobjecten",
json=get_oio_response(document2, zaak_url),
status_code=201,
)

response1 = self.client.post(
reverse(ZaakInformatieObject),
{"zaak": zaak_url, "informatieobject": document},
{"zaak": zaak_url, "informatieobject": document1},
HTTP_HOST="openzaak.nl",
)
self.client.post(
reverse(ZaakInformatieObject),
{"zaak": zaak_url, "informatieobject": document2},
HTTP_HOST="openzaak.nl",
)

io_url = response.data["informatieobject"]
io1_url = response1.data["informatieobject"]
zio_list_url = reverse("zaakinformatieobject-list")

# Test that only 1 of the 2 ZIOs in the database is returned.
response = self.client.get(
zio_list_url, {"informatieobject": io_url}, HTTP_HOST="openzaak.nl"
zio_list_url, {"informatieobject": io1_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)
self.assertEqual(response.data[0]["informatieobject"], io1_url)

def test_update_zaak_and_informatieobject_fails(self):
zaak = ZaakFactory.create()
Expand Down
Expand Up @@ -209,22 +209,32 @@ def test_filter_by_zaak(self):

@override_settings(ALLOWED_HOSTS=["testserver", "example.com"])
def test_filter_by_informatieobject(self):
eio = EnkelvoudigInformatieObjectFactory.create()
eio_url = f"http://example.com{reverse(eio)}"
self.adapter.get(eio_url, json=serialise_eio(eio, eio_url))
self.create_zaak_besluit_services()
zaak = self.create_zaak()
ZaakInformatieObjectFactory.create(informatieobject=eio_url, zaak=zaak)

# Create two ZIOs
eio1 = EnkelvoudigInformatieObjectFactory.create()
eio1_url = f"http://example.com{reverse(eio1)}"
self.adapter.get(eio1_url, json=serialise_eio(eio1, eio1_url))

ZaakInformatieObjectFactory.create(informatieobject=eio1_url, zaak=zaak)

eio2 = EnkelvoudigInformatieObjectFactory.create()
eio2_url = f"http://example.com{reverse(eio2)}"
self.adapter.get(eio2_url, json=serialise_eio(eio2, eio2_url))

ZaakInformatieObjectFactory.create(informatieobject=eio2_url, zaak=zaak)

zio_list_url = reverse("zaakinformatieobject-list")

# Test that only 1 of the 2 ZIOs is returned
response = self.client.get(
zio_list_url, {"informatieobject": eio_url}, HTTP_HOST="example.com",
zio_list_url, {"informatieobject": eio1_url}, HTTP_HOST="example.com",
)

self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
self.assertEqual(response.data[0]["informatieobject"], eio_url)
self.assertEqual(response.data[0]["informatieobject"], eio1_url)

def test_update_zaak_and_informatieobject_fails(self):
zaak = ZaakFactory.create()
Expand Down

0 comments on commit a60d2d4

Please sign in to comment.