Skip to content

Commit 1c2e67b

Browse files
committed
fix: serialise QTI item language as xml:lang
QTI 3.0 declares xml:lang on qti-assessment-item; `language` is not an attribute of the element. Renaming the pydantic field to `xml__lang` is enough — XMLElement.to_element already maps `__` to `:`. Exercise zip checksums shift because the generated XML changed.
1 parent 906966f commit 1c2e67b

12 files changed

Lines changed: 26 additions & 26 deletions

‎contentcuration/contentcuration/tests/utils/qti/fixtures/free_response_no_answers.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="K_ty6CYdlQyH-3LoJh2VDIQ" title="Test Question 1" adaptive="false" time-dependent="false" language="en-US" tool-name="kolibri" tool-version="0.1">
2+
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="K_ty6CYdlQyH-3LoJh2VDIQ" title="Test Question 1" adaptive="false" time-dependent="false" xml:lang="en-US" tool-name="kolibri" tool-version="0.1">
33
<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="string" />
44
<qti-outcome-declaration identifier="SCORE" cardinality="single" base-type="float" />
55
<qti-item-body>

‎contentcuration/contentcuration/tests/utils/qti/fixtures/free_response_with_maths.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="K_ty6CYdlQyH-3LoJh2VDIQ" title="Test Question 1" adaptive="false" time-dependent="false" language="en-US" tool-name="kolibri" tool-version="0.1">
2+
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="K_ty6CYdlQyH-3LoJh2VDIQ" title="Test Question 1" adaptive="false" time-dependent="false" xml:lang="en-US" tool-name="kolibri" tool-version="0.1">
33
<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="string">
44
<qti-correct-response>
55
<qti-value>Nothing</qti-value>

‎contentcuration/contentcuration/tests/utils/qti/fixtures/input_question.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="K_ty6CYdlQyH-3LoJh2VDIQ" title="Test Question 1" adaptive="false" time-dependent="false" language="en-US" tool-name="kolibri" tool-version="0.1">
2+
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="K_ty6CYdlQyH-3LoJh2VDIQ" title="Test Question 1" adaptive="false" time-dependent="false" xml:lang="en-US" tool-name="kolibri" tool-version="0.1">
33
<qti-response-declaration identifier="RESPONSE" cardinality="multiple" base-type="float">
44
<qti-correct-response>
55
<qti-value>1</qti-value>

‎contentcuration/contentcuration/tests/utils/qti/fixtures/math_content_choice_interaction.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="K3d3d3d3d3d3d3d3d3d3d3Q" title="Test Question 1" adaptive="false" time-dependent="false" language="en-US" tool-name="kolibri" tool-version="0.1">
2+
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="K3d3d3d3d3d3d3d3d3d3d3Q" title="Test Question 1" adaptive="false" time-dependent="false" xml:lang="en-US" tool-name="kolibri" tool-version="0.1">
33
<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="identifier">
44
<qti-correct-response>
55
<qti-value>choice_0</qti-value>

‎contentcuration/contentcuration/tests/utils/qti/fixtures/multiple_selection.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="Kq83vEjRWeJCrze8SNFZ4kA" title="Test Question 1" adaptive="false" time-dependent="false" language="en-US" tool-name="kolibri" tool-version="0.1">
2+
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="Kq83vEjRWeJCrze8SNFZ4kA" title="Test Question 1" adaptive="false" time-dependent="false" xml:lang="en-US" tool-name="kolibri" tool-version="0.1">
33
<qti-response-declaration identifier="RESPONSE" cardinality="multiple" base-type="identifier">
44
<qti-correct-response>
55
<qti-value>choice_0</qti-value>

‎contentcuration/contentcuration/tests/utils/qti/fixtures/single_selection.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="KEjRWeJCrze8SNFZ4kKvN7w" title="Test Question 1" adaptive="false" time-dependent="false" language="en-US" tool-name="kolibri" tool-version="0.1">
2+
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="KEjRWeJCrze8SNFZ4kKvN7w" title="Test Question 1" adaptive="false" time-dependent="false" xml:lang="en-US" tool-name="kolibri" tool-version="0.1">
33
<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="identifier">
44
<qti-correct-response>
55
<qti-value>choice_0</qti-value>

‎contentcuration/contentcuration/tests/utils/qti/fixtures/true_false.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="KEjRWeJCrze8SNFZ4kKvN7w" title="Test Question 1" adaptive="false" time-dependent="false" language="en-US" tool-name="kolibri" tool-version="0.1">
2+
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="KEjRWeJCrze8SNFZ4kKvN7w" title="Test Question 1" adaptive="false" time-dependent="false" xml:lang="en-US" tool-name="kolibri" tool-version="0.1">
33
<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="identifier">
44
<qti-correct-response>
55
<qti-value>choice_0</qti-value>

‎contentcuration/contentcuration/tests/utils/qti/test_assessment_items.py‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def test_assessment_item_with_catalog_info_orders_between_item_body_and_response
5656
assessment_item = AssessmentItem(
5757
identifier="item1",
5858
title="Test",
59-
language="en-US",
59+
xml__lang="en-US",
6060
item_body=item_body,
6161
catalog_info=catalog_info,
6262
response_processing=response_processing,
@@ -78,7 +78,7 @@ def test_true_false_question(self):
7878
title="BG true false example "
7979
adaptive="false"
8080
time-dependent="false"
81-
language="en-US"
81+
xml:lang="en-US"
8282
tool-name="kolibri"
8383
tool-version="0.1">
8484
<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="identifier">
@@ -139,7 +139,7 @@ def test_true_false_question(self):
139139
assessment_item = AssessmentItem(
140140
identifier="beginnersguide007",
141141
title="BG true false example ",
142-
language="EN-US",
142+
xml__lang="EN-US",
143143
time_dependent=False,
144144
item_body=item_body,
145145
response_declaration=[response_declaration],
@@ -162,7 +162,7 @@ def test_multiple_choice_question(self):
162162
title="BG Choice example"
163163
adaptive="false"
164164
time-dependent="false"
165-
language="en-US"
165+
xml:lang="en-US"
166166
tool-name="kolibri"
167167
tool-version="0.1">
168168
<qti-response-declaration identifier="RESPONSE" cardinality="multiple" base-type="identifier">
@@ -257,7 +257,7 @@ def test_multiple_choice_question(self):
257257
assessment_item = AssessmentItem(
258258
identifier="beginnersguide008",
259259
title="BG Choice example",
260-
language="EN-US",
260+
xml__lang="EN-US",
261261
time_dependent=False,
262262
item_body=item_body,
263263
response_declaration=[response_declaration],
@@ -277,7 +277,7 @@ def test_long_text_question(self):
277277
title="BG Postcard example"
278278
adaptive="false"
279279
time-dependent="false"
280-
language="en-US"
280+
xml:lang="en-US"
281281
tool-name="kolibri"
282282
tool-version="0.1">
283283
<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="string" />
@@ -350,7 +350,7 @@ def test_long_text_question(self):
350350
assessment_item = AssessmentItem(
351351
identifier="beginnersguide009",
352352
title="BG Postcard example",
353-
language="en-US",
353+
xml__lang="en-US",
354354
time_dependent=False,
355355
item_body=item_body,
356356
response_declaration=[response_declaration],
@@ -369,7 +369,7 @@ def test_missing_word_question(self):
369369
title="BG Missing Word example"
370370
adaptive="false"
371371
time-dependent="false"
372-
language="en-US"
372+
xml:lang="en-US"
373373
tool-name="kolibri"
374374
tool-version="0.1">
375375
<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="string">
@@ -460,7 +460,7 @@ def test_missing_word_question(self):
460460
assessment_item = AssessmentItem(
461461
identifier="beginnersguide010",
462462
title="BG Missing Word example",
463-
language="en-US",
463+
xml__lang="en-US",
464464
time_dependent=False,
465465
item_body=item_body,
466466
response_declaration=[response_declaration],
@@ -480,7 +480,7 @@ def test_numerical_entry_question(self):
480480
title="Numerical Entry Question"
481481
adaptive="false"
482482
time-dependent="false"
483-
language="en-US"
483+
xml:lang="en-US"
484484
tool-name="kolibri"
485485
tool-version="0.1">
486486
<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="float">
@@ -525,7 +525,7 @@ def test_numerical_entry_question(self):
525525
assessment_item = AssessmentItem(
526526
identifier="numerical-entry-item",
527527
title="Numerical Entry Question",
528-
language="en-US",
528+
xml__lang="en-US",
529529
time_dependent=False,
530530
item_body=ItemBody(
531531
children=[

‎contentcuration/contentcuration/tests/utils/qti/test_qti.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,10 @@ def test_assessment_item_element(self):
220220
assessment_item_element = AssessmentItem(
221221
identifier="item_1",
222222
title="Test Assessment Item",
223-
language="en-US",
223+
xml__lang="en-US",
224224
item_body=item_body,
225225
)
226-
expected_xml = '<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="item_1" title="Test Assessment Item" adaptive="false" language="en-US" tool-name="kolibri" tool-version="0.1"><qti-item-body><p>Test Item Body Content</p></qti-item-body></qti-assessment-item>' # noqa: E501
226+
expected_xml = '<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="item_1" title="Test Assessment Item" adaptive="false" xml:lang="en-US" tool-name="kolibri" tool-version="0.1"><qti-item-body><p>Test Item Body Content</p></qti-item-body></qti-assessment-item>' # noqa: E501
227227
self.assertEqual(assessment_item_element.to_xml_string(), expected_xml)
228228

229229
def test_prompt_element(self):

‎contentcuration/contentcuration/tests/utils/test_exercise_creation.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,7 +1637,7 @@ def test_exercise_with_image(self):
16371637
_normalize_xml(actual_manifest_xml),
16381638
)
16391639

1640-
self.assertEqual(exercise_file.checksum, "cd5a770d35fa1c25092331ee00f4ce4a")
1640+
self.assertEqual(exercise_file.checksum, "08f316508478ea4710b96473d0e5e1f3")
16411641

16421642
def test_image_resizing(self):
16431643
# Create a base image file
@@ -1707,7 +1707,7 @@ def test_image_resizing(self):
17071707

17081708
# Expected QTI item XML content with MathML conversion
17091709
expected_item_xml = f"""<?xml version="1.0" encoding="UTF-8"?>
1710-
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="{qti_id}" title="Test QTI Exercise 1" adaptive="false" time-dependent="false" language="en-US" tool-name="kolibri" tool-version="0.1">
1710+
<qti-assessment-item xmlns="http://www.imsglobal.org/xsd/imsqtiasi_v3p0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/imsqtiasi_v3p0 https://purl.imsglobal.org/spec/qti/v3p0/schema/xsd/imsqti_asiv3p0p1_v1p0.xsd" identifier="{qti_id}" title="Test QTI Exercise 1" adaptive="false" time-dependent="false" xml:lang="en-US" tool-name="kolibri" tool-version="0.1">
17111711
<qti-response-declaration identifier="RESPONSE" cardinality="single" base-type="identifier">
17121712
<qti-correct-response>
17131713
<qti-value>choice_0</qti-value>
@@ -1843,7 +1843,7 @@ def test_multiple_question_types_mixed(self):
18431843
_normalize_xml(actual_manifest_xml),
18441844
)
18451845

1846-
self.assertEqual(exercise_file.checksum, "f15370f74b06b59bca6e289fe0e9cb87")
1846+
self.assertEqual(exercise_file.checksum, "f4689243ba9f9b5e1abdc874d2d7527d")
18471847

18481848
def test_unsupported_question_type(self):
18491849
"""Test that unsupported question types raise appropriate errors"""

0 commit comments

Comments
 (0)