From ad7c869c75a5541d08d75e956fd5514d5efc956a Mon Sep 17 00:00:00 2001 From: Andreas Ellewsen <ae@uio.no> Date: Tue, 12 Oct 2021 12:51:50 +0200 Subject: [PATCH] Add test of views using invitations --- gregui/api/urls.py | 4 +- gregui/api/views/invitation.py | 2 +- gregui/tests/api/test_invitation.py | 135 ++++++++++++++++++++++++++++ gregui/tests/conftest.py | 46 +++++++++- 4 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 gregui/tests/api/test_invitation.py diff --git a/gregui/api/urls.py b/gregui/api/urls.py index 64977e22..e5b04c50 100644 --- a/gregui/api/urls.py +++ b/gregui/api/urls.py @@ -16,7 +16,7 @@ urlpatterns = router.urls urlpatterns += [ re_path(r"roletypes/$", RoleTypeViewSet.as_view(), name="role-types"), re_path(r"units/$", UnitsViewSet.as_view(), name="units"), - path("invited/", InvitedGuestView.as_view(), name="invite"), - path("invited/<uuid>", CheckInvitationView.as_view()), + path("invited/", InvitedGuestView.as_view(), name="invited-info"), + path("invited/<uuid>", CheckInvitationView.as_view(), name="invite-verify"), path("invite/", CreateInvitationView.as_view(), name="invite-create"), ] diff --git a/gregui/api/views/invitation.py b/gregui/api/views/invitation.py index 82ac8bbc..18ac8723 100644 --- a/gregui/api/views/invitation.py +++ b/gregui/api/views/invitation.py @@ -169,7 +169,7 @@ class InvitedGuestView(APIView): clicked by the user. The next part of the flow is for the sponsor to confirm the guest. """ - invite_id = kwargs["uuid"] + invite_id = request.session.get("invite_id") data = request.data with transaction.atomic(): diff --git a/gregui/tests/api/test_invitation.py b/gregui/tests/api/test_invitation.py new file mode 100644 index 00000000..d2aa578d --- /dev/null +++ b/gregui/tests/api/test_invitation.py @@ -0,0 +1,135 @@ +import pytest + +from rest_framework import status +from rest_framework.reverse import reverse +from rest_framework.test import APIClient + +from greg.models import InvitationLink, Person + + +@pytest.mark.django_db +def test_get_invite(client): + """Forbid access with bad invitation link uuid""" + response = client.get( + reverse("gregui-v1:invite-verify", kwargs={"uuid": "baduuid"}) + ) + assert response.status_code == status.HTTP_403_FORBIDDEN + + +@pytest.mark.django_db +def test_get_invite_ok(client, invitation_link): + """Access okay with valid invitation link""" + response = client.get( + reverse("gregui-v1:invite-verify", kwargs={"uuid": invitation_link.uuid}) + ) + assert response.status_code == status.HTTP_200_OK + + +@pytest.mark.django_db +def test_get_invite_expired(client, invitation_link_expired): + """Forbid access with expired invite link""" + response = client.get( + reverse( + "gregui-v1:invite-verify", kwargs={"uuid": invitation_link_expired.uuid} + ) + ) + assert response.status_code == status.HTTP_403_FORBIDDEN + + +@pytest.mark.django_db +def test_get_invited_info_no_session(client, invitation_link): + response = client.get(reverse("gregui-v1:invited-info")) + assert response.status_code == status.HTTP_403_FORBIDDEN + + +@pytest.mark.django_db +def test_get_invited_info_session_okay(client, invitation_link): + # get a session + client.get( + reverse("gregui-v1:invite-verify", kwargs={"uuid": invitation_link.uuid}) + ) + # Get info + response = client.get(reverse("gregui-v1:invited-info")) + assert response.status_code == status.HTTP_200_OK + data = response.json() + assert data.get("person") + assert data.get("sponsor") + assert data.get("role") + + +@pytest.mark.django_db +def test_get_invited_info_expired_link(client, invitation_link): + # Get a session while link is valid + client.get( + reverse("gregui-v1:invite-verify", kwargs={"uuid": invitation_link.uuid}) + ) + # Set expire link to expire long ago + invlink = InvitationLink.objects.get(uuid=invitation_link.uuid) + invlink.expire = "1970-01-01" + invlink.save() + # Make a get request that should fail because invite expired after login, but + # before get to userinfo + response = client.get(reverse("gregui-v1:invited-info")) + assert response.status_code == status.HTTP_403_FORBIDDEN + + +@pytest.mark.django_db +def test_post_invited_info_ok_mobile_update(client: APIClient, invitation_link): + # get a session + client.get( + reverse("gregui-v1:invite-verify", kwargs={"uuid": invitation_link.uuid}) + ) + # post updated info to confirm from guest + new_phone = "12345678" + post_data = {"mobile_phone": new_phone} + response = client.post( + reverse("gregui-v1:invited-info"), + post_data, + format="json", + ) + assert response.status_code == status.HTTP_201_CREATED + # Check that the object was updated in the database + person = Person.objects.get(id=invitation_link.invitation.role.person.id) + assert person.mobile_phone == new_phone + + +@pytest.mark.django_db +def test_post_invited_info_ok(client, invitation_link): + # get a session + client.get( + reverse("gregui-v1:invite-verify", kwargs={"uuid": invitation_link.uuid}) + ) + # post updated info to confirm from guest + response = client.post(reverse("gregui-v1:invited-info")) + assert response.status_code == status.HTTP_201_CREATED + + +@pytest.mark.django_db +def test_post_invited_info_expired_session(client, invitation_link): + # get a session + client.get( + reverse("gregui-v1:invite-verify", kwargs={"uuid": invitation_link.uuid}) + ) + # Set expire link to expire long ago + invlink = InvitationLink.objects.get(uuid=invitation_link.uuid) + invlink.expire = "1970-01-01" + invlink.save() + # post updated info to confirm from guest, should fail because of expired + # invitation link + response = client.post(reverse("gregui-v1:invited-info")) + assert response.status_code == status.HTTP_403_FORBIDDEN + + +@pytest.mark.django_db +def test_post_invited_info_deleted_inv_link(client, invitation_link): + # get a session + client.get( + reverse("gregui-v1:invite-verify", kwargs={"uuid": invitation_link.uuid}) + ) + # Delete link + invlink = InvitationLink.objects.get(uuid=invitation_link.uuid) + invlink.delete() + # post updated info to confirm from guest, should fail because of removed + # invitation link + response = client.post(reverse("gregui-v1:invited-info")) + assert response.status_code == status.HTTP_403_FORBIDDEN diff --git a/gregui/tests/conftest.py b/gregui/tests/conftest.py index b71080b0..40d3fab6 100644 --- a/gregui/tests/conftest.py +++ b/gregui/tests/conftest.py @@ -6,7 +6,15 @@ from rest_framework.test import APIClient import pytest -from greg.models import Sponsor, OrganizationalUnit, RoleType +from greg.models import ( + Invitation, + InvitationLink, + OrganizationalUnit, + Person, + Role, + RoleType, + Sponsor, +) from gregui.models import GregUserProfile # faker spams the logs with localisation warnings @@ -56,3 +64,39 @@ def user_sponsor(sponsor_guy: Sponsor) -> User: # This user is a sponsor for unit_foo return user + + +@pytest.fixture +def person() -> Person: + pe = Person.objects.create() + return Person.objects.get(id=pe.id) + + +@pytest.fixture +def role(person, sponsor_guy, unit_foo, role_type_foo) -> Role: + role = Role.objects.create( + person=person, + sponsor_id=sponsor_guy, + orgunit_id=unit_foo, + end_date="2050-10-15", + type_id=role_type_foo.id, + ) + return Role.objects.get(id=role.id) + + +@pytest.fixture +def invitation(role) -> Invitation: + inv = Invitation.objects.create(role=role) + return Invitation.objects.get(id=inv.id) + + +@pytest.fixture +def invitation_link(invitation) -> InvitationLink: + il = InvitationLink.objects.create(invitation=invitation, expire="2060-10-15") + return InvitationLink.objects.get(id=il.id) + + +@pytest.fixture +def invitation_link_expired(invitation) -> InvitationLink: + il = InvitationLink.objects.create(invitation=invitation, expire="1970-01-01") + return InvitationLink.objects.get(id=il.id) -- GitLab