Skip to content

Commit 1073bd1

Browse files
committed
Add regression test and fix to ensure that full image paths are put in the question_images dict as keys, rather than just filenames.
1 parent 5d6c0db commit 1073bd1

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

contentcuration/contentcuration/tests/utils/test_exercise_creation.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,86 @@ def test_multiple_question_types(self):
728728
# we are deliberately changing the archive generation algorithm for perseus files.
729729
self.assertEqual(exercise_file.checksum, "94de065d485e52d56c3032074044e7c3")
730730

731+
def test_image_key_full_path_regression(self):
732+
"""Regression test for image key containing full path in Perseus files.
733+
734+
This test ensures that the 'images' object in Perseus JSON files uses the full path
735+
as the key (${IMG_PLACEHOLDER}/images/filename.ext) rather than just the filename.
736+
737+
Bug: The image key in the 'images' object was being set to just the filename
738+
instead of the full path with IMG_PLACEHOLDER prefix.
739+
"""
740+
# Create an image file
741+
image_file = fileobj_exercise_image()
742+
743+
# Create a question with image that has dimensions (to trigger images object generation)
744+
image_url = exercises.CONTENT_STORAGE_FORMAT.format(image_file.filename())
745+
question_text = f"Identify the shape: ![shape]({image_url} =100x100)"
746+
item = self._create_assessment_item(
747+
exercises.SINGLE_SELECTION,
748+
question_text,
749+
[
750+
{"answer": "Circle", "correct": True, "order": 1},
751+
{"answer": "Square", "correct": False, "order": 2},
752+
],
753+
)
754+
755+
# Associate the image with the assessment item
756+
image_file.assessment_item = item
757+
image_file.save()
758+
759+
# Create the exercise data
760+
exercise_data = {
761+
"mastery_model": exercises.M_OF_N,
762+
"randomize": True,
763+
"n": 1,
764+
"m": 1,
765+
"all_assessment_items": [item.assessment_id],
766+
"assessment_mapping": {item.assessment_id: exercises.SINGLE_SELECTION},
767+
}
768+
769+
# Create the Perseus exercise
770+
self._create_perseus_zip(exercise_data)
771+
772+
# Verify that a file was created
773+
exercise_file = self.exercise_node.files.get(preset_id=format_presets.EXERCISE)
774+
775+
# Validate the zip file
776+
zip_file, _ = self._validate_perseus_zip(exercise_file)
777+
778+
# Get the Perseus item JSON content
779+
item_json = json.loads(
780+
zip_file.read(f"{item.assessment_id}.json").decode("utf-8")
781+
)
782+
783+
# The critical regression check: images object keys should contain full path
784+
question_images = item_json["question"]["images"]
785+
786+
# Should have exactly one image entry
787+
self.assertEqual(
788+
len(question_images),
789+
1,
790+
f"Expected 1 image in images object, got {len(question_images)}: {list(question_images.keys())}",
791+
)
792+
793+
# Get the image key from the images object
794+
image_key = list(question_images.keys())[0]
795+
796+
# The key should be the full path, not just the filename
797+
expected_full_path = (
798+
f"${exercises.IMG_PLACEHOLDER}/images/{image_file.filename()}"
799+
)
800+
self.assertEqual(
801+
image_key,
802+
expected_full_path,
803+
f"Image key should be '{expected_full_path}' but got: '{image_key}'",
804+
)
805+
806+
# Verify the image has the expected dimensions
807+
image_data = question_images[image_key]
808+
self.assertEqual(image_data["width"], 100)
809+
self.assertEqual(image_data["height"], 100)
810+
731811
def _test_image_resizing_in_field(self, field_type):
732812
"""
733813
Helper method to test image resizing in different fields (question, answer, hint)

contentcuration/contentcuration/utils/assessment/base.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,11 @@ def process_image_strings(self, content):
272272
)
273273
if width is not None and height is not None:
274274
image_list.append(
275-
{"name": processed_filename, "width": width, "height": height}
275+
{
276+
"name": f"{new_image_path}/{processed_filename}",
277+
"width": width,
278+
"height": height,
279+
}
276280
)
277281

278282
content = content.replace(

0 commit comments

Comments
 (0)