|
38 | 38 | from cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers import ( |
39 | 39 | ALWAYS, |
40 | 40 | VisibilityState, |
| 41 | + _get_metadata_with_problem_defaults, |
41 | 42 | _get_source_index, |
42 | 43 | _xblock_type_and_display_name, |
43 | 44 | add_container_page_publishing_info, |
@@ -3501,6 +3502,83 @@ def validate_xblock_info_consistency( |
3501 | 3502 | self.assertIsNone(xblock_info.get("child_info", None)) |
3502 | 3503 |
|
3503 | 3504 |
|
| 3505 | +class TestGetMetadataWithProblemDefaults(ModuleStoreTestCase): |
| 3506 | + """ |
| 3507 | + Unit tests for _get_metadata_with_problem_defaults. |
| 3508 | +
|
| 3509 | + The helper must inject a ``weight`` value (derived from ``max_score()``) for |
| 3510 | + problem xblocks that have never had ``weight`` explicitly saved, while leaving |
| 3511 | + every other combination untouched. |
| 3512 | + """ |
| 3513 | + |
| 3514 | + def _make_problem(self, **kwargs): |
| 3515 | + """Create and return a problem xblock from the modulestore.""" |
| 3516 | + course = CourseFactory.create() |
| 3517 | + block = BlockFactory.create( |
| 3518 | + parent_location=course.location, |
| 3519 | + category='problem', |
| 3520 | + display_name='A Problem', |
| 3521 | + **kwargs, |
| 3522 | + ) |
| 3523 | + return modulestore().get_item(block.location) |
| 3524 | + |
| 3525 | + # ------------------------------------------------------------------ |
| 3526 | + # Problem blocks – weight absent from stored metadata |
| 3527 | + # ------------------------------------------------------------------ |
| 3528 | + |
| 3529 | + def test_problem_without_weight_adds_weight_from_max_score(self): |
| 3530 | + """ |
| 3531 | + When weight is absent and max_score() > 0, it is injected into metadata. |
| 3532 | + """ |
| 3533 | + xblock = self._make_problem() |
| 3534 | + with patch.object(xblock, 'max_score', return_value=3.0): |
| 3535 | + metadata = _get_metadata_with_problem_defaults(xblock) |
| 3536 | + self.assertEqual(metadata.get('weight'), 3.0) |
| 3537 | + |
| 3538 | + def test_problem_without_weight_max_score_zero_does_not_inject(self): |
| 3539 | + """ |
| 3540 | + A zero max_score will not inject a weight. |
| 3541 | + """ |
| 3542 | + xblock = self._make_problem() |
| 3543 | + with patch.object(xblock, 'max_score', return_value=0): |
| 3544 | + metadata = _get_metadata_with_problem_defaults(xblock) |
| 3545 | + self.assertNotIn('weight', metadata) |
| 3546 | + |
| 3547 | + # ------------------------------------------------------------------ |
| 3548 | + # Problem blocks – weight already present in stored metadata |
| 3549 | + # ------------------------------------------------------------------ |
| 3550 | + |
| 3551 | + def test_problem_with_explicit_weight_is_preserved(self): |
| 3552 | + """ |
| 3553 | + When weight is already explicitly set, it will not be overwritten. |
| 3554 | + """ |
| 3555 | + xblock = self._make_problem(weight=5.0) |
| 3556 | + with patch.object(xblock, 'max_score', return_value=2.0): |
| 3557 | + metadata = _get_metadata_with_problem_defaults(xblock) |
| 3558 | + self.assertEqual(metadata.get('weight'), 5.0) |
| 3559 | + |
| 3560 | + # ------------------------------------------------------------------ |
| 3561 | + # Non-problem blocks |
| 3562 | + # ------------------------------------------------------------------ |
| 3563 | + |
| 3564 | + def test_non_problem_block_is_unmodified(self): |
| 3565 | + """ |
| 3566 | + Non-problem blocks must pass through untouched even if a max_score |
| 3567 | + method is available on them. |
| 3568 | + """ |
| 3569 | + course = CourseFactory.create() |
| 3570 | + video = BlockFactory.create( |
| 3571 | + parent_location=course.location, |
| 3572 | + category='video', |
| 3573 | + display_name='A Video', |
| 3574 | + ) |
| 3575 | + xblock = modulestore().get_item(video.location) |
| 3576 | + metadata_before = dict(get_block_info(xblock).get('metadata', {})) |
| 3577 | + metadata_result = _get_metadata_with_problem_defaults(xblock) |
| 3578 | + self.assertEqual(metadata_result, metadata_before) |
| 3579 | + self.assertNotIn('weight', metadata_result) |
| 3580 | + |
| 3581 | + |
3504 | 3582 | @patch.dict("django.conf.settings.FEATURES", {"ENABLE_SPECIAL_EXAMS": True}) |
3505 | 3583 | @ddt.ddt |
3506 | 3584 | class TestSpecialExamXBlockInfo(ItemTest): |
|
0 commit comments