Skip to content
Snippets Groups Projects
Commit 279b7951 authored by Tore.Brede's avatar Tore.Brede
Browse files

GREG-161: Updating test and formatting

parent 89b0ac62
No related branches found
No related tags found
1 merge request!228GREG-161: Search birthdate and name
Pipeline #108363 passed
......@@ -4,7 +4,7 @@ from rest_framework.fields import BooleanField, CharField, SerializerMethodField
from greg.api.serializers.consent import ConsentSerializerBrief
from greg.api.serializers.identity import IdentitySerializer, SpecialIdentitySerializer
from greg.api.serializers.role import RoleSerializer, SpecialRoleSerializer
from greg.models import Person, Identity
from greg.models import Person
class PersonSerializer(serializers.ModelSerializer):
......
......@@ -36,7 +36,10 @@ urlpatterns += [
name="invite-resend",
),
path("invite/", InvitationView.as_view(), name="invitation"),
path("person/search/", PersonSearchViewSet.as_view({"get": "list"}), name="person-search",
),
path(
"person/search/",
PersonSearchViewSet.as_view({"get": "list"}),
name="person-search",
),
path("userinfo/", UserInfoView.as_view(), name="userinfo"),
]
......@@ -40,7 +40,7 @@ class PersonViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, GenericV
class PersonSearchViewSet(GenericViewSet):
"""Search for persons using email or phone number"""
"""Search for persons using name, email, phone number and birth date"""
authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsAuthenticated, IsSponsor]
......@@ -56,12 +56,13 @@ class PersonSearchViewSet(GenericViewSet):
)
if len(self.request.query_params["q"]) > 50:
return Response(status=status.HTTP_400_BAD_REQUEST,
data={
"code": "search_term_too_large",
"message": "Search term is too large",
},
)
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
"code": "search_term_too_large",
"message": "Search term is too large",
},
)
hits = self.get_hits()
return Response(hits)
......@@ -70,32 +71,52 @@ class PersonSearchViewSet(GenericViewSet):
search = self.request.query_params["q"]
split_search = search.split()
words_joined = '|'.join(map(str, split_search))
search_regex = r'^(%s)' % words_joined
words_joined = "|".join(map(str, split_search))
# Create a regex with the terms in the search or-ed together. This will trigger a match
# if one of the fields that are being searched contains one of the terms
search_regex = r"^(%s)" % words_joined
hits = []
persons = Person.objects.filter(Q(first_name__iregex=search_regex) |
Q(last_name__iregex=search_regex) |
Q(date_of_birth__iregex=search_regex))[:10]
# First look for hits on name and birth date
persons = Person.objects.filter(
Q(first_name__iregex=search_regex)
| Q(last_name__iregex=search_regex)
| Q(date_of_birth__iregex=search_regex)
)[:10]
included_persons = []
for person in persons:
hits.append({"pid": person.id, "first": person.first_name, "last": person.last_name})
hits.append(
{"pid": person.id, "first": person.first_name, "last": person.last_name}
)
included_persons.append(person.id)
if len(hits) == 10:
# Max number of hits, no need to search more
return hits
# Look for hits in e-mail and mobile phone
identities = Identity.objects.filter(
value__iregex=search_regex,
type__in=[
Identity.IdentityType.PRIVATE_EMAIL,
Identity.IdentityType.PRIVATE_MOBILE_NUMBER,
],
)[:10]
)[: (10 - len(hits))]
for identity in identities:
if identity.person_id in included_persons:
continue
hits.append({"pid": identity.person_id, "first": identity.person.first_name, "last": identity.person.last_name, "value": identity.value, "type": identity.type})
hits.append(
{
"pid": identity.person_id,
"first": identity.person.first_name,
"last": identity.person.last_name,
"value": identity.value,
"type": identity.type,
}
)
return hits
......@@ -126,6 +147,6 @@ class GuestInfoViewSet(mixins.ListModelMixin, GenericViewSet):
units = user.sponsor.get_allowed_units()
return (
Person.objects.filter(roles__orgunit__in=list(units))
.distinct()
.order_by("id")
.distinct()
.order_by("id")
)
......@@ -4,8 +4,8 @@ from rest_framework.reverse import reverse
@pytest.mark.django_db
def test_name_search(client, log_in, user_sponsor, create_person):
person = create_person(
def test_no_search_parameter_fails(client, log_in, user_sponsor, create_person):
create_person(
first_name="foo",
last_name="bar",
email="foo@bar.com",
......@@ -26,7 +26,7 @@ def test_date_of_birth_search(client, log_in, user_sponsor, create_person):
first_name="foo",
last_name="bar",
email="foo@bar.com",
date_of_birth="2005-06-20"
date_of_birth="2005-06-20",
)
url = reverse("gregui-v1:person-search") + "?q=2005-06-20"
......@@ -47,18 +47,37 @@ def test_multiple_words_search(client, log_in, user_sponsor, create_person):
person = create_person(
first_name="foo",
last_name="bar",
email="example@company.com",
)
person2 = create_person(
first_name="test",
last_name="test2",
email="foo@bar.com",
date_of_birth="2005-06-20"
date_of_birth="2006-06-20",
)
person3 = create_person(
first_name="Bob",
last_name="Smith",
email="bob@smith.com",
date_of_birth="2005-06-20",
)
person4 = create_person(
first_name="Frank",
last_name="Paulsen",
email="frank@paulsen.com",
)
url = reverse("gregui-v1:person-search") + "?q=foo%20bar"
url = reverse("gregui-v1:person-search") + "?q=foo%20bar%202005-06-20"
log_in(user_sponsor)
response = client.get(url)
assert len(response.data) == 1
assert len(response.data) == 3
person_ids = list(map(lambda x: x["pid"], response.data))
assert person.id in person_ids
assert person2.id in person_ids
assert person3.id in person_ids
assert person4.id not in person_ids
assert response.status_code == status.HTTP_200_OK
......@@ -326,7 +326,9 @@ def invitation_link_expired(
@pytest.fixture
def create_person() -> Callable[[str, str, str, Optional[str], Optional[str], Optional[datetime.date]], Person]:
def create_person() -> Callable[
[str, str, str, Optional[str], Optional[str], Optional[datetime.date]], Person
]:
# TODO fix the typing...
def create_person(
first_name: str,
......@@ -334,12 +336,10 @@ def create_person() -> Callable[[str, str, str, Optional[str], Optional[str], Op
email: str = None,
nin: str = None,
feide_id: str = None,
date_of_birth: datetime.date = None
date_of_birth: datetime.date = None,
) -> Person:
person = Person.objects.create(
first_name=first_name,
last_name=last_name,
date_of_birth=date_of_birth
first_name=first_name, last_name=last_name, date_of_birth=date_of_birth
)
if nin:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment