import json from django.utils import timezone from rest_framework.test import APITestCase from vbv_lernwelt.assignment.models import ( Assignment, AssignmentCompletion, AssignmentCompletionAuditLog, ) from vbv_lernwelt.core.create_default_users import create_default_users from vbv_lernwelt.core.models import User from vbv_lernwelt.core.utils import find_first from vbv_lernwelt.course.consts import COURSE_TEST_ID from vbv_lernwelt.course.creators.test_course import create_test_course from vbv_lernwelt.course.models import CourseSession, CourseSessionUser class AssignmentApiTestCase(APITestCase): def setUp(self) -> None: create_default_users() create_test_course(include_vv=False) self.assignment = Assignment.objects.first() self.assignment_subtasks = self.assignment.filter_user_subtasks() self.cs = CourseSession.objects.create( course_id=COURSE_TEST_ID, title="Test Lehrgang Session", ) self.student = User.objects.get(username="student") self.student_csu = CourseSessionUser.objects.create( course_session=self.cs, user=self.student, ) self.expert = User.objects.get(username="admin") self.expert_csu = CourseSessionUser.objects.create( course_session=self.cs, user=self.expert, role="EXPERT" ) def test_student_can_upsertAssignmentCompletion(self): self.client.login(username="student", password="test") url = f"/api/assignment/upsert/" user_text_input = find_first( self.assignment_subtasks, pred=lambda x: x["type"] == "user_text_input" ) response = self.client.post( url, { "assignment_id": self.assignment.id, "course_session_id": self.cs.id, "completion_status": "IN_PROGRESS", "completion_data": { user_text_input["id"]: {"user_data": {"text": "Hallo via API"}}, }, }, format="json", ) response_json = response.json() print(json.dumps(response.json(), indent=2)) self.assertEqual(response.status_code, 200) self.assertEqual(response_json["assignment_user"], self.student.id) self.assertEqual(response_json["assignment"], self.assignment.id) self.assertEqual(response_json["completion_status"], "IN_PROGRESS") self.assertDictEqual( response_json["completion_data"], { user_text_input["id"]: {"user_data": {"text": "Hallo via API"}}, }, ) db_entry = AssignmentCompletion.objects.get( assignment_user=self.student, course_session_id=self.cs.id, assignment_id=self.assignment.id, ) self.assertEqual(db_entry.completion_status, "IN_PROGRESS") self.assertDictEqual( db_entry.completion_data, { user_text_input["id"]: {"user_data": {"text": "Hallo via API"}}, }, ) # read data via request api response = self.client.get( f"/api/assignment/{self.assignment.id}/{self.cs.id}/", format="json", ) response_json = response.json() print(json.dumps(response.json(), indent=2)) self.assertDictEqual( response_json["completion_data"], { user_text_input["id"]: {"user_data": {"text": "Hallo via API"}}, }, ) # submit the assignment response = self.client.post( url, { "assignment_id": self.assignment.id, "course_session_id": self.cs.id, "completion_status": "SUBMITTED", "completion_data": { user_text_input["id"]: {"user_data": {"text": "Hallo via API 2"}}, }, }, format="json", ) response_json = response.json() print(json.dumps(response.json(), indent=2)) self.assertEqual(response.status_code, 200) self.assertEqual(response_json["assignment_user"], self.student.id) self.assertEqual(response_json["assignment"], self.assignment.id) self.assertEqual(response_json["completion_status"], "SUBMITTED") self.assertDictEqual( response_json["completion_data"], { user_text_input["id"]: {"user_data": {"text": "Hallo via API 2"}}, }, ) # second submit will fail response = self.client.post( url, { "assignment_id": self.assignment.id, "course_session_id": self.cs.id, "completion_status": "SUBMITTED", "completion_data": { user_text_input["id"]: {"user_data": {"text": "Hallo via API 2"}}, }, }, format="json", ) response_json = response.json() print(json.dumps(response.json(), indent=2)) self.assertEqual(response.status_code, 404) self.assertTrue("Cannot update completion status" in str(response_json)) def test_expert_can_gradeAssignmentCompletion(self): # setup AssignmentCompletion subtasks = self.assignment.filter_user_subtasks( subtask_types=["user_text_input"] ) user_text_input = find_first( subtasks, pred=lambda x: (value := x.get("value")) and value.get("text", "").startswith( "Gibt es zusätzliche Deckungen, die du der Person empfehlen würdest?" ), ) ac = AssignmentCompletion.objects.create( assignment_user=self.student, assignment=self.assignment, course_session=self.cs, completion_status="SUBMITTED", submitted_at=timezone.now(), completion_data={ user_text_input["id"]: { "user_data": {"text": "Ich würde nichts weiteres empfehlen."} }, }, ) # make api call self.client.login(username="admin", password="test") url = f"/api/assignment/evaluate/" response = self.client.post( url, { "assignment_id": self.assignment.id, "assignment_user_id": self.student.id, "course_session_id": self.cs.id, "completion_status": "EVALUATION_IN_PROGRESS", "completion_data": { user_text_input["id"]: { "expert_data": {"points": 1, "comment": "Gut gemacht!"} }, }, }, format="json", ) response_json = response.json() print(json.dumps(response.json(), indent=2)) self.assertEqual(response.status_code, 200) self.assertEqual(response_json["assignment_user"], self.student.id) self.assertEqual(response_json["assignment"], self.assignment.id) self.assertEqual(response_json["completion_status"], "EVALUATION_IN_PROGRESS") self.assertDictEqual( response_json["completion_data"], { user_text_input["id"]: { "user_data": {"text": "Ich würde nichts weiteres empfehlen."}, "expert_data": {"points": 1, "comment": "Gut gemacht!"}, }, }, ) db_entry = AssignmentCompletion.objects.get( assignment_user=self.student, course_session_id=self.cs.id, assignment_id=self.assignment.id, ) self.assertEqual(db_entry.completion_status, "EVALUATION_IN_PROGRESS") self.assertDictEqual( db_entry.completion_data, { user_text_input["id"]: { "user_data": {"text": "Ich würde nichts weiteres empfehlen."}, "expert_data": {"points": 1, "comment": "Gut gemacht!"}, }, }, ) # finish grading response = self.client.post( url, { "assignment_id": self.assignment.id, "assignment_user_id": self.student.id, "course_session_id": self.cs.id, "completion_status": "EVALUATION_SUBMITTED", "completion_data": { user_text_input["id"]: { "expert_data": {"points": 1, "comment": "Gut gemacht!"} }, }, "evaluation_grade": 4.5, "evaluation_points": 16, }, format="json", ) response_json = response.json() print(json.dumps(response.json(), indent=2)) self.assertEqual(response.status_code, 200) self.assertEqual(response_json["assignment_user"], self.student.id) self.assertEqual(response_json["assignment"], self.assignment.id) self.assertEqual(response_json["completion_status"], "EVALUATION_SUBMITTED") self.assertDictEqual( response_json["completion_data"], { user_text_input["id"]: { "user_data": {"text": "Ich würde nichts weiteres empfehlen."}, "expert_data": {"points": 1, "comment": "Gut gemacht!"}, }, }, ) db_entry = AssignmentCompletion.objects.get( assignment_user=self.student, course_session_id=self.cs.id, assignment_id=self.assignment.id, ) self.assertEqual(db_entry.completion_status, "EVALUATION_SUBMITTED") self.assertDictEqual( db_entry.completion_data, { user_text_input["id"]: { "user_data": {"text": "Ich würde nichts weiteres empfehlen."}, "expert_data": {"points": 1, "comment": "Gut gemacht!"}, }, }, ) # `EVALUATION_SUBMITTED` will create a new AssignmentCompletionAuditLog acl = AssignmentCompletionAuditLog.objects.get( assignment_user=self.student, course_session_id=self.cs.id, assignment_id=self.assignment.id, completion_status="EVALUATION_SUBMITTED", ) self.maxDiff = None self.assertDictEqual( acl.completion_data, { user_text_input["id"]: { "id": user_text_input["id"], "type": "user_text_input", "value": { "text": "Gibt es zusätzliche Deckungen, die du der Person empfehlen würdest? Begründe deine Empfehlung", }, "user_data": {"text": "Ich würde nichts weiteres empfehlen."}, "expert_data": {"points": 1, "comment": "Gut gemacht!"}, }, }, )