|
17 | 17 | from django.test.client import RequestFactory |
18 | 18 | from django.test.utils import override_settings |
19 | 19 | from django.urls import reverse |
| 20 | +from edx_toggles.toggles.testutils import override_waffle_flag |
20 | 21 | from milestones.tests.utils import MilestonesTestCaseMixin |
21 | 22 | from opaque_keys.edx.locator import CourseLocator |
22 | 23 |
|
|
30 | 31 | from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory |
31 | 32 | from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES |
32 | 33 | from openedx.features.content_type_gating.models import ContentTypeGatingConfig |
| 34 | +from openedx.features.course_experience import ENFORCE_MASQUERADE_START_DATES |
33 | 35 | from common.djangoapps.student.models import CourseEnrollment |
34 | 36 | from common.djangoapps.student.roles import CourseCcxCoachRole, CourseStaffRole |
35 | 37 | from common.djangoapps.student.tests.factories import ( |
@@ -465,6 +467,50 @@ def test__has_access_to_block_with_start_date(self, start, expected_error_type): |
465 | 467 |
|
466 | 468 | self.verify_access(mock_unit, expected_access, expected_error_type) |
467 | 469 |
|
| 470 | + @ddt.data( |
| 471 | + # Flag inactive (default) |
| 472 | + (False, True, None), # Masquerading, no start date |
| 473 | + (False, True, YESTERDAY), # Masquerading, past start date |
| 474 | + (False, False, TOMORROW), # Not masquerading, future start date |
| 475 | + (False, True, TOMORROW), # Masquerading, future start date |
| 476 | + # Flag active |
| 477 | + (True, True, None), # Masquerading, no start date |
| 478 | + (True, True, YESTERDAY), # Masquerading, past start date |
| 479 | + (True, False, TOMORROW), # Not masquerading, future start date |
| 480 | + (True, True, TOMORROW, False), # Masquerading, future start date - no access |
| 481 | + ) |
| 482 | + @ddt.unpack |
| 483 | + @patch.dict("django.conf.settings.FEATURES", {"DISABLE_START_DATES": False}) |
| 484 | + def test_enforce_masquerade_start_dates_flag(self, flag_active, is_masquerading, start, expected_access=True): |
| 485 | + """ |
| 486 | + Test that the ENFORCE_MASQUERADE_START_DATES flag controls whether masquerading bypasses start date |
| 487 | + restrictions. |
| 488 | +
|
| 489 | + When the flag is disabled (default), masquerading users bypass start dates. |
| 490 | + When the flag is enabled, masquerading users see the same start date restrictions as regular students. |
| 491 | + """ |
| 492 | + mock_unit = Mock( |
| 493 | + location=self.course.location, |
| 494 | + user_partitions=[], |
| 495 | + _class_tags={}, |
| 496 | + start=self.DATES[start], |
| 497 | + visible_to_staff_only=False, |
| 498 | + merged_group_access={}, |
| 499 | + ) |
| 500 | + |
| 501 | + if is_masquerading: |
| 502 | + self.course_staff.masquerade_settings = {self.course.id: CourseMasquerade(self.course.id, role="student")} |
| 503 | + |
| 504 | + with override_waffle_flag(ENFORCE_MASQUERADE_START_DATES, active=flag_active): |
| 505 | + response = access._has_access_to_block(self.course_staff, "load", mock_unit, course_key=self.course.id) |
| 506 | + |
| 507 | + if expected_access: |
| 508 | + assert response == access.ACCESS_GRANTED |
| 509 | + else: |
| 510 | + assert isinstance(response, access_response.StartDateError) |
| 511 | + assert response.to_json()["error_code"] is not None |
| 512 | + assert str(self.DATES[start]) in response.developer_message |
| 513 | + |
468 | 514 | def test__has_access_course_can_enroll(self): |
469 | 515 | yesterday = datetime.datetime.now(pytz.utc) - datetime.timedelta(days=1) |
470 | 516 | tomorrow = datetime.datetime.now(pytz.utc) + datetime.timedelta(days=1) |
|
0 commit comments