diff --git a/frontend/src/components/Quiz.vue b/frontend/src/components/Quiz.vue index aac7eba9..0dfac5d7 100644 --- a/frontend/src/components/Quiz.vue +++ b/frontend/src/components/Quiz.vue @@ -426,7 +426,15 @@ import { FormControl, toast, } from 'frappe-ui' -import { computed, inject, reactive, ref, watch } from 'vue' +import { + computed, + inject, + onMounted, + onUnmounted, + reactive, + ref, + watch, +} from 'vue' import { CheckCircle, ChevronLeft, @@ -464,6 +472,28 @@ const props = defineProps({ }, }) +onMounted(() => { + window.addEventListener('beforeunload', handleBeforeUnload) + window.addEventListener('unload', handleUnload) +}) + +onUnmounted(() => { + window.removeEventListener('beforeunload', handleBeforeUnload) + window.removeEventListener('unload', handleUnload) +}) + +const handleBeforeUnload = (event) => { + if (activeQuestion.value > 0 && !quizSubmission.data) { + event.preventDefault() + return '' + } +} + +const handleUnload = (event) => { + console.log('unload event triggered') + submitQuiz() +} + const quiz = createResource({ url: 'frappe.client.get', makeParams(values) { diff --git a/lms/lms/doctype/lms_quiz/lms_quiz.py b/lms/lms/doctype/lms_quiz/lms_quiz.py index 27b5bc86..e313dd7d 100644 --- a/lms/lms/doctype/lms_quiz/lms_quiz.py +++ b/lms/lms/doctype/lms_quiz/lms_quiz.py @@ -145,14 +145,12 @@ def process_results(results: list, quiz_details: dict): is_open_ended = False for result in results: - print(result) question_details = frappe.db.get_value( "LMS Quiz Question", {"parent": quiz_details.name, "question": result["question_name"]}, ["question", "marks", "question_detail", "type"], as_dict=1, ) - result["question_name"] = question_details.question result["question"] = question_details.question_detail result["marks_out_of"] = question_details.marks @@ -166,6 +164,7 @@ def process_results(results: list, quiz_details: dict): result["marks"] = -quiz_details.marks_to_cut if quiz_details.enable_negative_marking else 0 score += result["marks"] + result["is_correct"] = 1 if correct else 0 else: is_open_ended = True diff --git a/lms/lms/test_api.py b/lms/lms/test_api.py index 28700217..9661af75 100644 --- a/lms/lms/test_api.py +++ b/lms/lms/test_api.py @@ -47,8 +47,8 @@ class TestLMSAPI(BaseTestUtils): for quiz in progress.quizzes: self.assertEqual(quiz.quiz, self.quiz.name) self.assertEqual(quiz.quiz_title, self.quiz.title) - self.assertEqual(quiz.score, 12) - self.assertEqual(quiz.percentage, 80) + self.assertEqual(quiz.score, 10) + self.assertEqual(quiz.percentage, 66) self.assertEqual(len(progress.assignments), 1) for assignment in progress.assignments: @@ -61,3 +61,25 @@ class TestLMSAPI(BaseTestUtils): self.assertEqual(exercise.exercise, self.programming_exercise.name) self.assertEqual(exercise.exercise_title, self.programming_exercise.title) self.assertEqual(exercise.status, "Passed") + + def test_quiz_submission(self): + submission = frappe.get_all( + "LMS Quiz Submission", filters={"quiz": self.quiz.name, "member": self.student1.name} + ) + self.assertEqual(len(submission), 1) + submission = submission[0] + submission = frappe.get_doc("LMS Quiz Submission", submission.name) + + self.assertEqual(submission.score, 10) + self.assertEqual(submission.score_out_of, 15) + self.assertEqual(submission.percentage, 66) + self.assertEqual(submission.passing_percentage, 70) + self.assertEqual(len(submission.result), 3) + for index, result in enumerate(submission.result): + self.assertEqual(result.question_name, self.quiz.questions[index].question) + self.assertEqual( + result.answer, + self.questions[index].option_1 if index % 2 == 0 else self.questions[index].option_2, + ) + self.assertEqual(result.is_correct, 1 if index % 2 == 0 else 0) + self.assertEqual(result.marks, 5 if index % 2 == 0 else 0) diff --git a/lms/lms/test_helpers.py b/lms/lms/test_helpers.py index e6a2362a..3c11d87a 100644 --- a/lms/lms/test_helpers.py +++ b/lms/lms/test_helpers.py @@ -1,8 +1,11 @@ +import json + import frappe from frappe.tests import UnitTestCase from frappe.utils import add_days, nowdate from lms.lms.doctype.lms_certificate.lms_certificate import get_default_certificate_template +from lms.lms.doctype.lms_quiz.lms_quiz import submit_quiz class BaseTestUtils(UnitTestCase): @@ -267,7 +270,7 @@ class BaseTestUtils(UnitTestCase): } ) question.save() - self.cleanup_items.append(("LMS Quiz Question", question.name)) + self.cleanup_items.append(("LMS Question", question.name)) questions.append(question) return questions @@ -450,29 +453,22 @@ class BaseTestUtils(UnitTestCase): existing = frappe.db.exists("LMS Quiz Submission", {"quiz": self.quiz.name, "member": member}) if existing: return frappe.get_doc("LMS Quiz Submission", existing) - submission = frappe.new_doc("LMS Quiz Submission") - submission.update( - { - "quiz": self.quiz.name, - "member": member, - "score_out_of": self.quiz.total_marks, - "passing_percentage": self.quiz.passing_percentage, - } - ) - for question in self.questions: - submission.append( - "result", + frappe.session.user = member + results = [] + for index, question in enumerate(self.questions): + results.append( { - "question": question.name, - "marks": 4, - "marks_out_of": 5, - }, + "question_name": question.name, + "answer": [question.option_1 if index % 2 == 0 else question.option_2], + } ) - - submission.insert() - self.cleanup_items.append(("LMS Quiz Submission", submission.name)) - return submission + submit_quiz(self.quiz.name, json.dumps(results)) + submission = frappe.db.get_value( + "LMS Quiz Submission", {"quiz": self.quiz.name, "member": member}, "name" + ) + self.cleanup_items.append(("LMS Quiz Submission", submission)) + frappe.session.user = "Administrator" def _create_assignment_submission(self, member): existing = frappe.db.exists(