import datetime import re import pytest from django.utils import timezone from rest_framework.exceptions import ValidationError from gregui.api.serializers.role import RoleSerializerUi @pytest.mark.django_db def test_minimum_ok(role, sponsor_foo): """The minimum amount of fields works""" ser = RoleSerializerUi( data={ "person": role.person.id, "orgunit": role.orgunit.id, "type": role.type.id, "start_date": None, "end_date": (timezone.now() + datetime.timedelta(days=10)).date(), }, context={"sponsor": sponsor_foo}, ) assert ser.is_valid(raise_exception=True) @pytest.mark.django_db def test_start_date_past_fail(role, sponsor_foo): """Should fail because of start_date in the past""" ser = RoleSerializerUi( data={ "person": role.person.id, "orgunit": role.orgunit.id, "type": role.type.id, "start_date": (timezone.now() - datetime.timedelta(days=10)).date(), "end_date": (timezone.now() + datetime.timedelta(days=10)).date(), }, context={"sponsor": sponsor_foo}, ) with pytest.raises( ValidationError, match=re.escape( "{'start_date': [ErrorDetail(string='Start date cannot be in the past', code='invalid')]}" ), ): ser.is_valid(raise_exception=True) @pytest.mark.django_db def test_end_date_past_fail(role, sponsor_foo): """Should fail because of end_date in the past""" ser = RoleSerializerUi( data={ "person": role.person.id, "orgunit": role.orgunit.id, "type": role.type.id, "start_date": datetime.date.today(), "end_date": (timezone.now() - datetime.timedelta(days=10)).date(), }, context={"sponsor": sponsor_foo}, ) with pytest.raises( ValidationError, match=re.escape( "{'end_date': [ErrorDetail(string='End date cannot be in the past', code='invalid')]}" ), ): ser.is_valid(raise_exception=True) @pytest.mark.django_db def test_end_date_expired_role_fail(role, sponsor_foo): """New end date fail because role has ended""" # Expire the role to ensure failure role.end_date = datetime.date.today() - datetime.timedelta(days=10) role.save() # Try to change it ser = RoleSerializerUi( instance=role, data={ "person": role.person.id, "orgunit": role.orgunit.id, "type": role.type.id, "start_date": datetime.date.today(), "end_date": (timezone.now() + datetime.timedelta(days=10)).date(), }, context={"sponsor": sponsor_foo}, ) # Verify that a validation error is raised with pytest.raises( ValidationError, match=re.escape( "{'end_date': [ErrorDetail(string='Role has ended, cannot change end date', code='invalid')]}" ), ): ser.is_valid(raise_exception=True) @pytest.mark.django_db def test_wrong_sponsor(role, sponsor_foo, sponsor_bar): """Touching another sponsor's roles does not work""" # Try to touch sponsor_foo's guest role as sponsor_bar ser = RoleSerializerUi( instance=role, data={ "person": role.person.id, "orgunit": role.orgunit.id, "type": role.type.id, "start_date": datetime.date.today(), "end_date": (timezone.now() + datetime.timedelta(days=10)).date(), }, context={"sponsor": sponsor_bar}, ) # Verify that a validation error is raised with pytest.raises( ValidationError, match=re.escape( "{'non_field_errors': [ErrorDetail(string='You can only edit your own roles.', code='invalid')]}" ), ): ser.is_valid(raise_exception=True) @pytest.mark.django_db def test_too_future_end_date(role, sponsor_foo): """Setting the end date further than max_days of role_type fails""" max_future = timezone.now().date() + datetime.timedelta(days=role.type.max_days) ser = RoleSerializerUi( instance=role, data={ "person": role.person.id, "orgunit": role.orgunit.id, "type": role.type.id, "start_date": datetime.date.today(), "end_date": max_future + datetime.timedelta(days=1), }, context={"sponsor": sponsor_foo}, ) # Verify that a validation error is raised with pytest.raises( ValidationError, match=re.escape( "".join( [ "{'non_field_errors': [ErrorDetail(string=", f"'New end date too far into the future for this type. Must be before {max_future}.'", ", code='invalid')]}", ] ) ), ): ser.is_valid(raise_exception=True) @pytest.mark.django_db def test_end_before_start(role, sponsor_foo): """Setting the end date before start date not allowed""" # Existing instance ser = RoleSerializerUi( instance=role, data={ "person": role.person.id, "orgunit": role.orgunit.id, "type": role.type.id, "start_date": datetime.date.today() + datetime.timedelta(days=1), "end_date": datetime.date.today(), }, context={"sponsor": sponsor_foo}, ) # Verify that a validation error is raised with pytest.raises( ValidationError, match=re.escape( "".join( [ "{'non_field_errors': [ErrorDetail(string=", "'End date cannot be before start date.'", ", code='invalid')]}", ] ) ), ): ser.is_valid(raise_exception=True) # New instance ser = RoleSerializerUi( data={ "person": role.person.id, "orgunit": role.orgunit.id, "type": role.type.id, "start_date": datetime.date.today() + datetime.timedelta(days=1), "end_date": datetime.date.today(), }, context={"sponsor": sponsor_foo}, ) # Verify that a validation error is raised with pytest.raises( ValidationError, match=re.escape( "".join( [ "{'non_field_errors': [ErrorDetail(string=", "'End date cannot be before start date.'", ", code='invalid')]}", ] ) ), ): ser.is_valid(raise_exception=True)