fix
This commit is contained in:
@@ -21,7 +21,7 @@ from django.db.models import (
|
||||
Subquery,
|
||||
)
|
||||
from django.utils import timezone
|
||||
from account.decorators import admin_required
|
||||
from account.decorators import admin_required, super_required
|
||||
from prompt.models import Conversation, Message
|
||||
from .classifier import classify_conversation_messages
|
||||
|
||||
@@ -517,7 +517,7 @@ def get_task_stats(request, task_id: int, classname: Optional[str] = None):
|
||||
|
||||
|
||||
@router.get("/gradebook/", response=GradebookOut)
|
||||
@admin_required
|
||||
@super_required
|
||||
def get_gradebook(
|
||||
request,
|
||||
classname: str = "",
|
||||
@@ -536,7 +536,7 @@ def get_gradebook(
|
||||
|
||||
|
||||
@router.get("/gradebook/export/")
|
||||
@admin_required
|
||||
@super_required
|
||||
def export_gradebook(
|
||||
request,
|
||||
classname: str = "",
|
||||
|
||||
@@ -60,7 +60,7 @@ def _csv_number(value):
|
||||
|
||||
def _classes():
|
||||
return list(
|
||||
User.objects.filter(role=RoleChoices.NORMAL)
|
||||
User.objects.filter(role__in=(RoleChoices.NORMAL, RoleChoices.ADMIN))
|
||||
.exclude(classname="")
|
||||
.values_list("classname", flat=True)
|
||||
.distinct()
|
||||
@@ -81,7 +81,9 @@ def build_gradebook(filters: GradebookFilters):
|
||||
|
||||
classes = _classes()
|
||||
class_students = list(
|
||||
User.objects.filter(role=RoleChoices.NORMAL, classname=classname)
|
||||
User.objects.filter(
|
||||
role__in=(RoleChoices.NORMAL, RoleChoices.ADMIN), classname=classname
|
||||
)
|
||||
.order_by("username", "id")
|
||||
.only("id", "username", "classname")
|
||||
)
|
||||
|
||||
@@ -268,6 +268,7 @@ class ShowcaseManagementApiTest(TestCase):
|
||||
|
||||
class GradebookApiTest(TestCase):
|
||||
def setUp(self):
|
||||
self.super = _make_user("grade-super", role=RoleChoices.SUPER)
|
||||
self.admin = _make_user("grade-admin", role=RoleChoices.ADMIN)
|
||||
self.normal = _make_user("grade-normal", classname="blocked")
|
||||
|
||||
@@ -289,7 +290,7 @@ class GradebookApiTest(TestCase):
|
||||
return submission
|
||||
|
||||
def test_gradebook_requires_classname(self):
|
||||
self.client.force_login(self.admin)
|
||||
self.client.force_login(self.super)
|
||||
|
||||
resp = self.client.get("/api/submission/gradebook/")
|
||||
|
||||
@@ -307,6 +308,34 @@ class GradebookApiTest(TestCase):
|
||||
self.assertIn(resp.status_code, (302, 403))
|
||||
self.assertIn(export_resp.status_code, (302, 403))
|
||||
|
||||
def test_admin_user_cannot_access_gradebook(self):
|
||||
self.client.force_login(self.admin)
|
||||
|
||||
resp = self.client.get("/api/submission/gradebook/?classname=10A")
|
||||
export_resp = self.client.get(
|
||||
"/api/submission/gradebook/export/?classname=10A"
|
||||
)
|
||||
|
||||
self.assertIn(resp.status_code, (302, 403))
|
||||
self.assertIn(export_resp.status_code, (302, 403))
|
||||
|
||||
def test_admin_user_is_counted_in_class_gradebook(self):
|
||||
self._student("alice")
|
||||
admin_in_class = _make_user(
|
||||
"grade-admin-2", role=RoleChoices.ADMIN, classname="10A"
|
||||
)
|
||||
task = _make_task(title="Admin Visible", task_type="challenge", display=9)
|
||||
self._submit(admin_in_class, task, 5.0)
|
||||
self.client.force_login(self.super)
|
||||
|
||||
resp = self.client.get("/api/submission/gradebook/?classname=10A")
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
data = resp.json()
|
||||
self.assertEqual(data["student_count"], 2)
|
||||
usernames = [row["username"] for row in data["rows"]]
|
||||
self.assertIn("grade-admin-2", usernames)
|
||||
|
||||
def test_coverage_includes_tutorial_and_challenge_without_public_requirement(self):
|
||||
students = [
|
||||
self._student("alice"),
|
||||
@@ -337,7 +366,7 @@ class GradebookApiTest(TestCase):
|
||||
self._submit(students[0], challenge, 3.0)
|
||||
self._submit(students[1], challenge, 4.0)
|
||||
self._submit(students[0], low_coverage, 5.0)
|
||||
self.client.force_login(self.admin)
|
||||
self.client.force_login(self.super)
|
||||
|
||||
resp = self.client.get("/api/submission/gradebook/?classname=10A")
|
||||
|
||||
@@ -390,7 +419,7 @@ class GradebookApiTest(TestCase):
|
||||
old_best = self._submit(alice, task, 4.5, created=older)
|
||||
new_best = self._submit(alice, task, 4.5, created=newer)
|
||||
self._submit(bob, task, 3.0)
|
||||
self.client.force_login(self.admin)
|
||||
self.client.force_login(self.super)
|
||||
|
||||
resp = self.client.get("/api/submission/gradebook/?classname=10A")
|
||||
|
||||
@@ -412,7 +441,7 @@ class GradebookApiTest(TestCase):
|
||||
self._submit(bob, tutorial, 5.0)
|
||||
self._submit(alice, challenge, 5.0)
|
||||
self._submit(bob, challenge, 1.0)
|
||||
self.client.force_login(self.admin)
|
||||
self.client.force_login(self.super)
|
||||
|
||||
resp = self.client.get(
|
||||
"/api/submission/gradebook/?classname=10A&task_type=tutorial&username=alice"
|
||||
@@ -427,7 +456,7 @@ class GradebookApiTest(TestCase):
|
||||
|
||||
def test_missing_class_returns_empty_table_with_class_options(self):
|
||||
self._student("alice")
|
||||
self.client.force_login(self.admin)
|
||||
self.client.force_login(self.super)
|
||||
|
||||
resp = self.client.get("/api/submission/gradebook/?classname=missing")
|
||||
|
||||
@@ -447,7 +476,7 @@ class GradebookApiTest(TestCase):
|
||||
]
|
||||
optional = _make_task(title="Low Coverage", task_type="challenge", display=8)
|
||||
self._submit(students[0], optional, 5.0)
|
||||
self.client.force_login(self.admin)
|
||||
self.client.force_login(self.super)
|
||||
|
||||
resp = self.client.get("/api/submission/gradebook/?classname=10A")
|
||||
|
||||
@@ -481,7 +510,7 @@ class GradebookApiTest(TestCase):
|
||||
for i in range(1, 21):
|
||||
student = self._student(f"s{i:02d}", classname="10B")
|
||||
self._submit(student, task, float(21 - i))
|
||||
self.client.force_login(self.admin)
|
||||
self.client.force_login(self.super)
|
||||
|
||||
resp = self.client.get("/api/submission/gradebook/?classname=10B")
|
||||
|
||||
@@ -504,7 +533,7 @@ class GradebookApiTest(TestCase):
|
||||
self._submit(alice, tutorial, 4.0)
|
||||
self._submit(bob, tutorial, 2.0)
|
||||
self._submit(alice, challenge, 5.0)
|
||||
self.client.force_login(self.admin)
|
||||
self.client.force_login(self.super)
|
||||
|
||||
resp = self.client.get(
|
||||
"/api/submission/gradebook/export/?classname=10A&task_type=tutorial"
|
||||
|
||||
Reference in New Issue
Block a user