Repository: e-valuation/EvaP

Issue:
Replace `toggle_no_grades` with an idempotent alternative
Currently, there is a URL for toggling grade status of a course (`grades:toggle_no_grades`). Instead of having a toggle, we would like an idempotent operation, that is, the endpoint should be something like `grades:set_gets_grade_documents` where the desired boolean value is sent with the request. This way, two people who want to change the status don't revert each others action but instead set the same value.


Discussion:
/assign
assign pls :)

Resolving patch:
diff --git a/evap/grades/urls.py b/evap/grades/urls.py
--- a/evap/grades/urls.py
+++ b/evap/grades/urls.py
@@ -13,5 +13,5 @@
     path("grade_document/<int:grade_document_id>/edit", views.edit_grades, name="edit_grades"),
 
     path("delete_grades", views.delete_grades, name="delete_grades"),
-    path("toggle_no_grades", views.toggle_no_grades, name="toggle_no_grades"),
+    path("set_no_grades", views.set_no_grades, name="set_no_grades"),
 ]
diff --git a/evap/grades/views.py b/evap/grades/views.py
--- a/evap/grades/views.py
+++ b/evap/grades/views.py
@@ -1,6 +1,6 @@
 from django.conf import settings
 from django.contrib import messages
-from django.core.exceptions import PermissionDenied
+from django.core.exceptions import PermissionDenied, SuspiciousOperation
 from django.db.models.query import QuerySet
 from django.http import FileResponse, HttpResponse
 from django.shortcuts import get_object_or_404, redirect, render
@@ -146,12 +146,18 @@ def upload_grades(request, course_id):
 
 @require_POST
 @grade_publisher_required
-def toggle_no_grades(request):
+def set_no_grades(request):
     course = get_object_from_dict_pk_entry_or_logged_40x(Course, request.POST, "course_id")
+
+    try:
+        status = bool(int(request.POST["status"]))
+    except (KeyError, TypeError, ValueError) as e:
+        raise SuspiciousOperation from e
+
     if course.semester.grade_documents_are_deleted:
         raise PermissionDenied
 
-    course.gets_no_grade_documents = not course.gets_no_grade_documents
+    course.gets_no_grade_documents = status
     course.save()
 
     if course.gets_no_grade_documents:


Test patch:
diff --git a/evap/grades/tests.py b/evap/grades/tests.py
--- a/evap/grades/tests.py
+++ b/evap/grades/tests.py
@@ -135,7 +135,7 @@ def test_upload_final_grades(self):
         evaluation.save()
         self.helper_check_final_grade_upload(course, 0)
 
-    def test_toggle_no_grades(self):
+    def test_set_no_grades(self):
         evaluation = self.evaluation
         evaluation.manager_approve()
         evaluation.begin_evaluation()
@@ -146,8 +146,8 @@ def test_toggle_no_grades(self):
         self.assertFalse(evaluation.course.gets_no_grade_documents)
 
         self.app.post(
-            "/grades/toggle_no_grades",
-            params={"course_id": evaluation.course.id},
+            "/grades/set_no_grades",
+            params={"course_id": evaluation.course.id, "status": "1"},
             user=self.grade_publisher,
             status=200,
         )
@@ -160,8 +160,17 @@ def test_toggle_no_grades(self):
         )
 
         self.app.post(
-            "/grades/toggle_no_grades",
-            params={"course_id": evaluation.course.id},
+            "/grades/set_no_grades",
+            params={"course_id": evaluation.course.id, "status": "0"},
+            user=self.grade_publisher,
+            status=200,
+        )
+        evaluation = Evaluation.objects.get(id=evaluation.id)
+        self.assertFalse(evaluation.course.gets_no_grade_documents)
+
+        self.app.post(
+            "/grades/set_no_grades",
+            params={"course_id": evaluation.course.id, "status": "0"},
             user=self.grade_publisher,
             status=200,
         )