wip: Add evaluation tests

This commit is contained in:
Christian Cueni 2023-12-02 16:48:09 +01:00
parent 39ea4d8555
commit 0fc428ff06
8 changed files with 367 additions and 177 deletions

View File

@ -42,6 +42,7 @@ const dropdownSelected = computed<DropdownSelectable>({
border: !props.borderless,
'font-bold': !props.borderless,
}"
data-cy="dropdown-select"
>
<span v-if="dropdownSelected.iconName" class="mr-4">
<component :is="dropdownSelected.iconName"></component>
@ -75,6 +76,7 @@ const dropdownSelected = computed<DropdownSelectable>({
'relative cursor-default select-none py-2 pl-3 pr-9',
]"
class="flex flex-row items-center"
:data-cy="`dropdown-select-option-${item.name}`"
>
<span v-if="item.iconName" class="mr-4">
<component :is="item.iconName"></component>

View File

@ -30,7 +30,7 @@ const text = computed(() => {
} else {
return {
evaluationTitle: "Feedback",
evaluationInstruction: "assignment.evaluationInstrumentDescriptionTextFeedback",
evaluationInstruction: "a.assignment.evaluationInstrumentDescriptionTextFeedback",
evaluationStart: "a.Feedback geben",
evaluationContinue: "a.Feedback fortsetzen",
evaluationView: "a.Feedback ansehen",
@ -80,7 +80,7 @@ async function startEvaluation() {
<h3 data-cy="title">{{ $t(text.evaluationTitle) }}</h3>
<p v-if="props.dueDate" class="my-4">
<p v-if="props.dueDate" class="my-4" data-cy="evaluation-duedate">
{{
$t(
"assignment.Du musst die Bewertung bis am x um y Uhr abschliessen und freigeben",

View File

@ -48,7 +48,7 @@ const text = computed(() => {
evaluationDescription: "assignment.evaluationInstrumentDescriptionText",
evaluationSubmit: "a.Bewertung freigeben",
evaluationSubmission: "a.Bewertung Freigabe",
evaluationForUser: "a.Bewertung von x y",
evaluationFromUser: "a.Bewertung von x y",
evaluationSuccess: "a.Deine Bewertung für x y wurde freigegeben.",
};
} else {
@ -58,7 +58,7 @@ const text = computed(() => {
evaluationDescription: "a.assignment.evaluationFeedbackDescriptionText",
evaluationSubmit: "a.Feedback freigeben",
evaluationSubmission: "a.Feedback Freigabe",
evaluationForUser: "a.Feedback von x y",
evaluationFromUser: "a.Feedback von x y",
evaluationSuccess: "a.Dein Feedback für x y wurde freigegeben.",
};
}
@ -82,7 +82,9 @@ async function submitEvaluation() {
}
function subTaskByPoints(task: AssignmentEvaluationTask, points = 0) {
return task.value.sub_tasks.find((subTask) => subTask.value.points === points);
return task.value.sub_tasks !== undefined
? task.value.sub_tasks.find((subTask) => subTask.value.points === points)
: null;
}
function evaluationForTask(task: AssignmentEvaluationTask) {
@ -118,14 +120,13 @@ const evaluationUser = computed(() => {
<div>
<h3 v-if="evaluationUser && props.showEvaluationUser" class="mb-6">
{{
$t(text.evaluationForUser, {
x: evaluationUser.first_name,
y: evaluationUser.last_name,
$t(text.evaluationFromUser, {
x: evaluationUser?.first_name,
y: evaluationUser?.last_name,
})
}}
</h3>
<h3 v-else class="mb-6" data-cy="sub-title">{{ $t(text.evaluationSubmission) }}</h3>
<section class="mb-6 border p-6" data-cy="result-section">
<section
v-if="props.assignment.assignment_type === 'CASEWORK'"
@ -197,8 +198,8 @@ const evaluationUser = computed(() => {
<ItSuccessAlert
:text="
$t(text.evaluationSuccess, {
x: evaluationUser?.first_name,
y: evaluationUser?.last_name,
x: props.assignmentUser.first_name,
y: props.assignmentUser.last_name,
})
"
></ItSuccessAlert>

View File

@ -38,6 +38,12 @@ const assignmentDetail = computed(() => {
return courseSessionDetailResult.findAssignment(props.learningContent.id);
});
const isPraxisAssignment = computed(() => {
return (
props.learningContent.content_assignment.assignment_type === "PRAXIS_ASSIGNMENT"
);
});
onMounted(async () => {
const { gradedUsers, assignmentSubmittedUsers } =
await loadAssignmentCompletionStatusData(
@ -130,7 +136,13 @@ function findUserPointsHtml(userId: string) {
>
<it-icon-check class="h-4/5 w-4/5"></it-icon-check>
</div>
<div class="ml-2">{{ $t("a.Bewertung freigegeben") }}</div>
<div class="ml-2">
{{
isPraxisAssignment
? $t("a.Feedback freigegeben")
: $t("a.Bewertung freigegeben")
}}
</div>
</div>
<div
v-else-if="state.assignmentSubmittedUsers.includes(csu)"
@ -146,7 +158,7 @@ function findUserPointsHtml(userId: string) {
<!-- eslint-disable vue/no-v-html -->
<div
v-if="findGradedUser(csu.user_id)"
v-if="findGradedUser(csu.user_id) && !isPraxisAssignment"
v-html="findUserPointsHtml(csu.user_id)"
></div>
</section>

View File

@ -343,7 +343,7 @@ export interface AssignmentEvaluationTask {
title: string;
description: string;
max_points: number;
sub_tasks: AssignmentEvaluationSubTask[];
sub_tasks?: AssignmentEvaluationSubTask[];
};
}

View File

@ -7,191 +7,334 @@ describe("assignmentTrainer.cy.js", () => {
login("test-trainer1@example.com", "test");
});
it("can open cockpit assignment page and open user assignment", () => {
cy.visit("/course/test-lehrgang/cockpit");
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]'
).click();
describe("Caswork", () => {
it("can open cockpit assignment page and open user assignment", () => {
cy.visit("/course/test-lehrgang/cockpit");
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]'
).click();
cy.get('[data-cy="Student1"]').should("contain", "Ergebnisse abgegeben");
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.get('[data-cy="Student1"]').should("contain", "Ergebnisse abgegeben");
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.get('[data-cy="student-submission"]').should("contain", "Ergebnisse");
cy.get('[data-cy="student-submission"]').should("contain", "Student1");
});
it("can start evaluation and store evaluation results", () => {
cy.visit("/course/test-lehrgang/cockpit");
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]'
).click();
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.get('[data-cy="start-evaluation"]').click();
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 1 / 5"
);
// without text input the button should be disabled
cy.get('[data-cy="next-step"]').should("be.disabled");
// with text you can continue
cy.get('[data-cy="subtask-4"]').click();
cy.get('[data-cy="reason-text"]').type("Gut gemacht!");
// wait for debounce
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 2 / 5"
);
cy.get('[data-cy="subtask-2"]').click();
cy.get('[data-cy="reason-text"]').type("Nicht so gut");
cy.wait(500);
// revisit step 1 will show stored data
cy.get('[data-cy="previous-step"]').click();
cy.get('[data-cy="reason-text"]')
.find("textarea")
.should("have.value", "Gut gemacht!");
// even after reload
cy.reload();
cy.get('[data-cy="reason-text"]')
.find("textarea")
.should("have.value", "Gut gemacht!");
// it can access step directly via url
cy.url().then((url) => {
const step2Url = url.replace("step=1", "step=2");
console.log(step2Url);
cy.visit(step2Url);
cy.get('[data-cy="student-submission"]').should("contain", "Ergebnisse");
cy.get('[data-cy="student-submission"]').should("contain", "Student1");
});
cy.get('[data-cy="reason-text"]')
.find("textarea")
.should("have.value", "Nicht so gut");
it("can start evaluation and store evaluation results", () => {
cy.visit("/course/test-lehrgang/cockpit");
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]'
).click();
// load AssignmentCompletion from DB and check
cy.loadAssignmentCompletion(
"assignment_user_id",
TEST_STUDENT1_USER_ID
).then((ac) => {
expect(ac.completion_status).to.equal("EVALUATION_IN_PROGRESS");
expect(JSON.stringify(ac.completion_data)).to.include("Nicht so gut");
expect(Cypress._.values(ac.completion_data)).to.deep.include({
expert_data: { points: 2, text: "Nicht so gut" },
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.get('[data-cy="title"]').should("contain", "Bewertung");
cy.get('[data-cy="evaluation-duedate"]').should("exist");
cy.get('[data-cy="instruction"]').should(
"contain",
"Die Gesamtpunktzahl und die daraus resultierende Note wird auf Grund des hinterlegeten Beurteilungsinstrument berechnet."
);
cy.get('[data-cy="start-evaluation"]').click();
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 1 / 5"
);
// without text input the button should be disabled
cy.get('[data-cy="next-step"]').should("be.disabled");
// with text you can continue
cy.get('[data-cy="subtask-4"]').click();
cy.get('[data-cy="reason-text"]').type("Gut gemacht!");
// wait for debounce
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 2 / 5"
);
cy.get('[data-cy="subtask-2"]').click();
cy.get('[data-cy="reason-text"]').type("Nicht so gut");
cy.wait(500);
// revisit step 1 will show stored data
cy.get('[data-cy="previous-step"]').click();
cy.get('[data-cy="reason-text"]')
.find("textarea")
.should("have.value", "Gut gemacht!");
// even after reload
cy.reload();
cy.get('[data-cy="reason-text"]')
.find("textarea")
.should("have.value", "Gut gemacht!");
// it can access step directly via url
cy.url().then((url) => {
const step2Url = url.replace("step=1", "step=2");
console.log(step2Url);
cy.visit(step2Url);
});
expect(Cypress._.values(ac.completion_data)).to.deep.include({
expert_data: { points: 4, text: "Gut gemacht!" },
cy.get('[data-cy="reason-text"]')
.find("textarea")
.should("have.value", "Nicht so gut");
cy.wait(500);
// load AssignmentCompletion from DB and check
cy.loadAssignmentCompletion(
"assignment_user_id",
TEST_STUDENT1_USER_ID
).then((ac) => {
expect(ac.completion_status).to.equal("EVALUATION_IN_PROGRESS");
expect(JSON.stringify(ac.completion_data)).to.include("Nicht so gut");
expect(Cypress._.values(ac.completion_data)).to.deep.include({
expert_data: { points: 2, text: "Nicht so gut" },
});
expect(Cypress._.values(ac.completion_data)).to.deep.include({
expert_data: { points: 4, text: "Gut gemacht!" },
});
});
});
it("can make complete evaluation", () => {
cy.visit("/course/test-lehrgang/cockpit");
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]'
).click();
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.get('[data-cy="start-evaluation"]').click();
// step 1
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 1 / 5"
);
cy.get('[data-cy="subtask-6"]').click();
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 1");
// wait for debounce
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// step 2
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 2 / 5"
);
cy.get('[data-cy="subtask-4"]').click();
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 2");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// step 3
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 3 / 5"
);
cy.get('[data-cy="subtask-2"]').click();
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 3");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// step 4
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 4 / 5"
);
cy.get('[data-cy="subtask-3"]').click();
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 4");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// step 5
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 5 / 5"
);
cy.get('[data-cy="subtask-2"]').click();
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 5");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// freigabe
cy.get('[data-cy="sub-title"]').should("contain", "Bewertung Freigabe");
cy.get('[data-cy="user-points"]').should("contain", "17");
cy.get('[data-cy="total-points"]').should("contain", "24");
cy.get('[data-cy="submit-evaluation"]').click();
cy.get('[data-cy="result-section"]').should(
"contain",
"Deine Bewertung für Test Student1 wurde freigegeben"
);
// going back to cockpit should show points for student
cy.visit("/course/test-lehrgang/cockpit");
cy.reload();
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]'
).click();
cy.get('[data-cy="Student1"]').should("contain", "Bewertung freigegeben");
cy.get('[data-cy="Student1"]').should("contain", "17 von 24 Punkte");
// clicking on results page will go to last step
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.url().should("include", "step=6");
// load AssignmentCompletion from DB and check
cy.loadAssignmentCompletion(
"assignment_user_id",
TEST_STUDENT1_USER_ID
).then((ac) => {
expect(ac.completion_status).to.equal("EVALUATION_SUBMITTED");
expect(ac.evaluation_points).to.equal(17);
expect(ac.evaluation_max_points).to.equal(24);
expect(ac.evaluation_passed).to.equal(true);
const completionString = JSON.stringify(ac.completion_data);
expect(completionString).to.include("Begründung Schritt 1");
expect(completionString).to.include("Begründung Schritt 2");
expect(completionString).to.include("Begründung Schritt 3");
expect(completionString).to.include("Begründung Schritt 4");
expect(completionString).to.include("Begründung Schritt 5");
});
});
});
it("can make complete evaluation", () => {
cy.visit("/course/test-lehrgang/cockpit");
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]'
).click();
//Todo: Move tests to Lernbegleitung once it is implemented
describe("Praxis Assignment", () => {
it("can start evaluation and store evaluation results", () => {
cy.visit("/course/test-lehrgang/cockpit");
cy.get('[data-cy="dropdown-select"]').click();
cy.get('[data-cy="dropdown-select-option-Reisen"]').click();
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-reisen-lc-mein-kundenstamm"]'
).click();
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.get('[data-cy="start-evaluation"]').click();
cy.get('[data-cy="title"]').should("contain", "Feedback");
cy.get('[data-cy="evaluation-duedate]"').should("not.exist");
cy.get('[data-cy="instruction"]').should("contain", "Intro für Feedback");
cy.get('[data-cy="start-evaluation"]').click();
cy.get('[data-cy="evaluation-task"]').should("contain", "Feedback 1 / 5");
// step 1
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 1 / 5"
);
cy.get('[data-cy="subtask-6"]').click();
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 1");
// wait for debounce
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// without text input the button should be disabled
cy.get('[data-cy="next-step"]').should("be.disabled");
// step 2
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 2 / 5"
);
cy.get('[data-cy="subtask-4"]').click();
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 2");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// with text you can continue
cy.get('[data-cy="reason-text"]').type("Gut gemacht!");
// wait for debounce
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// step 3
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 3 / 5"
);
cy.get('[data-cy="subtask-2"]').click();
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 3");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
cy.get('[data-cy="evaluation-task"]').should("contain", "Feedback 2 / 5");
cy.get('[data-cy="reason-text"]').type("Nicht so gut");
cy.wait(1000);
// step 4
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 4 / 5"
);
cy.get('[data-cy="subtask-3"]').click();
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 4");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// load AssignmentCompletion from DB and check
cy.loadAssignmentCompletion(
"assignment_user_id",
TEST_STUDENT1_USER_ID
).then((ac) => {
console.log(ac.completion_status);
expect(ac.completion_status).to.equal("EVALUATION_IN_PROGRESS");
expect(JSON.stringify(ac.completion_data)).to.include("Nicht so gut");
expect(Cypress._.values(ac.completion_data)).to.deep.include({
expert_data: { points: 0, text: "Nicht so gut" },
});
expect(Cypress._.values(ac.completion_data)).to.deep.include({
expert_data: { points: 0, text: "Gut gemacht!" },
});
});
});
// step 5
cy.get('[data-cy="evaluation-task"]').should(
"contain",
"Beurteilungskriterium 5 / 5"
);
cy.get('[data-cy="subtask-2"]').click();
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 5");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
it("can make complete evaluation", () => {
cy.visit("/course/test-lehrgang/cockpit");
cy.get('[data-cy="dropdown-select"]').click();
cy.get('[data-cy="dropdown-select-option-Reisen"]').click();
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-reisen-lc-mein-kundenstamm"]'
).click();
// freigabe
cy.get('[data-cy="sub-title"]').should("contain", "Bewertung Freigabe");
cy.get('[data-cy="user-points"]').should("contain", "17");
cy.get('[data-cy="total-points"]').should("contain", "24");
cy.get('[data-cy="submit-evaluation"]').click();
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.get('[data-cy="result-section"]').should(
"contain",
"Deine Bewertung für Test Student1 wurde freigegeben"
);
cy.get('[data-cy="start-evaluation"]').click();
// going back to cockpit should show points for student
cy.visit("/course/test-lehrgang/cockpit");
cy.reload();
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-fahrzeug-lc-überprüfen-einer-motorfahrzeug-versicherungspolice"]'
).click();
// step 1
cy.get('[data-cy="evaluation-task"]').should("contain", "Feedback 1 / 5");
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 1");
// wait for debounce
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
cy.get('[data-cy="Student1"]').should("contain", "Bewertung freigegeben");
cy.get('[data-cy="Student1"]').should("contain", "17 von 24 Punkte");
// step 2
cy.get('[data-cy="evaluation-task"]').should("contain", "Feedback 2 / 5");
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 2");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// clicking on results page will go to last step
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.url().should("include", "step=6");
// step 3
cy.get('[data-cy="evaluation-task"]').should("contain", "Feedback 3 / 5");
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 3");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// load AssignmentCompletion from DB and check
cy.loadAssignmentCompletion(
"assignment_user_id",
TEST_STUDENT1_USER_ID
).then((ac) => {
expect(ac.completion_status).to.equal("EVALUATION_SUBMITTED");
expect(ac.evaluation_points).to.equal(17);
expect(ac.evaluation_max_points).to.equal(24);
expect(ac.evaluation_passed).to.equal(true);
const completionString = JSON.stringify(ac.completion_data);
expect(completionString).to.include("Begründung Schritt 1");
expect(completionString).to.include("Begründung Schritt 2");
expect(completionString).to.include("Begründung Schritt 3");
expect(completionString).to.include("Begründung Schritt 4");
expect(completionString).to.include("Begründung Schritt 5");
// step 4
cy.get('[data-cy="evaluation-task"]').should("contain", "Feedback 4 / 5");
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 4");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// step 5
cy.get('[data-cy="evaluation-task"]').should("contain", "Feedback 5 / 5");
cy.get('[data-cy="reason-text"]').type("Begründung Schritt 5");
cy.wait(500);
cy.get('[data-cy="next-step"]').click();
// freigabe
cy.get('[data-cy="sub-title"]').should("contain", "Feedback Freigabe");
cy.get('[data-cy="total-points"]').should("not.exist");
cy.get('[data-cy="submit-evaluation"]').click();
cy.get('[data-cy="result-section"]').should(
"contain",
"Dein Feedback für Test Student1 wurde freigegeben"
);
// going back to cockpit should show points for student
cy.visit("/course/test-lehrgang/cockpit");
cy.reload();
cy.get('[data-cy="dropdown-select"]').click();
cy.get('[data-cy="dropdown-select-option-Reisen"]').click();
cy.get(
'[data-cy="show-details-btn-test-lehrgang-lp-circle-reisen-lc-mein-kundenstamm"]'
).click();
cy.get('[data-cy="Student1"]').should("contain", "Feedback freigegeben");
cy.get('[data-cy="Student1"]').should("not.contain", "Punkte");
// clicking on results page will go to last step
cy.get('[data-cy="Student1"]').find('[data-cy="show-results"]').click();
cy.url().should("include", "step=6");
// load AssignmentCompletion from DB and check
cy.loadAssignmentCompletion(
"assignment_user_id",
TEST_STUDENT1_USER_ID
).then((ac) => {
expect(ac.completion_status).to.equal("EVALUATION_SUBMITTED");
expect(ac.evaluation_max_points).to.equal(0);
const completionString = JSON.stringify(ac.completion_data);
expect(completionString).to.include("Begründung Schritt 1");
expect(completionString).to.include("Begründung Schritt 2");
expect(completionString).to.include("Begründung Schritt 3");
expect(completionString).to.include("Begründung Schritt 4");
expect(completionString).to.include("Begründung Schritt 5");
});
});
});
});

View File

@ -4294,6 +4294,15 @@ def create_vv_gewinnen_casework(course_id=COURSE_VERSICHERUNGSVERMITTLERIN_ID):
),
),
)
assignment.evaluation_tasks.append(
(
"task",
EvaluationTaskBlockFactory(
title="Feedback zu Teilaufgabe 5",
max_points=0,
),
),
)
assignment.tasks = []
assignment.tasks.append(
@ -4515,6 +4524,29 @@ def create_vv_gewinnen_casework(course_id=COURSE_VERSICHERUNGSVERMITTLERIN_ID):
),
)
)
assignment.tasks.append(
(
"task",
TaskBlockFactory(
title="Teilaufgabe 5: Kundentelefonate2",
content=StreamValue(
TaskContentStreamBlock(),
stream_data=[
(
"user_text_input",
UserTextInputBlockFactory(
text=RichText(
"""
<p>Notiere, welche hundert Kunden du nächste Woche für ein Beratungsgespräch telefonisch kontaktieren willst.</p>
"""
)
),
),
],
),
),
)
)
assignment.save()

View File

@ -144,7 +144,7 @@ def update_assignment_completion(
ac.evaluation_points = evaluation_points
# if no evaluation_passed is provided, we calculate it from the points
if evaluation_passed is None:
if evaluation_passed is None and ac.evaluation_max_points > 0:
if evaluation_points is not None and ac.evaluation_max_points is not None:
# if more or equal than 60% of the points are reached, the assignment is passed
ac.evaluation_passed = (evaluation_points / ac.evaluation_max_points) >= 0.6