vbv/server/vbv_lernwelt/assignment/tests/test_graphql.py

451 lines
16 KiB
Python

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"}
},
},
)