From fe982656365a6a61571d4fc2e01e4fa1378d557e Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Fri, 20 Oct 2023 10:56:47 +0530 Subject: [PATCH] test: fix quiz tests --- lms/lms/doctype/lms_question/lms_question.py | 30 ++++++++- lms/lms/doctype/lms_quiz/lms_quiz.js | 10 +++ lms/lms/doctype/lms_quiz/test_lms_quiz.py | 61 +++++++------------ .../lms_quiz_question/lms_quiz_question.json | 4 +- lms/patches/v1_0/add_default_marks.py | 2 + 5 files changed, 65 insertions(+), 42 deletions(-) diff --git a/lms/lms/doctype/lms_question/lms_question.py b/lms/lms/doctype/lms_question/lms_question.py index 414baf02..0e6f87bd 100644 --- a/lms/lms/doctype/lms_question/lms_question.py +++ b/lms/lms/doctype/lms_question/lms_question.py @@ -16,6 +16,8 @@ def validate_correct_answers(question): if question.type == "Choices": validate_duplicate_options(question) validate_correct_options(question) + else: + validate_possible_answer(question) def validate_duplicate_options(question): @@ -39,14 +41,40 @@ def validate_correct_options(question): frappe.throw(_("At least one option must be correct for this question.")) +def validate_possible_answer(question): + possible_answers = [] + possible_answers_fields = [ + "possibility_1", + "possibility_2", + "possibility_3", + "possibility_4", + ] + + for field in possible_answers_fields: + if question.get(field): + possible_answers.append(field) + + if not len(possible_answers): + frappe.throw( + _("Add at least one possible answer for this question: {0}").format( + frappe.bold(question.question) + ) + ) + + def get_correct_options(question): + correct_options = [] correct_option_fields = [ "is_correct_1", "is_correct_2", "is_correct_3", "is_correct_4", ] - return list(filter(lambda x: question.get(x) == 1, correct_option_fields)) + for field in correct_option_fields: + if question.get(field) == 1: + correct_options.append(field) + + return correct_options @frappe.whitelist() diff --git a/lms/lms/doctype/lms_quiz/lms_quiz.js b/lms/lms/doctype/lms_quiz/lms_quiz.js index 095938be..0f6f4729 100644 --- a/lms/lms/doctype/lms_quiz/lms_quiz.js +++ b/lms/lms/doctype/lms_quiz/lms_quiz.js @@ -5,3 +5,13 @@ frappe.ui.form.on("LMS Quiz", { // refresh: function(frm) { // } }); + +frappe.ui.form.on("LMS Quiz Question", { + marks: function (frm) { + total_marks = 0; + frm.doc.questions.forEach((question) => { + total_marks += question.marks; + }); + frm.doc.total_marks = total_marks; + }, +}); diff --git a/lms/lms/doctype/lms_quiz/test_lms_quiz.py b/lms/lms/doctype/lms_quiz/test_lms_quiz.py index ee79b89a..ca6a998c 100644 --- a/lms/lms/doctype/lms_quiz/test_lms_quiz.py +++ b/lms/lms/doctype/lms_quiz/test_lms_quiz.py @@ -10,51 +10,36 @@ import frappe class TestLMSQuiz(unittest.TestCase): @classmethod def setUpClass(cls) -> None: - frappe.get_doc({"doctype": "LMS Quiz", "title": "Test Quiz"}).save( - ignore_permissions=True - ) + frappe.get_doc( + {"doctype": "LMS Quiz", "title": "Test Quiz", "passing_percentage": 90} + ).save(ignore_permissions=True) def test_with_multiple_options(self): - quiz = frappe.get_doc("LMS Quiz", "test-quiz") - quiz.append( - "questions", - { - "question": "Question Multiple", - "type": "Choices", - "option_1": "Option 1", - "is_correct_1": 1, - "option_2": "Option 2", - "is_correct_2": 1, - }, - ) - quiz.save() - self.assertTrue(quiz.questions[0].multiple) + question = frappe.new_doc("LMS Question") + question.question = "Question Multiple" + question.type = "Choices" + question.option_1 = "Option 1" + question.is_correct_1 = 1 + question.option_2 = "Option 2" + question.is_correct_2 = 1 + question.save() + self.assertTrue(question.multiple) def test_with_no_correct_option(self): - quiz = frappe.get_doc("LMS Quiz", "test-quiz") - quiz.append( - "questions", - { - "question": "Question no correct option", - "type": "Choices", - "option_1": "Option 1", - "option_2": "Option 2", - }, - ) - self.assertRaises(frappe.ValidationError, quiz.save) + question = frappe.new_doc("LMS Question") + question.question = "Question Multiple" + question.type = "Choices" + question.option_1 = "Option 1" + question.option_2 = "Option 2" + self.assertRaises(frappe.ValidationError, question.save) def test_with_no_possible_answers(self): - quiz = frappe.get_doc("LMS Quiz", "test-quiz") - quiz.append( - "questions", - { - "question": "Question Possible Answers", - "type": "User Input", - }, - ) - self.assertRaises(frappe.ValidationError, quiz.save) + question = frappe.new_doc("LMS Question") + question.question = "Question Multiple" + question.type = "User Input" + self.assertRaises(frappe.ValidationError, question.save) @classmethod def tearDownClass(cls) -> None: frappe.db.delete("LMS Quiz", "test-quiz") - frappe.db.delete("LMS Quiz Question", {"parent": "test-quiz"}) + frappe.db.delete("LMS Question") diff --git a/lms/lms/doctype/lms_quiz_question/lms_quiz_question.json b/lms/lms/doctype/lms_quiz_question/lms_quiz_question.json index 4be1f88e..e14a8d48 100644 --- a/lms/lms/doctype/lms_quiz_question/lms_quiz_question.json +++ b/lms/lms/doctype/lms_quiz_question/lms_quiz_question.json @@ -13,7 +13,6 @@ "fieldname": "question", "fieldtype": "Link", "in_list_view": 1, - "in_preview": 1, "label": "Question", "options": "LMS Question", "reqd": 1 @@ -23,7 +22,6 @@ "fieldname": "marks", "fieldtype": "Int", "in_list_view": 1, - "in_preview": 1, "label": "Marks", "non_negative": 1, "reqd": 1 @@ -32,7 +30,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2023-10-16 19:51:03.893143", + "modified": "2023-10-16 19:51:03.893144", "modified_by": "Administrator", "module": "LMS", "name": "LMS Quiz Question", diff --git a/lms/patches/v1_0/add_default_marks.py b/lms/patches/v1_0/add_default_marks.py index fb35a0f6..5560af5d 100644 --- a/lms/patches/v1_0/add_default_marks.py +++ b/lms/patches/v1_0/add_default_marks.py @@ -2,6 +2,8 @@ import frappe def execute(): + frappe.reload_doc("lms", "doctype", "lms_quiz_question") + frappe.reload_doc("lms", "doctype", "lms_quiz") questions = frappe.get_all("LMS Quiz Question", pluck="name") for question in questions: