import json from datetime import date from django.utils import timezone from graphene_django.utils import GraphQLTestCase 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.creators.test_course import create_test_course from vbv_lernwelt.course.models import CourseSession class AttendanceCourseUserMutationTestCase(GraphQLTestCase): GRAPHQL_URL = "/server/graphql/" def setUp(self): create_default_users() create_test_course(include_vv=False, with_sessions=True) self.course_session = CourseSession.objects.get(title="Test Bern 2022 a") self.trainer = User.objects.get(username="test-trainer1@example.com") self.student = User.objects.get(username="test-student1@example.com") self.assignment = Assignment.objects.get( slug="test-lehrgang-assignment-überprüfen-einer-motorfahrzeugs-versicherungspolice" ) self.assignment_subtasks = self.assignment.filter_user_subtasks() # self.client.force_login(self.trainer) def test_student_can_upsertAssignmentCompletion(self): self.client.force_login(self.student) user_text_input = find_first( self.assignment_subtasks, pred=lambda x: x["type"] == "user_text_input" ) completion_data_string = json.dumps( { user_text_input["id"]: {"user_data": {"text": "Hallo via API"}}, } ).replace('"', '\\"') query = f""" mutation {{ upsert_assignment_completion( assignment_id: {self.assignment.id} course_session_id: {self.course_session.id} completion_status: IN_PROGRESS completion_data_string: "{completion_data_string}" ) {{ assignment_completion {{ id completion_status completion_data assignment_user {{ id }} assignment {{ id }} }} }} }} """ response = self.query(query) self.assertResponseNoErrors(response) data = json.loads(response.content)["data"]["upsert_assignment_completion"][ "assignment_completion" ] self.assertEqual(data["assignment_user"]["id"], str(self.student.id)) self.assertEqual(data["assignment"]["id"], str(self.assignment.id)) self.assertEqual(data["completion_status"], "IN_PROGRESS") self.assertDictEqual( data["completion_data"], { user_text_input["id"]: {"user_data": {"text": "Hallo via API"}}, }, ) # check DB data db_entry = AssignmentCompletion.objects.get( assignment_user=self.student, course_session_id=self.course_session.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"}}, }, ) # submit the response completion_data_string = json.dumps( { user_text_input["id"]: {"user_data": {"text": "Hallo via API 2"}}, } ).replace('"', '\\"') query = f""" mutation {{ upsert_assignment_completion( assignment_id: {self.assignment.id} course_session_id: {self.course_session.id} completion_status: SUBMITTED completion_data_string: "{completion_data_string}" ) {{ assignment_completion {{ id completion_status completion_data assignment_user {{ id }} assignment {{ id }} }} }} }} """ response = self.query(query) self.assertResponseNoErrors(response) data = json.loads(response.content)["data"]["upsert_assignment_completion"][ "assignment_completion" ] self.assertEqual(data["assignment_user"]["id"], str(self.student.id)) self.assertEqual(data["assignment"]["id"], str(self.assignment.id)) self.assertEqual(data["completion_status"], "SUBMITTED") self.assertDictEqual( data["completion_data"], { user_text_input["id"]: {"user_data": {"text": "Hallo via API 2"}}, }, ) # check DB data db_entry = AssignmentCompletion.objects.get( assignment_user=self.student, course_session_id=self.course_session.id, assignment_id=self.assignment.id, ) self.assertEqual(db_entry.completion_status, "SUBMITTED") self.assertEqual(db_entry.submitted_at.date(), date.today()) self.assertDictEqual( db_entry.completion_data, { user_text_input["id"]: {"user_data": {"text": "Hallo via API 2"}}, }, ) # second submit will fail completion_data_string = json.dumps( { user_text_input["id"]: {"user_data": {"text": "Hallo via API 3"}}, } ).replace('"', '\\"') query = f""" mutation {{ upsert_assignment_completion( assignment_id: {self.assignment.id} course_session_id: {self.course_session.id} completion_status: SUBMITTED completion_data_string: "{completion_data_string}" ) {{ assignment_completion {{ id completion_status completion_data assignment_user {{ id }} assignment {{ id }} }} }} }} """ response = self.query(query) self.assertResponseHasErrors(response) 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, learning_content_page=self.assignment.learningcontentassignment_set.first(), course_session=self.course_session, completion_status="SUBMITTED", submitted_at=timezone.now(), completion_data={ user_text_input["id"]: { "user_data": {"text": "Ich würde nichts weiteres empfehlen."} }, }, ) self.client.force_login(self.trainer) completion_data_string = json.dumps( { user_text_input["id"]: { "expert_data": {"points": 1, "comment": "Gut gemacht!"} }, } ).replace('"', '\\"') query = f""" mutation {{ upsert_assignment_completion( assignment_id: {self.assignment.id} assignment_user_id: {self.student.id} course_session_id: {self.course_session.id} completion_status: EVALUATION_IN_PROGRESS completion_data_string: "{completion_data_string}" ) {{ assignment_completion {{ id completion_status completion_data assignment_user {{ id }} assignment {{ id }} }} }} }} """ response = self.query(query) self.assertResponseNoErrors(response) data = json.loads(response.content)["data"]["upsert_assignment_completion"][ "assignment_completion" ] self.assertEqual(data["assignment_user"]["id"], str(self.student.id)) self.assertEqual(data["assignment"]["id"], str(self.assignment.id)) self.assertEqual(data["completion_status"], "EVALUATION_IN_PROGRESS") self.assertDictEqual( data["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.course_session.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 completion_data_string = json.dumps( { user_text_input["id"]: { "expert_data": {"points": 1, "comment": "Gut gemacht!"} }, } ).replace('"', '\\"') query = f""" mutation {{ upsert_assignment_completion( assignment_id: {self.assignment.id} assignment_user_id: {self.student.id} course_session_id: {self.course_session.id} completion_status: EVALUATION_SUBMITTED completion_data_string: "{completion_data_string}" evaluation_grade: 4.5, evaluation_points: 16, ) {{ assignment_completion {{ id completion_status completion_data assignment_user {{ id }} assignment {{ id }} }} }} }} """ response = self.query(query) self.assertResponseNoErrors(response) data = json.loads(response.content)["data"]["upsert_assignment_completion"][ "assignment_completion" ] self.assertEqual(data["assignment_user"]["id"], str(self.student.id)) self.assertEqual(data["assignment"]["id"], str(self.assignment.id)) self.assertEqual(data["completion_status"], "EVALUATION_SUBMITTED") self.assertDictEqual( data["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.course_session.id, assignment_id=self.assignment.id, ) self.assertEqual(db_entry.completion_status, "EVALUATION_SUBMITTED") self.assertEqual(db_entry.evaluation_grade, 4.5) self.assertEqual(db_entry.evaluation_points, 16) 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.course_session.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!"}, }, }, ) def test_student_can_upsert_reflection(self): """ when upserting a reflection, it will store also the page_id of the learning content """ reflection = Assignment.objects.get(slug="test-lehrgang-assignment-reflexion") reflection_subtasks = reflection.filter_user_subtasks() reflection_learning_content = reflection.learningcontentassignment_set.first() self.client.force_login(self.student) user_text_input = find_first( reflection_subtasks, pred=lambda x: x["type"] == "user_text_input" ) completion_data_string = json.dumps( { user_text_input["id"]: { "user_data": {"text": "Hallo via Reflection API"} }, } ).replace('"', '\\"') query = f""" mutation {{ upsert_assignment_completion( assignment_id: {reflection.id} course_session_id: {self.course_session.id} learning_content_page_id: {reflection_learning_content.id} completion_status: IN_PROGRESS completion_data_string: "{completion_data_string}" ) {{ assignment_completion {{ id completion_status completion_data assignment_user {{ id }} assignment {{ id }} learning_content_page_id }} }} }} """ response = self.query(query) self.assertResponseNoErrors(response) data = json.loads(response.content)["data"]["upsert_assignment_completion"][ "assignment_completion" ] print(data) self.assertEqual(data["assignment_user"]["id"], str(self.student.id)) self.assertEqual(data["assignment"]["id"], str(reflection.id)) self.assertEqual(data["completion_status"], "IN_PROGRESS") self.assertEqual( data["learning_content_page_id"], str(reflection_learning_content.id) ) self.assertDictEqual( data["completion_data"], { user_text_input["id"]: { "user_data": {"text": "Hallo via Reflection API"} }, }, ) # check DB data db_entry = AssignmentCompletion.objects.get( assignment_user=self.student, course_session_id=self.course_session.id, assignment_id=reflection.id, learning_content_page_id=reflection_learning_content.id, ) self.assertEqual(db_entry.completion_status, "IN_PROGRESS") self.assertDictEqual( db_entry.completion_data, { user_text_input["id"]: { "user_data": {"text": "Hallo via Reflection API"} }, }, )