Repository: ephios-dev/ephios

Issue:
Tests for consequences



Discussion:

Resolving patch:
diff --git a/ephios/user_management/consequences.py b/ephios/user_management/consequences.py
--- a/ephios/user_management/consequences.py
+++ b/ephios/user_management/consequences.py
@@ -151,23 +151,23 @@ def create(
             data=dict(
                 qualification_id=qualification.id,
                 event_id=None if shift is None else shift.event_id,
-                expires=None if expires is None else expires.isoformat(),
+                expires=expires,
             ),
         )
 
     @classmethod
     def execute(cls, consequence):
-        expires_str = consequence.data["expires"]
-        expires = None if not expires_str else datetime.fromisoformat(expires_str)
         qg, created = QualificationGrant.objects.get_or_create(
             defaults=dict(
-                expires=expires,
+                expires=consequence.data["expires"],
             ),
             user=consequence.user,
             qualification_id=consequence.data["qualification_id"],
         )
         if not created:
-            qg.expires = max(qg.expires, expires, key=lambda dt: dt or datetime.max)
+            qg.expires = max(
+                qg.expires, consequence.data["expires"], key=lambda dt: dt or datetime.max
+            )
             qg.save()
 
     @classmethod
@@ -188,8 +188,8 @@ def render(cls, consequence):
                 id=consequence.data["qualification_id"]
             ).title
 
-        if expires_str := consequence.data.get("expires"):
-            expires_str = date_format(datetime.fromisoformat(expires_str))
+        if expires := consequence.data.get("expires"):
+            expires = date_format(expires)
 
         user = consequence.user.get_full_name()
 
@@ -205,8 +205,8 @@ def render(cls, consequence):
                 qualification=qualification_title,
             )
 
-        if expires_str:
-            s += " " + _("(valid until {expires_str})").format(expires_str=expires_str)
+        if expires:
+            s += " " + _("(valid until {expires_str})").format(expires_str=expires)
         return s
 
     @classmethod


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -319,7 +319,7 @@ def qualifications_consequence(volunteer, qualifications, event, tz):
         user=volunteer,
         shift=event.shifts.first(),
         qualification=qualifications.nfs,
-        expires=datetime(2064, 4, 1).astimezone(tz),
+        expires=datetime(2065, 4, 1).astimezone(tz),
     )
 
 
diff --git a/tests/user_management/test_consequences.py b/tests/user_management/test_consequences.py
--- a/tests/user_management/test_consequences.py
+++ b/tests/user_management/test_consequences.py
@@ -45,6 +45,18 @@ def test_confirm_qualification_granting(
         qualifications_consequence.confirm(superuser)
         assert qualifications.nfs in qualifications_consequence.user.qualifications
 
+    def test_extend_qualification(
+        self, django_app, qualified_volunteer, qualifications_consequence, qualifications
+    ):
+        with pytest.raises(Qualification.DoesNotExist):
+            qualified_volunteer.qualifications.get(
+                pk=qualifications.nfs.pk, expires=qualifications_consequence.data.get("expires")
+            )
+        qualifications_consequence.confirm(qualified_volunteer)
+        assert qualified_volunteer.qualifications.get(
+            pk=qualifications.nfs.pk, expires=qualifications_consequence.data.get("expires")
+        )
+
 
 @pytest.mark.django_db
 class TestWorkingHourConsequence:
@@ -58,10 +70,36 @@ def test_request_workinghour(self, django_app, volunteer):
             user=volunteer, data__date=datetime.now().date(), data__hours=42, data__reason="testing"
         )
 
-    def test_render_qualification_granting(self, qualifications_consequence):
-        assert qualifications_consequence.render()
+    def test_render_workinghour_consequence(self, workinghours_consequence):
+        assert workinghours_consequence.render()
 
     def test_confirm_workinghours(self, volunteer, superuser, workinghours_consequence):
         assert volunteer.get_workhour_items()[0] == 0
         workinghours_consequence.confirm(superuser)
         assert volunteer.get_workhour_items()[0] == workinghours_consequence.data.get("hours")
+
+
+@pytest.mark.django_db
+def test_post_consequence_confirm(csrf_exempt_django_app, superuser, qualifications_consequence):
+    assert qualifications_consequence.state == Consequence.States.NEEDS_CONFIRMATION
+    POST_DATA = {"action": "confirm"}
+    csrf_exempt_django_app.post(
+        reverse("user_management:consequence_edit", kwargs=dict(pk=qualifications_consequence.pk)),
+        user=superuser,
+        params=POST_DATA,
+    )
+    qualifications_consequence.refresh_from_db()
+    assert qualifications_consequence.state == Consequence.States.EXECUTED
+
+
+@pytest.mark.django_db
+def test_post_consequence_deny(csrf_exempt_django_app, superuser, qualifications_consequence):
+    assert qualifications_consequence.state == Consequence.States.NEEDS_CONFIRMATION
+    POST_DATA = {"action": "deny"}
+    csrf_exempt_django_app.post(
+        reverse("user_management:consequence_edit", kwargs=dict(pk=qualifications_consequence.pk)),
+        user=superuser,
+        params=POST_DATA,
+    )
+    qualifications_consequence.refresh_from_db()
+    assert qualifications_consequence.state == Consequence.States.DENIED