diff --git a/greg/admin.py b/greg/admin.py index d73bdab829f508534fac1eea3473a2ef7a1a1a35..3722fcf28c0e84b494cce1521abb73c08f85e789 100644 --- a/greg/admin.py +++ b/greg/admin.py @@ -3,8 +3,8 @@ from reversion.admin import VersionAdmin from greg.models import ( Person, - PersonRole, Role, + RoleType, PersonIdentity, Consent, PersonConsent, @@ -17,7 +17,7 @@ admin.site.site_header = "Guest Registration Admin" class RoleInline(admin.TabularInline): - model = PersonRole + model = Role extra = 1 @@ -47,18 +47,18 @@ class PersonAdmin(VersionAdmin): role_count.short_description = "# roles" # type: ignore -class PersonRoleAdmin(VersionAdmin): - list_display = ("id", "person", "role") +class RoleAdmin(VersionAdmin): + list_display = ("id", "person", "type") search_fields = ( "person__id", - "role__id", + "type__id", ) - raw_id_fields = ("person", "role") + raw_id_fields = ("person", "type") readonly_fields = ("id", "created", "updated") -class RoleAdmin(VersionAdmin): - list_display = ("id", "type", "name_nb", "name_en") +class RoleTypeAdmin(VersionAdmin): + list_display = ("id", "identifier", "name_nb", "name_en") readonly_fields = ("id", "created", "updated") @@ -104,8 +104,8 @@ class SponsorOrganizationalUnitAdmin(VersionAdmin): admin.site.register(Person, PersonAdmin) -admin.site.register(PersonRole, PersonRoleAdmin) admin.site.register(Role, RoleAdmin) +admin.site.register(RoleType, RoleTypeAdmin) admin.site.register(PersonIdentity, PersonIdentityAdmin) admin.site.register(Consent, ConsentAdmin) admin.site.register(PersonConsent, PersonConsentAdmin) diff --git a/greg/api/filters.py b/greg/api/filters.py index c7af546c6b456316345e0f4977fc2a1675cec7e9..d88b1b724ac8374d8f68aa5c912d3f7be9390755 100644 --- a/greg/api/filters.py +++ b/greg/api/filters.py @@ -6,7 +6,7 @@ from django_filters.rest_framework import ( from greg.models import ( Person, - PersonRole, + Role, PersonIdentity, ) @@ -15,7 +15,7 @@ class PersonRoleFilter(FilterSet): type = BaseInFilter(field_name="role__type", lookup_expr="in") class Meta: - model = PersonRole + model = Role fields = ["type"] diff --git a/greg/api/serializers/__init__.py b/greg/api/serializers/__init__.py index f6fe4dc2514fc0c9f45510b26ab737a03fca983b..ca5bdad3c424bdcde320e7ef21107d2e4870a92f 100644 --- a/greg/api/serializers/__init__.py +++ b/greg/api/serializers/__init__.py @@ -1,11 +1,11 @@ from .notification import NotificationSerializer from .person import PersonSerializer -from .role import RoleSerializer +from .role_type import RoleTypeSerializer def get_serializer(instance): return { "notification": NotificationSerializer, "person": PersonSerializer, - "role": RoleSerializer, + "role": RoleTypeSerializer, }.get(instance._meta.verbose_name) diff --git a/greg/api/serializers/person.py b/greg/api/serializers/person.py index 720972d75296594cc6438df985d29276efe04638..30320561161eae174e8c1c0f2ad708f748af1184 100644 --- a/greg/api/serializers/person.py +++ b/greg/api/serializers/person.py @@ -1,13 +1,15 @@ from rest_framework import serializers -from greg.models import Person, PersonRole, Role, PersonIdentity, PersonConsent, Consent +from greg.models import Person, Role, RoleType, PersonIdentity, PersonConsent, Consent -class PersonRoleSerializer(serializers.ModelSerializer): - role = serializers.SlugRelatedField(queryset=Role.objects.all(), slug_field="type") +class RoleSerializer(serializers.ModelSerializer): + type = serializers.SlugRelatedField( + queryset=RoleType.objects.all(), slug_field="identifier" + ) class Meta: - model = PersonRole + model = Role fields = [ "id", "start_date", @@ -16,7 +18,7 @@ class PersonRoleSerializer(serializers.ModelSerializer): "unit", "created", "updated", - "role", + "type", ] @@ -61,7 +63,7 @@ class PersonConsentSerializerBrief(serializers.ModelSerializer): class PersonSerializer(serializers.ModelSerializer): identities = PersonIdentitySerializer(many=True, read_only=True) - person_roles = PersonRoleSerializer(many=True, read_only=True) + roles = RoleSerializer(many=True, read_only=True) person_consent = PersonConsentSerializerBrief(many=True, read_only=True) class Meta: @@ -79,6 +81,6 @@ class PersonSerializer(serializers.ModelSerializer): "registration_completed_date", "token", "identities", - "person_roles", + "roles", "person_consent", ] diff --git a/greg/api/serializers/role.py b/greg/api/serializers/role_type.py similarity index 50% rename from greg/api/serializers/role.py rename to greg/api/serializers/role_type.py index 3fd2d03d884330f481e529919126ee6350221e2f..d52c5efcf2fd41b190b2ee160ebb5e9d4c0ca841 100644 --- a/greg/api/serializers/role.py +++ b/greg/api/serializers/role_type.py @@ -1,9 +1,9 @@ from rest_framework.serializers import ModelSerializer -from greg.models import Role +from greg.models import RoleType -class RoleSerializer(ModelSerializer): +class RoleTypeSerializer(ModelSerializer): class Meta: - model = Role + model = RoleType fields = "__all__" diff --git a/greg/api/urls.py b/greg/api/urls.py index 6428641d97d1370684bb8c48b6c231bf16bd2ae8..5ba6fa352d49cf0d94077a72775e434b49939178 100644 --- a/greg/api/urls.py +++ b/greg/api/urls.py @@ -6,16 +6,16 @@ from rest_framework.routers import DefaultRouter from greg.api.views.consent import ConsentViewSet from greg.api.views.organizational_unit import OrganizationalUnitViewSet from greg.api.views.person import ( - PersonRoleViewSet, + RoleViewSet, PersonViewSet, PersonIdentityViewSet, ) -from greg.api.views.role import RoleViewSet +from greg.api.views.role_type import RoleTypeViewSet from greg.api.views.sponsor import SponsorViewSet, SponsorGuestsViewSet router = DefaultRouter() router.register(r"persons", PersonViewSet, basename="person") -router.register(r"roles", RoleViewSet, basename="role") +router.register(r"roletypes", RoleTypeViewSet, basename="roletype") router.register(r"consents", ConsentViewSet, basename="consent") router.register(r"sponsors", SponsorViewSet, basename="sponsor") router.register(r"orgunit", OrganizationalUnitViewSet, basename="orgunit") @@ -26,12 +26,12 @@ urlpatterns = router.urls urlpatterns += [ re_path( r"^persons/(?P<person_id>[0-9]+)/roles/$", - PersonRoleViewSet.as_view({"get": "list", "post": "create"}), + RoleViewSet.as_view({"get": "list", "post": "create"}), name="person_role-list", ), re_path( r"^persons/(?P<person_id>[0-9]+)/roles/(?P<id>[0-9]+)/$", - PersonRoleViewSet.as_view( + RoleViewSet.as_view( {"get": "retrieve", "patch": "partial_update", "delete": "destroy"} ), name="person_role-detail", diff --git a/greg/api/views/person.py b/greg/api/views/person.py index bb58842992f4afc293d90a6f7457388046579382..6759425bafb2abc9d812e3092ffde9863238fc84 100644 --- a/greg/api/views/person.py +++ b/greg/api/views/person.py @@ -8,10 +8,10 @@ from greg.api.filters import PersonFilter, PersonRoleFilter, PersonIdentityFilte from greg.api.pagination import PrimaryKeyCursorPagination from greg.api.serializers.person import ( PersonSerializer, - PersonRoleSerializer, + RoleSerializer, PersonIdentitySerializer, ) -from greg.models import Person, PersonRole, PersonIdentity +from greg.models import Person, Role, PersonIdentity class PersonViewSet(viewsets.ModelViewSet): @@ -39,11 +39,11 @@ class PersonViewSet(viewsets.ModelViewSet): return super().list(request, *args, **kwargs) -class PersonRoleViewSet(viewsets.ModelViewSet): +class RoleViewSet(viewsets.ModelViewSet): """Person role API""" - queryset = PersonRole.objects.all().order_by("id") - serializer_class = PersonRoleSerializer + queryset = Role.objects.all().order_by("id") + serializer_class = RoleSerializer pagination_class = PrimaryKeyCursorPagination filter_backends = (filters.DjangoFilterBackend,) filterset_class = PersonRoleFilter diff --git a/greg/api/views/role.py b/greg/api/views/role.py deleted file mode 100644 index fbfce2fd85e3b515ccbce00cbe9778aa3b7d8994..0000000000000000000000000000000000000000 --- a/greg/api/views/role.py +++ /dev/null @@ -1,14 +0,0 @@ -from rest_framework import viewsets - -from greg.api.pagination import PrimaryKeyCursorPagination -from greg.api.serializers.role import RoleSerializer -from greg.models import Role - - -class RoleViewSet(viewsets.ModelViewSet): - """Role API""" - - queryset = Role.objects.all().order_by("id") - serializer_class = RoleSerializer - pagination_class = PrimaryKeyCursorPagination - lookup_field = "id" diff --git a/greg/api/views/role_type.py b/greg/api/views/role_type.py new file mode 100644 index 0000000000000000000000000000000000000000..cb39712515c5e87325dac0ae3551e3b5399af8ac --- /dev/null +++ b/greg/api/views/role_type.py @@ -0,0 +1,14 @@ +from rest_framework import viewsets + +from greg.api.pagination import PrimaryKeyCursorPagination +from greg.api.serializers.role_type import RoleTypeSerializer +from greg.models import RoleType + + +class RoleTypeViewSet(viewsets.ModelViewSet): + """Role type API""" + + queryset = RoleType.objects.all().order_by("id") + serializer_class = RoleTypeSerializer + pagination_class = PrimaryKeyCursorPagination + lookup_field = "id" diff --git a/greg/api/views/sponsor.py b/greg/api/views/sponsor.py index d88772b523da93de2e60eb1a6cf15c644a298111..6e149fea441514b7d3a58aa2928da00e6d53e080 100644 --- a/greg/api/views/sponsor.py +++ b/greg/api/views/sponsor.py @@ -39,5 +39,5 @@ class SponsorGuestsViewSet(mixins.ListModelMixin, GenericViewSet): if not self.kwargs: return qs.none() sponsor_id = self.kwargs["sponsor_id"] - qs = qs.filter(person_roles__registered_by=sponsor_id).order_by("id") + qs = qs.filter(roles__registered_by=sponsor_id).order_by("id") return qs diff --git a/greg/migrations/0001_initial.py b/greg/migrations/0001_initial.py index 57ab464e0e28796d720fd454be2879facd5ea84a..64b1d8a93475a151aedbaf3a873859d17d2512fc 100644 --- a/greg/migrations/0001_initial.py +++ b/greg/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.5 on 2021-08-23 08:53 +# Generated by Django 3.2.5 on 2021-08-30 22:16 import datetime import dirtyfields.dirtyfields @@ -87,12 +87,12 @@ class Migration(migrations.Migration): bases=(dirtyfields.dirtyfields.DirtyFieldsMixin, models.Model), ), migrations.CreateModel( - name='Role', + name='RoleType', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created', models.DateTimeField(auto_now_add=True)), ('updated', models.DateTimeField(auto_now=True)), - ('type', models.SlugField(max_length=64, unique=True)), + ('identifier', models.SlugField(max_length=64, unique=True)), ('name_nb', models.CharField(max_length=256)), ('name_en', models.CharField(max_length=256)), ('description_nb', models.TextField()), @@ -142,7 +142,7 @@ class Migration(migrations.Migration): field=models.ManyToManyField(related_name='sponsor_unit', through='greg.SponsorOrganizationalUnit', to='greg.OrganizationalUnit'), ), migrations.CreateModel( - name='PersonRole', + name='Role', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created', models.DateTimeField(auto_now_add=True)), @@ -152,9 +152,9 @@ class Migration(migrations.Migration): ('contact_person_unit', models.TextField(blank=True)), ('comments', models.TextField(blank=True)), ('available_in_search', models.BooleanField(default=False)), - ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='person_roles', to='greg.person')), + ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='roles', to='greg.person')), ('registered_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='sponsor_role', to='greg.sponsor')), - ('role', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='person_roles', to='greg.role')), + ('type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='person_roles', to='greg.roletype')), ('unit', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='unit_person_role', to='greg.organizationalunit')), ], bases=(dirtyfields.dirtyfields.DirtyFieldsMixin, models.Model), @@ -174,7 +174,7 @@ class Migration(migrations.Migration): ('verified_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='sponsor', to='greg.sponsor')), ], options={ - 'abstract': False, + 'verbose_name_plural': 'person identities', }, bases=(dirtyfields.dirtyfields.DirtyFieldsMixin, models.Model), ), @@ -185,8 +185,8 @@ class Migration(migrations.Migration): ('created', models.DateTimeField(auto_now_add=True)), ('updated', models.DateTimeField(auto_now=True)), ('consent_given_at', models.DateField(null=True)), - ('consent', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='link_person_consent', to='greg.consent')), - ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='link_person_consent', to='greg.person')), + ('consent', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='person_consent', to='greg.consent')), + ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='person_consent', to='greg.person')), ], bases=(dirtyfields.dirtyfields.DirtyFieldsMixin, models.Model), ), @@ -197,8 +197,8 @@ class Migration(migrations.Migration): ), migrations.AddField( model_name='person', - name='roles', - field=models.ManyToManyField(related_name='persons', through='greg.PersonRole', to='greg.Role'), + name='role_types', + field=models.ManyToManyField(related_name='persons', through='greg.Role', to='greg.RoleType'), ), migrations.AddConstraint( model_name='sponsororganizationalunit', @@ -209,8 +209,8 @@ class Migration(migrations.Migration): constraint=models.UniqueConstraint(fields=('feide_id',), name='unique_feide_id'), ), migrations.AddConstraint( - model_name='personrole', - constraint=models.UniqueConstraint(fields=('person_id', 'role_id', 'unit_id', 'start_date', 'end_date'), name='person_role_unique'), + model_name='role', + constraint=models.UniqueConstraint(fields=('person_id', 'type_id', 'unit_id', 'start_date', 'end_date'), name='person_role_type_unique'), ), migrations.AddConstraint( model_name='personconsent', diff --git a/greg/migrations/0002_auto_20210827_1437.py b/greg/migrations/0002_auto_20210827_1437.py deleted file mode 100644 index db4be5644728b585677111dd9a127c568fd6df4e..0000000000000000000000000000000000000000 --- a/greg/migrations/0002_auto_20210827_1437.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 3.2.5 on 2021-08-27 14:37 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('greg', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='personconsent', - name='consent', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='person_consent', to='greg.consent'), - ), - migrations.AlterField( - model_name='personconsent', - name='person', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='person_consent', to='greg.person'), - ), - ] diff --git a/greg/models.py b/greg/models.py index 2571bba1084c9198397ddd87a303321076cbd5bb..626447365f0b832c379b088f765210e3f84d7765 100644 --- a/greg/models.py +++ b/greg/models.py @@ -44,7 +44,9 @@ class Person(BaseModel): mobile_phone_verified_date = models.DateField(null=True) registration_completed_date = models.DateField(null=True) token = models.CharField(max_length=32, blank=True) - roles = models.ManyToManyField("Role", through="PersonRole", related_name="persons") + role_types = models.ManyToManyField( + "RoleType", through="Role", related_name="persons" + ) consents = models.ManyToManyField( "Consent", through="PersonConsent", related_name="consent" ) @@ -120,10 +122,10 @@ class Person(BaseModel): ) -class Role(BaseModel): +class RoleType(BaseModel): """A role variant.""" - type = models.SlugField(max_length=64, unique=True) + identifier = models.SlugField(max_length=64, unique=True) name_nb = models.CharField(max_length=256) name_en = models.CharField(max_length=256) description_nb = models.TextField() @@ -134,23 +136,21 @@ class Role(BaseModel): return str(self.name_nb or self.name_en) def __repr__(self): - return "{}(id={!r}, type={!r}, name_nb={!r}, name_en={!r})".format( + return "{}(pk={!r}, identifier={!r}, name_nb={!r}, name_en={!r})".format( self.__class__.__name__, self.pk, - self.type, + self.identifier, self.name_nb, self.name_en, ) -class PersonRole(BaseModel): +class Role(BaseModel): """The relationship between a person and a role.""" - person = models.ForeignKey( - "Person", on_delete=models.CASCADE, related_name="person_roles" - ) - role = models.ForeignKey( - "Role", on_delete=models.PROTECT, related_name="person_roles" + person = models.ForeignKey("Person", on_delete=models.CASCADE, related_name="roles") + type = models.ForeignKey( + "RoleType", on_delete=models.PROTECT, related_name="person_roles" ) unit = models.ForeignKey( "OrganizationalUnit", on_delete=models.PROTECT, related_name="unit_person_role" @@ -169,14 +169,14 @@ class PersonRole(BaseModel): class Meta: constraints = [ models.UniqueConstraint( - fields=["person_id", "role_id", "unit_id", "start_date", "end_date"], - name="person_role_unique", + fields=["person_id", "type_id", "unit_id", "start_date", "end_date"], + name="person_role_type_unique", ) ] def __repr__(self): - return "{}(id={!r}, person={!r}, role={!r})".format( - self.__class__.__name__, self.pk, self.person, self.role + return "{}(id={!r}, person={!r}, type={!r})".format( + self.__class__.__name__, self.pk, self.person, self.type ) @@ -240,6 +240,9 @@ class PersonIdentity(BaseModel): self.verified_when, ) + class Meta: + verbose_name_plural = "person identities" + class Consent(BaseModel): """ diff --git a/greg/schedule.py b/greg/schedule.py index e9a907e36be35fd8c55d6ff7fc215c468c01731d..ee08c9a79ce2285b1d7189ce9cbfcf7d000713c9 100644 --- a/greg/schedule.py +++ b/greg/schedule.py @@ -5,7 +5,7 @@ from typing import Optional from abc import ABC, abstractmethod from django.utils import timezone -from greg.models import PersonRole, Notification, ScheduleTask +from greg.models import Role, Notification, ScheduleTask class BaseSchedule(ABC): @@ -77,12 +77,12 @@ class ExpiringRolesNotification(BaseSchedule): self.__get_roles_about_to_expire(check_date) def __get_roles_about_to_expire(self, end_date: date): - roles_about_to_expire = PersonRole.objects.filter(end_date=end_date) + roles_about_to_expire = Role.objects.filter(end_date=end_date) - for person_role in roles_about_to_expire: - meta = {"person_id": person_role.person.id, "role_id": person_role.role.id} + for role in roles_about_to_expire: + meta = {"person_id": role.person.id, "type_id": role.type.id} self._store_notification( - identifier=person_role.id, + identifier=role.id, object_type="PersonRole", operation="expire_reminder", **meta diff --git a/greg/signals.py b/greg/signals.py index e1d0f60c7abab9bd97d0c988a5e6e46ea6d4037d..432483e352ad52f6b6c6c4d16fa8283764baaa35 100644 --- a/greg/signals.py +++ b/greg/signals.py @@ -7,8 +7,8 @@ from django.dispatch import receiver from greg.models import ( Person, - PersonRole, Role, + RoleType, Notification, PersonIdentity, PersonConsent, @@ -19,8 +19,8 @@ logger = logging.getLogger(__name__) SUPPORTED_MODELS = ( Person, - PersonRole, Role, + RoleType, PersonIdentity, PersonConsent, ) @@ -123,7 +123,7 @@ def m2m_changed_notification_callback( ): if action not in ("post_add", "post_remove"): return - if sender not in (PersonConsent, PersonRole, PersonIdentity): + if sender not in (PersonConsent, Role, PersonIdentity): return operation = "add" if action == "post_add" else "delete" @@ -148,22 +148,18 @@ def m2m_changed_notification_callback( operation=operation, **meta ) - elif sender is PersonRole: - person_roles = [] - if instance_type is Person and model is Role: - person_roles = PersonRole.objects.filter( - person_id=instance.id, role_id__in=pk_set - ) - elif instance_type is Role and model is Person: - person_roles = PersonRole.objects.filter( - role_id=instance.id, person_id__in=pk_set - ) - - for pr in person_roles: + elif sender is Role: + roles = [] + if instance_type is Person and model is RoleType: + roles = Role.objects.filter(person_id=instance.id, role_id__in=pk_set) + elif instance_type is RoleType and model is Person: + roles = Role.objects.filter(role_id=instance.id, person_id__in=pk_set) + + for pr in roles: meta = _create_metadata(pr) _store_notification( identifier=pr.id, - object_type=PersonRole._meta.object_name, + object_type=Role._meta.object_name, operation=operation, **meta ) @@ -172,9 +168,9 @@ def m2m_changed_notification_callback( def _create_metadata(instance) -> Dict: meta = {} - if isinstance(instance, PersonRole): + if isinstance(instance, Role): meta["person_id"] = instance.person.id - meta["role_id"] = instance.role.id + meta["type_id"] = instance.type.id if isinstance(instance, PersonIdentity): meta["person_id"] = instance.person.id meta["identity_id"] = instance.id diff --git a/greg/tests/api/test_person.py b/greg/tests/api/test_person.py index 772c6ee546a8823dc339d19b12495ffe1008a0c6..e6757e0e9e62629f1143173c8b92049daaf1f127 100644 --- a/greg/tests/api/test_person.py +++ b/greg/tests/api/test_person.py @@ -10,18 +10,18 @@ from django.core.exceptions import ValidationError from greg.models import ( PersonIdentity, Sponsor, - Role, + RoleType, OrganizationalUnit, Consent, Person, - PersonRole, + Role, ) @pytest.fixture -def role_visiting_professor() -> Role: - return Role.objects.create( - type="visiting_professor", +def role_type_visiting_professor() -> RoleType: + return RoleType.objects.create( + identifier="visiting_professor", name_nb="Gjesteprofessor", name_en="Visiting professor", description_nb="Gjesteprofessor", @@ -44,10 +44,10 @@ def sponsor_bar() -> Sponsor: @pytest.fixture def role_data_guest( - role_test_guest: Role, sponsor_bar: Sponsor, unit_foo: OrganizationalUnit + role_type_test_guest: RoleType, sponsor_bar: Sponsor, unit_foo: OrganizationalUnit ) -> Dict: return { - "role": "Test Guest", + "type": "Test Guest", "start_date": "2021-06-10", "end_date": "2021-08-10", "registered_by": sponsor_bar.id, @@ -114,7 +114,7 @@ def test_persons_verified_filter_exclude( @pytest.mark.django_db def test_add_role( - client, person_foo, role_visiting_professor, sponsor_guy, unit_human_resources + client, person_foo, role_type_visiting_professor, sponsor_guy, unit_human_resources ): url = reverse("v1:person_role-list", kwargs={"person_id": person_foo.id}) roles_for_person = client.get(url).json()["results"] @@ -123,7 +123,7 @@ def test_add_role( assert len(roles_for_person) == 0 role_data = { - "role": "visiting_professor", + "type": "visiting_professor", "start_date": "2021-06-10", "end_date": "2021-08-10", "registered_by": "1", @@ -398,16 +398,14 @@ def test_remove_person( @pytest.mark.django_db -def test_add_duplicate_role_fails( - client, person_foo: Person, person_foo_role: PersonRole -): +def test_add_duplicate_role_fails(client, person_foo: Person, person_foo_role: Role): url = reverse("v1:person_role-list", kwargs={"person_id": person_foo.id}) roles_for_person = client.get(url).json()["results"] assert len(roles_for_person) == 1 role_data = { - "role": person_foo_role.role_id, + "type": person_foo_role.type_id, "start_date": person_foo_role.start_date, "end_date": person_foo_role.end_date, "registered_by": person_foo_role.registered_by, diff --git a/greg/tests/conftest.py b/greg/tests/conftest.py index 63646efdd9947cd04f5ec31079c855447e8b73b2..bf70862847668e3623708bdd7bfaf35f9bab9d5a 100644 --- a/greg/tests/conftest.py +++ b/greg/tests/conftest.py @@ -11,8 +11,8 @@ from greg.models import ( Sponsor, PersonIdentity, Role, + RoleType, OrganizationalUnit, - PersonRole, ) # faker spams the logs with localisation warnings @@ -82,8 +82,8 @@ def person_foo_not_verified(person_foo) -> PersonIdentity: @pytest.fixture() -def role_test_guest() -> Role: - return Role.objects.create(type="Test Guest") +def role_type_test_guest() -> RoleType: + return RoleType.objects.create(identifier="Test Guest") @pytest.fixture @@ -94,13 +94,13 @@ def unit_foo() -> OrganizationalUnit: @pytest.fixture def person_foo_role( person_foo: Person, - role_test_guest: Role, + role_type_test_guest: RoleType, sponsor_guy: Sponsor, unit_foo: OrganizationalUnit, -) -> PersonRole: - return PersonRole.objects.create( +) -> Role: + return Role.objects.create( person=person_foo, - role=role_test_guest, + type=role_type_test_guest, start_date="2021-08-02", end_date="2021-08-06", registered_by=sponsor_guy, diff --git a/greg/tests/models/test_person.py b/greg/tests/models/test_person.py index 87455763326c84b814830ceb84f00f52c9b869fa..9a7e6a9f44b2c3c1e0e2cc1badf420fd7ea31701 100644 --- a/greg/tests/models/test_person.py +++ b/greg/tests/models/test_person.py @@ -10,13 +10,13 @@ from greg.models import ( OrganizationalUnit, Person, PersonIdentity, - PersonRole, Role, + RoleType, Sponsor, ) -person_role_with = partial( - PersonRole.objects.create, +role_with = partial( + Role.objects.create, start_date="2020-03-05", end_date="2020-06-10", contact_person_unit="Contact Person", @@ -25,17 +25,17 @@ person_role_with = partial( @pytest.fixture -def role_foo() -> Role: - return Role.objects.create(type="role_foo", name_en="Role Foo") +def role_type_foo() -> RoleType: + return RoleType.objects.create(identifier="role_foo", name_en="Role Foo") @pytest.fixture -def role_bar() -> Role: - return Role.objects.create(type="role_bar", name_en="Role Bar") +def role_type_bar() -> RoleType: + return RoleType.objects.create(identifier="role_bar", name_en="Role Bar") @pytest.fixture -def person(role_foo: Role, role_bar: Role) -> Person: +def person(role_type_foo: RoleType, role_type_bar: RoleType) -> Person: person = Person.objects.create( first_name="Test", last_name="Tester", @@ -45,15 +45,15 @@ def person(role_foo: Role, role_bar: Role) -> Person: ) ou = OrganizationalUnit.objects.create(orgreg_id="12345", name_en="Test unit") - person_role_with( + role_with( person=person, - role=role_foo, + type=role_type_foo, unit=ou, registered_by=Sponsor.objects.create(feide_id="foosponsor@uio.no"), ) - person_role_with( + role_with( person=person, - role=role_bar, + type=role_type_bar, unit=ou, registered_by=Sponsor.objects.create(feide_id="barsponsor@uio.no"), ) @@ -107,11 +107,13 @@ def feide_verified(person: Person, feide_id: PersonIdentity) -> Person: @pytest.mark.django_db -def test_add_multiple_roles_to_person(person, role_foo, role_bar): - person_roles = person.roles.all() - assert len(person_roles) == 2 - assert role_foo in person_roles - assert role_bar in person_roles +def test_add_multiple_roles_to_person( + person: Person, role_type_foo: RoleType, role_type_bar: RoleType +): + role_types = person.role_types.all() + assert len(role_types) == 2 + assert role_type_foo in role_types + assert role_type_bar in role_types @pytest.mark.django_db diff --git a/greg/tests/populate_database.py b/greg/tests/populate_database.py index 1dd064aabab4ffaea36a2546180f7ce6a3f310e8..d60de04c0eab88a0791c109abcef04b622e3dce0 100644 --- a/greg/tests/populate_database.py +++ b/greg/tests/populate_database.py @@ -5,10 +5,10 @@ from django.db import connection, IntegrityError from faker import Faker from greg.models import ( Person, - Role, + RoleType, OrganizationalUnit, Sponsor, - PersonRole, + Role, Consent, PersonIdentity, ) @@ -28,7 +28,7 @@ class DatabasePopulation: persons: List[Person] = [] units: List[OrganizationalUnit] = [] sponsors: List[Sponsor] = [] - role_types: List[Role] = [] + role_types: List[RoleType] = [] consents: List[Consent] = [] random: random.Random @@ -62,7 +62,7 @@ class DatabasePopulation: for role_type in ("Visiting Professor", "Professor Emeritus", "Consultant"): self.role_types.append( - Role.objects.create(type=role_type, name_en=role_type) + RoleType.objects.create(type=role_type, name_en=role_type) ) for i in range(10): @@ -145,7 +145,7 @@ class DatabasePopulation: person_role_count = 0 while person_role_count < connections_to_create: try: - PersonRole.objects.create( + Role.objects.create( person=self.get_random_element_from_list(self.persons), role=self.get_random_element_from_list(self.role_types), unit=self.get_random_element_from_list(self.units), diff --git a/greg/tests/test_expire_role.py b/greg/tests/test_expire_role.py index d116eb92c8342fc4019872cca27dad4e00254116..b1a45bd4f62b7409347ccbfecce7270681d2fd26 100644 --- a/greg/tests/test_expire_role.py +++ b/greg/tests/test_expire_role.py @@ -6,10 +6,10 @@ from django.utils import timezone from greg.models import ( ScheduleTask, - Role, + RoleType, Person, OrganizationalUnit, - PersonRole, + Role, Notification, Sponsor, ) @@ -24,12 +24,12 @@ def role_task(): @pytest.fixture -def role_bar() -> Role: - return Role.objects.create(type="role_bar", name_en="Role Bar") +def role_type_bar() -> RoleType: + return RoleType.objects.create(identifier="role_bar", name_en="Role Bar") @pytest.fixture -def person(role_bar: Role) -> Person: +def person() -> Person: return Person.objects.create( first_name="Test", last_name="Tester", @@ -50,15 +50,15 @@ def sponsor() -> Sponsor: @pytest.fixture -def person_role( +def role( person: Person, - role_bar: Role, + role_type_bar: RoleType, organizational_unit: OrganizationalUnit, sponsor: Sponsor, -) -> PersonRole: - return PersonRole.objects.create( +) -> Role: + return Role.objects.create( person=person, - role=role_bar, + type=role_type_bar, unit=organizational_unit, start_date="2020-03-05", end_date=datetime.today() + timedelta(days=30), @@ -69,12 +69,12 @@ def person_role( @pytest.mark.django_db -def test_role_picked_up(role_task: ScheduleTask, person_role: PersonRole): +def test_role_picked_up(role_task: ScheduleTask, role: Role): role_notification = ExpiringRolesNotification() assert len(Notification.objects.filter(~Q(operation="add"))) == 0 role_notification.run() notification = Notification.objects.get(operation="expire_reminder") - assert notification.identifier == person_role.id + assert notification.identifier == role.id role_notification.run() notifications = Notification.objects.filter(operation="expire_reminder") assert len(notifications) == 1 @@ -82,10 +82,10 @@ def test_role_picked_up(role_task: ScheduleTask, person_role: PersonRole): @pytest.mark.django_db def test_no_notification_for_role_not_about_to_expire( - role_task: ScheduleTask, person_role: PersonRole + role_task: ScheduleTask, role: Role ): - person_role.end_date = datetime.today() + timedelta(days=31) - person_role.save() + role.end_date = datetime.today() + timedelta(days=31) + role.save() role_notification = ExpiringRolesNotification() assert len(Notification.objects.filter(operation="expire_reminder")) == 0 # Role should not be picked up since it expires in 31 days diff --git a/greg/tests/test_notifications.py b/greg/tests/test_notifications.py index 584858f9337cbf6b6054c9ddce946ddb57095232..0576827cd1d6260ee844e76c9fc98cfa260206d0 100644 --- a/greg/tests/test_notifications.py +++ b/greg/tests/test_notifications.py @@ -5,6 +5,7 @@ from greg.models import ( Notification, Consent, Role, + RoleType, OrganizationalUnit, Sponsor, PersonConsent, @@ -24,8 +25,8 @@ def person() -> Person: @pytest.fixture -def role_foo() -> Role: - return Role.objects.create(type="role_foo", name_en="Role Foo") +def role_type_foo() -> RoleType: + return RoleType.objects.create(identifier="role_foo", name_en="Role Foo") @pytest.fixture @@ -91,74 +92,78 @@ def test_person_delete_notification(person: Person): @pytest.mark.django_db def test_role_add_notification( - person: Person, role_foo: Role, org_unit_bar: OrganizationalUnit, sponsor: Sponsor + person: Person, + role_type_foo: RoleType, + org_unit_bar: OrganizationalUnit, + sponsor: Sponsor, ): - person.roles.add( # type: ignore - role_foo, - through_defaults={ - "start_date": "2021-05-06", - "end_date": "2021-10-20", - "unit": org_unit_bar, - "registered_by": sponsor, - }, + Role.objects.create( + person=person, + type=role_type_foo, + start_date="2021-05-06", + end_date="2021-10-20", + unit=org_unit_bar, + registered_by=sponsor, ) - notifications = Notification.objects.filter(object_type="PersonRole") + notifications = Notification.objects.filter(object_type="Role") assert len(notifications) == 1 assert notifications[0].operation == "add" meta_data = notifications[0].meta assert meta_data["person_id"] == person.id - assert meta_data["role_id"] == role_foo.id + assert meta_data["type_id"] == role_type_foo.id @pytest.mark.django_db def test_role_update_notification( - person: Person, role_foo: Role, org_unit_bar: OrganizationalUnit, sponsor: Sponsor + person: Person, + role_type_foo: RoleType, + org_unit_bar: OrganizationalUnit, + sponsor: Sponsor, ): - person.roles.add( # type: ignore - role_foo, - through_defaults={ - "start_date": "2021-05-06", - "end_date": "2021-10-20", - "unit": org_unit_bar, - "registered_by": sponsor, - }, + Role.objects.create( + person=person, + type=role_type_foo, + start_date="2021-05-06", + end_date="2021-10-20", + unit=org_unit_bar, + registered_by=sponsor, ) - - assert len(person.person_roles.all()) == 1 - person_role = person.person_roles.all()[0] + assert len(person.roles.all()) == 1 + person_role = person.roles.all()[0] person_role.end_date = "2021-10-21" person_role.save() - notifications = Notification.objects.filter(object_type="PersonRole") + notifications = Notification.objects.filter(object_type="Role") assert len(notifications) == 2 assert notifications[1].operation == "update" meta_data = notifications[1].meta assert meta_data["person_id"] == person.id - assert meta_data["role_id"] == role_foo.id + assert meta_data["type_id"] == role_type_foo.id @pytest.mark.django_db def test_role_delete_notification( - person: Person, role_foo: Role, org_unit_bar: OrganizationalUnit, sponsor: Sponsor + person: Person, + role_type_foo: RoleType, + org_unit_bar: OrganizationalUnit, + sponsor: Sponsor, ): - person.roles.add( # type: ignore - role_foo, - through_defaults={ - "start_date": "2021-05-06", - "end_date": "2021-10-20", - "unit": org_unit_bar, - "registered_by": sponsor, - }, + Role.objects.create( + person=person, + type=role_type_foo, + start_date="2021-05-06", + end_date="2021-10-20", + unit=org_unit_bar, + registered_by=sponsor, ) - - assert len(person.person_roles.all()) == 1 - person_role = person.person_roles.all()[0] + assert len(person.roles.all()) == 1 + person_role = person.roles.all()[0] person_role.delete() - notifications = Notification.objects.filter(object_type="PersonRole") + notifications = Notification.objects.filter(object_type="Role") assert len(notifications) == 2 assert notifications[1].operation == "delete" meta_data = notifications[1].meta assert meta_data["person_id"] == person.id - assert meta_data["role_id"] == role_foo.id + assert meta_data["type_id"] == role_type_foo.id @pytest.mark.django_db