diff --git a/contentcuration/contentcuration/tests/utils/test_exercise_creation.py b/contentcuration/contentcuration/tests/utils/test_exercise_creation.py index 639c40c8b0..d9cd3add1b 100644 --- a/contentcuration/contentcuration/tests/utils/test_exercise_creation.py +++ b/contentcuration/contentcuration/tests/utils/test_exercise_creation.py @@ -1517,6 +1517,52 @@ def test_free_response_question(self): self._normalize_xml(actual_item_xml), ) + def test_free_response_question_no_answers(self): + assessment_id = "fedcba0987654321fedcba0987654321" + item = self._create_assessment_item( + exercises.FREE_RESPONSE, + "What is the capital of France?", + [], + assessment_id=assessment_id, + ) + + exercise_data = { + "mastery_model": exercises.M_OF_N, + "randomize": True, + "n": 1, + "m": 1, + "all_assessment_items": [item.assessment_id], + "assessment_mapping": {item.assessment_id: exercises.FREE_RESPONSE}, + } + + self._create_qti_zip(exercise_data) + exercise_file = self.exercise_node.files.get(preset_id=format_presets.QTI_ZIP) + zip_file = self._validate_qti_zip_structure(exercise_file) + + # Check the QTI XML for text entry specifics + expected_item_file = "items/K_ty6CYdlQyH-3LoJh2VDIQ.xml" + actual_item_xml = zip_file.read(expected_item_file).decode("utf-8") + + # Expected QTI item XML content for text entry + expected_item_xml = """ + + + + +
+

What is the capital of France?

+

+
+
+ +
""" + + # Compare normalized XML + self.assertEqual( + self._normalize_xml(expected_item_xml), + self._normalize_xml(actual_item_xml), + ) + def test_free_response_question_with_maths(self): assessment_id = "fedcba0987654321fedcba0987654321" item = self._create_assessment_item( diff --git a/contentcuration/contentcuration/utils/assessment/qti/archive.py b/contentcuration/contentcuration/utils/assessment/qti/archive.py index 2feea1fe8c..7574192a61 100644 --- a/contentcuration/contentcuration/utils/assessment/qti/archive.py +++ b/contentcuration/contentcuration/utils/assessment/qti/archive.py @@ -152,15 +152,17 @@ def _create_text_entry_interaction_and_response( prompt.append(interaction_element) interaction = Div(children=prompt) - float_answer = True correct_values = [] + values_float = [] for answer in processed_data["answers"]: if answer["correct"]: correct_values.append(Value(value=str(answer["answer"]))) - try: - float(answer["answer"]) - except ValueError: - float_answer = False + try: + float(answer["answer"]) + values_float.append(True) + except ValueError: + values_float.append(False) + float_answer = bool(values_float) and all(values_float) response_declaration = ResponseDeclaration( identifier="RESPONSE",