diff --git a/greg/api/filters.py b/greg/api/filters.py index c71b6be157731961facc75a8732abdac546ce9f1..5f265b5a9bc812954ff11a4af808ec8bde27e665 100644 --- a/greg/api/filters.py +++ b/greg/api/filters.py @@ -65,7 +65,11 @@ class PersonFilter(FilterSet): class IdentityFilter(FilterSet): class Meta: model = Identity - fields = ["type", "verified_by_id"] + fields = { + "type": ["exact"], + "verified_by_id": ["exact"], + "value": ["exact", "startswith"], + } class PersonConsentFilter(FilterSet): diff --git a/greg/api/urls.py b/greg/api/urls.py index 2e721797ed19d75ac9d684b1e0747c1dc5d5b965..9dc97d183566d70419629da19efadf5142fbd697 100644 --- a/greg/api/urls.py +++ b/greg/api/urls.py @@ -5,11 +5,12 @@ from rest_framework.routers import DefaultRouter from greg.api.views.consent_type import ConsentTypeViewSet from greg.api.views.invitation import InvitationViewSet +from greg.api.views.identity import IdentityViewSet from greg.api.views.organizational_unit import OrganizationalUnitViewSet from greg.api.views.person import ( RoleViewSet, PersonViewSet, - IdentityViewSet, + PersonIdentityViewSet, ConsentViewSet, ) from greg.api.views.role_type import RoleTypeViewSet @@ -45,12 +46,12 @@ urlpatterns += [ ), re_path( r"^persons/(?P<person_id>[0-9]+)/identities$", - IdentityViewSet.as_view({"get": "list", "post": "create"}), + PersonIdentityViewSet.as_view({"get": "list", "post": "create"}), name="person_identity-list", ), re_path( r"^persons/(?P<person_id>[0-9]+)/identities/(?P<id>[0-9]+)$", - IdentityViewSet.as_view( + PersonIdentityViewSet.as_view( {"get": "retrieve", "delete": "destroy", "patch": "partial_update"} ), name="person_identity-detail", @@ -89,4 +90,9 @@ urlpatterns += [ PersonSearchSet.as_view({"get": "list"}), name="person_search-list", ), + re_path( + "identities/", + IdentityViewSet.as_view({"get": "list"}), + name="identities-list", + ), ] diff --git a/greg/api/views/identity.py b/greg/api/views/identity.py new file mode 100644 index 0000000000000000000000000000000000000000..e757cce637099bdfce4c1aebe5e925fd227871b3 --- /dev/null +++ b/greg/api/views/identity.py @@ -0,0 +1,20 @@ +from django_filters import rest_framework as filters +from rest_framework import viewsets, permissions + +from greg.api.filters import IdentityFilter +from greg.api.pagination import PrimaryKeyCursorPagination +from greg.api.serializers.identity import IdentitySerializer +from greg.models import Identity + + +class IdentityViewSet(viewsets.ModelViewSet): + """ + Identity API + """ + + queryset = Identity.objects.all().order_by("id") + serializer_class = IdentitySerializer + pagination_class = PrimaryKeyCursorPagination + permission_classes = (permissions.IsAdminUser,) + filter_backends = (filters.DjangoFilterBackend,) + filterset_class = IdentityFilter diff --git a/greg/api/views/person.py b/greg/api/views/person.py index 9769b5f00be9fdb6b90e1b08d4f1158b2aa3c816..aa3116f3c72fe726a89e78ad6df9056790f07865 100644 --- a/greg/api/views/person.py +++ b/greg/api/views/person.py @@ -133,7 +133,7 @@ class RoleViewSet(viewsets.ModelViewSet): serializer.save(person_id=person_id) -class IdentityViewSet(viewsets.ModelViewSet): +class PersonIdentityViewSet(viewsets.ModelViewSet): """ Person identity API """ diff --git a/greg/tests/api/test_identity.py b/greg/tests/api/test_identity.py new file mode 100644 index 0000000000000000000000000000000000000000..6d7b926ca2c162ff9b98679a392131760ebc15ea --- /dev/null +++ b/greg/tests/api/test_identity.py @@ -0,0 +1,37 @@ +import pytest +from rest_framework.reverse import reverse + +from greg.models import Identity + + +@pytest.mark.django_db +def test_get_identity(client, identity_norwegian_national_id_number, person): + response = client.get( + reverse( + "v1:identities-list", + ), + data={ + "type": identity_norwegian_national_id_number.type, + "value": identity_norwegian_national_id_number.value, + }, + ) + + data = response.json()["results"][0] + assert data["type"] == identity_norwegian_national_id_number.type + assert data["value"] == identity_norwegian_national_id_number.value + assert data["person"] == person.id + + +@pytest.mark.django_db +def test_get_identity_value_startswith( + client, identity_us_passport_1, identity_us_passport_2 +): + response = client.get( + reverse( + "v1:identities-list", + ), + data={"type": Identity.IdentityType.PASSPORT_NUMBER, "value_startswith": "US-"}, + ) + + data = response.json()["results"] + assert len(data) == 2 diff --git a/greg/tests/conftest.py b/greg/tests/conftest.py index bcf3ba58062ff5cc633392219f86f73c57210077..1c2207c4aa9ae6efa8232bd0a10b59ab8d55ae52 100644 --- a/greg/tests/conftest.py +++ b/greg/tests/conftest.py @@ -61,6 +61,39 @@ def pcm_mock(): return PCMMock() +@pytest.fixture +def identity_norwegian_national_id_number(person) -> Identity: + pi = Identity.objects.create( + person=person, + type=Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER, + source="Test", + value="12345", + ) + return Identity.objects.get(id=pi.id) + + +@pytest.fixture +def identity_us_passport_1(person) -> Identity: + pi = Identity.objects.create( + person=person, + type=Identity.IdentityType.PASSPORT_NUMBER, + source="Test", + value="US-12345", + ) + return Identity.objects.get(id=pi.id) + + +@pytest.fixture +def identity_us_passport_2(person) -> Identity: + pi = Identity.objects.create( + person=person, + type=Identity.IdentityType.PASSPORT_NUMBER, + source="Test", + value="US-67890", + ) + return Identity.objects.get(id=pi.id) + + @pytest.fixture def person() -> Person: pe = Person.objects.create(