Add EvaluationSummary

This commit is contained in:
Daniel Egger 2023-05-05 12:19:31 +02:00
parent d9a6f2dd94
commit 2d6cee9f9f
12 changed files with 262 additions and 46 deletions

View File

@ -4,14 +4,9 @@ import EvaluationContainer from "@/pages/cockpit/assignmentEvaluationPage/Evalua
import AssignmentSubmissionResponses from "@/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionResponses.vue"; import AssignmentSubmissionResponses from "@/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionResponses.vue";
import { useAssignmentStore } from "@/stores/assignmentStore"; import { useAssignmentStore } from "@/stores/assignmentStore";
import { useCourseSessionsStore } from "@/stores/courseSessions"; import { useCourseSessionsStore } from "@/stores/courseSessions";
import { import { Assignment, CourseSessionAssignmentDetails, CourseSessionUser } from "@/types";
Assignment,
AssignmentCompletion,
CourseSessionAssignmentDetails,
CourseSessionUser,
} from "@/types";
import log from "loglevel"; import log from "loglevel";
import { onMounted, reactive } from "vue"; import { computed, onMounted, reactive } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
const props = defineProps<{ const props = defineProps<{
@ -25,14 +20,12 @@ log.debug("AssignmentEvaluationPage created", props.assignmentId, props.userId);
export interface StateInterface { export interface StateInterface {
assignment: Assignment | undefined; assignment: Assignment | undefined;
courseSessionAssignmentDetails: CourseSessionAssignmentDetails | undefined; courseSessionAssignmentDetails: CourseSessionAssignmentDetails | undefined;
completionData: AssignmentCompletion | undefined;
assignmentUser: CourseSessionUser | undefined; assignmentUser: CourseSessionUser | undefined;
} }
const state: StateInterface = reactive({ const state: StateInterface = reactive({
assignment: undefined, assignment: undefined,
courseSessionAssignmentDetails: undefined, courseSessionAssignmentDetails: undefined,
completionData: undefined,
assignmentUser: undefined, assignmentUser: undefined,
}); });
@ -51,7 +44,7 @@ onMounted(async () => {
try { try {
state.assignment = await assignmentStore.loadAssignment(props.assignmentId); state.assignment = await assignmentStore.loadAssignment(props.assignmentId);
state.completionData = await assignmentStore.loadAssignmentCompletion( await assignmentStore.loadAssignmentCompletion(
props.assignmentId, props.assignmentId,
courseSessionStore.currentCourseSession.id, courseSessionStore.currentCourseSession.id,
props.userId props.userId
@ -66,11 +59,13 @@ function exit() {
path: `/course/${props.courseSlug}/cockpit/assignment`, path: `/course/${props.courseSlug}/cockpit/assignment`,
}); });
} }
const assignmentCompletion = computed(() => assignmentStore.assignmentCompletion);
</script> </script>
<template> <template>
<div class="absolute bottom-0 top-0 z-10 w-full bg-white"> <div class="absolute bottom-0 top-0 z-10 w-full bg-white">
<div v-if="state.assignment && state.completionData" class="relative"> <div v-if="state.assignment && assignmentCompletion" class="relative">
<header <header
class="relative flex h-12 w-full items-center justify-between border-b border-b-gray-400 bg-white px-4 lg:h-16 lg:px-8" class="relative flex h-12 w-full items-center justify-between border-b border-b-gray-400 bg-white px-4 lg:h-16 lg:px-8"
> >
@ -102,14 +97,14 @@ function exit() {
</div> </div>
<AssignmentSubmissionResponses <AssignmentSubmissionResponses
:assignment="state.assignment" :assignment="state.assignment"
:assignment-completion-data="state.completionData?.completion_data" :assignment-completion-data="assignmentCompletion.completion_data"
:allow-edit="false" :allow-edit="false"
></AssignmentSubmissionResponses> ></AssignmentSubmissionResponses>
</div> </div>
</div> </div>
<div class="w-1/2 overflow-y-auto bg-gray-200"> <div class="w-1/2 overflow-y-auto bg-gray-200">
<EvaluationContainer <EvaluationContainer
:assignment-completion="state.completionData" :assignment-completion="assignmentCompletion"
:assignment-user="state.assignmentUser" :assignment-user="state.assignmentUser"
:assignment="state.assignment" :assignment="state.assignment"
></EvaluationContainer> ></EvaluationContainer>

View File

@ -1,12 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import EvaluationIntro from "@/pages/cockpit/assignmentEvaluationPage/EvaluationIntro.vue"; import EvaluationIntro from "@/pages/cockpit/assignmentEvaluationPage/EvaluationIntro.vue";
import EvaluationSummary from "@/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue";
import EvaluationTask from "@/pages/cockpit/assignmentEvaluationPage/EvaluationTask.vue"; import EvaluationTask from "@/pages/cockpit/assignmentEvaluationPage/EvaluationTask.vue";
import { calcAssignmentLearningContents } from "@/services/assignmentService"; import { calcAssignmentLearningContents } from "@/services/assignmentService";
import { useCourseSessionsStore } from "@/stores/courseSessions"; import { useCourseSessionsStore } from "@/stores/courseSessions";
import { useLearningPathStore } from "@/stores/learningPath"; import { useLearningPathStore } from "@/stores/learningPath";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import type { Assignment, AssignmentCompletion, CourseSessionUser } from "@/types"; import type {
Assignment,
AssignmentCompletion,
AssignmentEvaluationTask,
CourseSessionUser,
} from "@/types";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { findIndex } from "lodash";
import * as log from "loglevel"; import * as log from "loglevel";
import { computed, reactive } from "vue"; import { computed, reactive } from "vue";
@ -24,7 +31,7 @@ interface StateInterface {
} }
const state: StateInterface = reactive({ const state: StateInterface = reactive({
pageIndex: 0, pageIndex: 6,
}); });
const courseSessionStore = useCourseSessionsStore(); const courseSessionStore = useCourseSessionsStore();
@ -41,6 +48,15 @@ function nextPage() {
state.pageIndex = Math.min(numTasks.value + 1, state.pageIndex + 1); state.pageIndex = Math.min(numTasks.value + 1, state.pageIndex + 1);
} }
function editTask(task: AssignmentEvaluationTask) {
log.debug("editTask", task);
const taskIndex =
findIndex(props.assignment.evaluation_tasks, {
id: task.id,
}) ?? 0;
state.pageIndex = taskIndex + 1;
}
function findAssignmentDetail() { function findAssignmentDetail() {
const learningPathStore = useLearningPathStore(); const learningPathStore = useLearningPathStore();
const userStore = useUserStore(); const userStore = useUserStore();
@ -88,10 +104,18 @@ const dueDate = computed(() =>
:assignment="props.assignment" :assignment="props.assignment"
:task-index="state.pageIndex - 1" :task-index="state.pageIndex - 1"
/> />
<EvaluationSummary
v-else
:assignment-user="props.assignmentUser"
:assignment="props.assignment"
:assignment-completion="props.assignmentCompletion"
:due-date="dueDate"
@edit-task="editTask($event)"
></EvaluationSummary>
</section> </section>
</div> </div>
<nav class="sticky bottom-0 border-t p-6"> <nav class="sticky bottom-0 border-t bg-gray-200 p-6" v-if="state.pageIndex > 0">
<div class="relative flex flex-row place-content-end"> <div class="relative flex flex-row place-content-end">
<button <button
v-if="true" v-if="true"

View File

@ -51,9 +51,8 @@ async function startEvaluation() {
</p> </p>
<p class="my-4"> <p class="my-4">
Auf Grund dieser Bewertung wird eine Gesamtpunktzahl und die daraus reslutierende Die Gesamtpunktzahl und die daruas resultierende Note wird auf Grund des
Note berechnet. Genauere Informationen dazu findest du im folgenden hinterlegeten Beurteilungsinstrument berechnet. Willst du mehr dazu erfahren:
Beurteilungsinstrument:
</p> </p>
<div> <div>

View File

@ -0,0 +1,131 @@
<script setup lang="ts">
import {
maxAssignmentPoints,
pointsToGrade,
userAssignmentPoints,
} from "@/services/assignmentService";
import { useAssignmentStore } from "@/stores/assignmentStore";
import { useCourseSessionsStore } from "@/stores/courseSessions";
import type { Assignment, AssignmentEvaluationTask, CourseSessionUser } from "@/types";
import { AssignmentCompletion } from "@/types";
import { Dayjs } from "dayjs";
import * as log from "loglevel";
import { computed } from "vue";
const props = defineProps<{
assignmentUser: CourseSessionUser;
assignment: Assignment;
assignmentCompletion: AssignmentCompletion;
dueDate?: Dayjs;
}>();
const emit = defineEmits(["submitEvaluation", "editTask"]);
log.debug("EvaluationSummary setup");
const courseSessionStore = useCourseSessionsStore();
const assignmentStore = useAssignmentStore();
async function submitEvaluation() {
log.debug("submitEvaluation");
await assignmentStore.evaluateAssignmentCompletion({
assignment_user_id: Number(props.assignmentUser.user_id),
assignment_id: props.assignment.id,
course_session_id: courseSessionStore.currentCourseSession!.id,
completion_data: {},
completion_status: "evaluation_submitted",
});
emit("submitEvaluation");
}
function subTaskByPoints(task: AssignmentEvaluationTask, points = 0) {
return task.value.sub_tasks.find((subTask) => subTask.points === points);
}
function evaluationForTask(task: AssignmentEvaluationTask) {
const expertData = props.assignmentCompletion.completion_data[task.id]?.expert_data;
if (task.id === "0e701176-a817-427b-b8ea-a7cd59f212cb") {
console.log("######################## ", expertData.text, expertData.points);
}
if (!expertData) {
return {
points: 0,
text: "",
};
}
return expertData;
}
const maxPoints = computed(() => maxAssignmentPoints(props.assignment));
const userPoints = computed(() =>
userAssignmentPoints(props.assignment, props.assignmentCompletion)
);
const grade = computed(() => pointsToGrade(userPoints.value, maxPoints.value));
</script>
<template>
<div>
<h3>Bewertung Freigabe</h3>
<section class="mb-6 border p-6">
<div class="text-lg font-bold">Note: {{ grade }}</div>
<div>Gesamtpunktezahl {{ userPoints }} / {{ maxPoints }}</div>
<p class="my-4">
Die Gesamtpunktzahl und die daraus resultierende Note wird auf Grund des
hinterlegeten Beurteilungsinstrument berechnet. Willst du mehr dazu erfahren:
</p>
<div>
<button class="btn-primary" @click="submitEvaluation()">
Bewertung freigeben
</button>
</div>
</section>
<section>
<div v-for="(task, index) in props.assignment.evaluation_tasks" :key="task.id">
<article class="border-t py-4">
<div class="flex flex-row justify-between">
<div class="mb-4">
Bewertungskriterium {{ index + 1 }}: {{ task.value.title }}
</div>
<div>
<button
class="link pl-2text-sm whitespace-nowrap"
@click="emit('editTask', task)"
>
{{ $t("assignment.edit") }}
</button>
</div>
</div>
<div class="default-wagtail-rich-text mb-2 font-bold">
{{ task.value.description }}
</div>
<section class="mb-4">
<div
v-html="subTaskByPoints(task, evaluationForTask(task).points).title"
></div>
<p
class="default-wagtail-rich-text"
v-html="subTaskByPoints(task, evaluationForTask(task).points).description"
></p>
<div class="text-sm text-gray-800">
{{ evaluationForTask(task).points }} Punkte
</div>
</section>
<div>
<span class="font-bold">Begründung:</span>
{{ evaluationForTask(task).text }}
</div>
</article>
</div>
</section>
</div>
</template>
<style lang="scss" scoped></style>

View File

@ -7,7 +7,6 @@ import { useAssignmentStore } from "@/stores/assignmentStore";
import { useCourseSessionsStore } from "@/stores/courseSessions"; import { useCourseSessionsStore } from "@/stores/courseSessions";
import type { import type {
Assignment, Assignment,
AssignmentCompletion,
AssignmentTask, AssignmentTask,
CourseSessionAssignmentDetails, CourseSessionAssignmentDetails,
LearningContent, LearningContent,
@ -24,14 +23,12 @@ const assignmentStore = useAssignmentStore();
interface State { interface State {
assignment: Assignment | undefined; assignment: Assignment | undefined;
courseSessionAssignmentDetails: CourseSessionAssignmentDetails | undefined; courseSessionAssignmentDetails: CourseSessionAssignmentDetails | undefined;
assignmentCompletion: AssignmentCompletion | undefined;
pageIndex: number; pageIndex: number;
} }
const state: State = reactive({ const state: State = reactive({
assignment: undefined, assignment: undefined,
courseSessionAssignmentDetails: undefined, courseSessionAssignmentDetails: undefined,
assignmentCompletion: undefined,
// 0 = introduction, 1 - n = tasks, n+1 = submission // 0 = introduction, 1 - n = tasks, n+1 = submission
pageIndex: 0, pageIndex: 0,
}); });
@ -51,7 +48,7 @@ onMounted(async () => {
state.courseSessionAssignmentDetails = courseSessionsStore.findAssignmentDetails( state.courseSessionAssignmentDetails = courseSessionsStore.findAssignmentDetails(
props.learningContent.id props.learningContent.id
); );
state.assignmentCompletion = await assignmentStore.loadAssignmentCompletion( await assignmentStore.loadAssignmentCompletion(
props.assignmentId, props.assignmentId,
courseSessionId.value courseSessionId.value
); );
@ -78,6 +75,7 @@ const currentTask = computed(() => {
} }
return undefined; return undefined;
}); });
const assignmentCompletion = computed(() => assignmentStore.assignmentCompletion);
const handleBack = () => { const handleBack = () => {
log.debug("handleBack"); log.debug("handleBack");
@ -115,7 +113,7 @@ const getTitle = () => {
</script> </script>
<template> <template>
<div v-if="state.assignment && state.assignmentCompletion"></div> <div v-if="state.assignment && assignmentCompletion"></div>
<LearningContentMultiLayout <LearningContentMultiLayout
:current-step="state.pageIndex" :current-step="state.pageIndex"
:subtitle="state.assignment?.title ?? ''" :subtitle="state.assignment?.title ?? ''"
@ -147,7 +145,7 @@ const getTitle = () => {
v-if="state.pageIndex + 1 === numPages && state.assignment && courseSessionId" v-if="state.pageIndex + 1 === numPages && state.assignment && courseSessionId"
:due-date="dueDate" :due-date="dueDate"
:assignment="state.assignment!" :assignment="state.assignment!"
:assignment-completion-data="state.assignmentCompletion?.completion_data ?? {}" :assignment-completion-data="assignmentCompletion?.completion_data ?? {}"
:course-session-id="courseSessionId!" :course-session-id="courseSessionId!"
@edit-task="jumpToTask($event)" @edit-task="jumpToTask($event)"
></AssignmentSubmissionView> ></AssignmentSubmissionView>

View File

@ -0,0 +1,32 @@
import { describe, it } from "vitest";
import { pointsToGrade } from "../assignmentService";
describe("assignmentService", () => {
it("pointsToGrade", () => {
expect(pointsToGrade(24, 24)).toBe(6);
expect(pointsToGrade(23, 24)).toBe(6);
expect(pointsToGrade(22, 24)).toBe(5.5);
expect(pointsToGrade(21, 24)).toBe(5.5);
expect(pointsToGrade(20, 24)).toBe(5);
expect(pointsToGrade(19, 24)).toBe(5);
expect(pointsToGrade(18, 24)).toBe(5);
expect(pointsToGrade(17, 24)).toBe(4.5);
expect(pointsToGrade(16, 24)).toBe(4.5);
expect(pointsToGrade(15, 24)).toBe(4);
expect(pointsToGrade(14, 24)).toBe(4);
expect(pointsToGrade(13, 24)).toBe(3.5);
expect(pointsToGrade(12, 24)).toBe(3.5);
expect(pointsToGrade(11, 24)).toBe(3.5);
expect(pointsToGrade(10, 24)).toBe(3);
expect(pointsToGrade(9, 24)).toBe(3);
expect(pointsToGrade(8, 24)).toBe(2.5);
expect(pointsToGrade(7, 24)).toBe(2.5);
expect(pointsToGrade(6, 24)).toBe(2.5);
expect(pointsToGrade(5, 24)).toBe(2);
expect(pointsToGrade(4, 24)).toBe(2);
expect(pointsToGrade(3, 24)).toBe(1.5);
expect(pointsToGrade(2, 24)).toBe(1.5);
expect(pointsToGrade(1, 24)).toBe(1);
expect(pointsToGrade(0, 24)).toBe(1);
});
});

View File

@ -3,10 +3,14 @@ import { itGet } from "@/fetchHelpers";
import type { LearningPath } from "@/services/learningPath"; import type { LearningPath } from "@/services/learningPath";
import { useCockpitStore } from "@/stores/cockpit"; import { useCockpitStore } from "@/stores/cockpit";
import type { import type {
Assignment,
AssignmentCompletion,
AssignmentCompletionStatus, AssignmentCompletionStatus,
CourseSessionUser, CourseSessionUser,
LearningContent, LearningContent,
} from "@/types"; } from "@/types";
import { sum } from "d3";
import pick from "lodash/pick";
export interface AssignmentLearningContent extends LearningContent { export interface AssignmentLearningContent extends LearningContent {
assignmentId: number; assignmentId: number;
@ -59,10 +63,42 @@ export function calcUserAssignmentCompletionStatus(
userStatus = userAssignmentStatus.completion_status; userStatus = userAssignmentStatus.completion_status;
} }
let progressStatus: StatusCountKey = "unknown"; let progressStatus: StatusCountKey = "unknown";
if (["submitted", "evaluation_in_progress", "evaluated"].includes(userStatus)) { if (
["submitted", "evaluation_in_progress", "evaluation_submitted"].includes(
userStatus
)
) {
progressStatus = "success"; progressStatus = "success";
} }
return { userId: u.user_id, userStatus, progressStatus }; return { userId: u.user_id, userStatus, progressStatus };
}); });
} }
export function maxAssignmentPoints(assignment: Assignment) {
return sum(assignment.evaluation_tasks.map((task) => task.value.max_points));
}
export function userAssignmentPoints(
assignment: Assignment,
assignmentCompletion: AssignmentCompletion
) {
const evaluationTaskIds = assignment.evaluation_tasks.map((task) => {
return task.id;
});
return sum(
Object.entries(pick(assignmentCompletion.completion_data, evaluationTaskIds)).map(
(entry) => {
return entry[1]?.expert_data?.points ?? 0;
}
)
);
}
export function pointsToGrade(points: number, maxPoints: number) {
// round to half-grades
const grade = Math.round((points / maxPoints) * 10);
const halfGrade = grade / 2;
return Math.min(halfGrade, 5) + 1;
}

View File

@ -509,7 +509,7 @@ export type AssignmentCompletionStatus =
| "in_progress" | "in_progress"
| "submitted" | "submitted"
| "evaluation_in_progress" | "evaluation_in_progress"
| "evaluated"; | "evaluation_submitted";
export interface UserDataText { export interface UserDataText {
text: string; text: string;

View File

@ -8,7 +8,6 @@ from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
@ -261,7 +260,7 @@ class Migration(migrations.Migration):
(1, "in_progress"), (1, "in_progress"),
(2, "submitted"), (2, "submitted"),
(3, "evaluation_in_progress"), (3, "evaluation_in_progress"),
(4, "evaluated"), (4, "evaluation_submitted"),
], ],
default="in_progress", default="in_progress",
max_length=255, max_length=255,
@ -337,7 +336,7 @@ class Migration(migrations.Migration):
(1, "in_progress"), (1, "in_progress"),
(2, "submitted"), (2, "submitted"),
(3, "evaluation_in_progress"), (3, "evaluation_in_progress"),
(4, "evaluated"), (4, "evaluation_submitted"),
], ],
default="in_progress", default="in_progress",
max_length=255, max_length=255,

View File

@ -220,7 +220,7 @@ class Assignment(CourseBasePage):
AssignmentCompletionStatus = Enum( AssignmentCompletionStatus = Enum(
"AssignmentCompletionStatus", "AssignmentCompletionStatus",
["in_progress", "submitted", "evaluation_in_progress", "evaluated"], ["in_progress", "submitted", "evaluation_in_progress", "evaluation_submitted"],
) )
@ -262,7 +262,7 @@ class AssignmentCompletion(models.Model):
class AssignmentCompletionAuditLog(models.Model): class AssignmentCompletionAuditLog(models.Model):
""" """
This model is used to store the "submitted" and "evaluated" data separately This model is used to store the "submitted" and "evaluation_submitted" data separately
""" """
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)

View File

@ -40,7 +40,7 @@ def update_assignment_completion(
}, },
} }
:param copy_task_data: if true, the task data will be copied to the completion data :param copy_task_data: if true, the task data will be copied to the completion data
used for "submitted" and "evaluated" status, so that we don't lose the question used for "submitted" and "evaluation_submitted" status, so that we don't lose the question
context context
:return: AssignmentCompletion :return: AssignmentCompletion
""" """
@ -59,31 +59,33 @@ def update_assignment_completion(
if ac.completion_status in [ if ac.completion_status in [
"submitted", "submitted",
"evaluation_in_progress", "evaluation_in_progress",
"evaluated", "evaluation_submitted",
]: ]:
raise serializers.ValidationError( raise serializers.ValidationError(
{ {
"completion_status": f"Cannot update completion status from {ac.completion_status} to submitted" "completion_status": f"Cannot update completion status from {ac.completion_status} to submitted"
} }
) )
elif completion_status == "evaluated": elif completion_status == "evaluation_submitted":
if ac.completion_status == "evaluated": if ac.completion_status == "evaluation_submitted":
raise serializers.ValidationError( raise serializers.ValidationError(
{ {
"completion_status": f"Cannot update completion status from {ac.completion_status} to evaluated" "completion_status": f"Cannot update completion status from {ac.completion_status} to evaluation_submitted"
} }
) )
if completion_status in ["evaluated", "evaluation_in_progress"]: if completion_status in ["evaluation_submitted", "evaluation_in_progress"]:
if evaluation_user is None: if evaluation_user is None:
raise serializers.ValidationError( raise serializers.ValidationError(
{"evaluation_user": "evaluation_user is required for evaluated status"} {
"evaluation_user": "evaluation_user is required for evaluation_submitted status"
}
) )
ac.evaluation_user = evaluation_user ac.evaluation_user = evaluation_user
if completion_status == "submitted": if completion_status == "submitted":
ac.submitted_at = timezone.now() ac.submitted_at = timezone.now()
elif completion_status == "evaluated": elif completion_status == "evaluation_submitted":
ac.evaluated_at = timezone.now() ac.evaluated_at = timezone.now()
ac.completion_status = completion_status ac.completion_status = completion_status
@ -105,7 +107,7 @@ def update_assignment_completion(
ac.save() ac.save()
if completion_status in ["evaluated", "submitted"]: if completion_status in ["evaluation_submitted", "submitted"]:
acl = AssignmentCompletionAuditLog.objects.create( acl = AssignmentCompletionAuditLog.objects.create(
assignment_user=assignment_user, assignment_user=assignment_user,
assignment=assignment, assignment=assignment,

View File

@ -230,7 +230,7 @@ class AssignmentApiTestCase(APITestCase):
"assignment_id": self.assignment.id, "assignment_id": self.assignment.id,
"assignment_user_id": self.student.id, "assignment_user_id": self.student.id,
"course_session_id": self.cs.id, "course_session_id": self.cs.id,
"completion_status": "evaluated", "completion_status": "evaluation_submitted",
"completion_data": { "completion_data": {
user_text_input["id"]: { user_text_input["id"]: {
"expert_data": {"points": 1, "comment": "Gut gemacht!"} "expert_data": {"points": 1, "comment": "Gut gemacht!"}
@ -245,7 +245,7 @@ class AssignmentApiTestCase(APITestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response_json["assignment_user"], self.student.id) self.assertEqual(response_json["assignment_user"], self.student.id)
self.assertEqual(response_json["assignment"], self.assignment.id) self.assertEqual(response_json["assignment"], self.assignment.id)
self.assertEqual(response_json["completion_status"], "evaluated") self.assertEqual(response_json["completion_status"], "evaluation_submitted")
self.assertDictEqual( self.assertDictEqual(
response_json["completion_data"], response_json["completion_data"],
{ {
@ -261,7 +261,7 @@ class AssignmentApiTestCase(APITestCase):
course_session_id=self.cs.id, course_session_id=self.cs.id,
assignment_id=self.assignment.id, assignment_id=self.assignment.id,
) )
self.assertEqual(db_entry.completion_status, "evaluated") self.assertEqual(db_entry.completion_status, "evaluation_submitted")
self.assertDictEqual( self.assertDictEqual(
db_entry.completion_data, db_entry.completion_data,
{ {
@ -272,12 +272,12 @@ class AssignmentApiTestCase(APITestCase):
}, },
) )
# `evaluated` will create a new AssignmentCompletionAuditLog # `evaluation_submitted` will create a new AssignmentCompletionAuditLog
acl = AssignmentCompletionAuditLog.objects.get( acl = AssignmentCompletionAuditLog.objects.get(
assignment_user=self.student, assignment_user=self.student,
course_session_id=self.cs.id, course_session_id=self.cs.id,
assignment_id=self.assignment.id, assignment_id=self.assignment.id,
completion_status="evaluated", completion_status="evaluation_submitted",
) )
self.maxDiff = None self.maxDiff = None
self.assertDictEqual( self.assertDictEqual(