Skip to content

Commit ab1b229

Browse files
committed
refactor: update test assertions for waffle flag migration logic
1 parent 8222406 commit ab1b229

1 file changed

Lines changed: 110 additions & 32 deletions

File tree

openedx_authz/tests/test_handlers.py

Lines changed: 110 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ def test_course_scope_migration_depends_on_override_choice(
367367
)
368368
else:
369369
mock_run.assert_not_called()
370-
mock_logger.info.assert_called_once_with("No change in waffle flag, skipping migration")
370+
mock_logger.info.assert_called_once_with("No effective change in waffle flag behavior, skipping migration")
371371

372372
@data(
373373
(WAFFLE_OVERRIDE_FORCE_ON, MigrationType.FORWARD, True),
@@ -402,7 +402,7 @@ def test_org_scope_migration_depends_on_override_choice(
402402
)
403403
else:
404404
mock_run.assert_not_called()
405-
mock_logger.info.assert_called_once_with("No change in waffle flag, skipping migration")
405+
mock_logger.info.assert_called_once_with("No effective change in waffle flag behavior, skipping migration")
406406

407407
def test_org_scope_passes_excluded_course_ids_when_course_overrides_oppose_org(self, mock_run):
408408
"""Org forward migration excludes active course rows whose override opposes force-on."""
@@ -467,7 +467,7 @@ def test_skips_when_previous_enabled_record_has_same_override_choice(
467467
trigger_course_authoring_migration(sender_model, instance, scope_key)
468468

469469
mock_run.assert_not_called()
470-
mock_logger.info.assert_called_once_with("No change in waffle flag, skipping migration")
470+
mock_logger.info.assert_called_once_with("No effective change in waffle flag behavior, skipping migration")
471471

472472
@data(
473473
(
@@ -538,76 +538,154 @@ def test_runs_when_previous_record_disabled_even_if_same_override_choice(
538538

539539

540540
class TestGetMigrationType(TestCase):
541-
"""Tests for ``get_migration_type``."""
541+
"""Tests for ``get_migration_type`` (effective state includes ``global_flag_enabled``)."""
542542

543543
def create_mock_record(self, enabled: bool, choice: str):
544544
"""Helper to create a mock record object."""
545545
return SimpleNamespace(enabled=enabled, override_choice=choice)
546546

547-
def test_creation_new_record_enabled(self):
548-
"""Case: No previous record, current is enabled and forced on."""
547+
def test_creation_new_record_enabled_global_off(self):
548+
"""No prior row: enabling FORCE_ON migrates forward when the global flag is off."""
549549
current = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_ON)
550550

551-
result = get_migration_type(current, None)
551+
result = get_migration_type(current, None, global_flag_enabled=False)
552552

553553
self.assertEqual(result, MigrationType.FORWARD)
554554

555-
def test_creation_new_record_disabled(self):
556-
"""Case: No previous record, current is disabled."""
557-
current = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_ON)
555+
def test_creation_new_record_enabled_global_on(self):
556+
"""No prior row: FORCE_ON is already the effective state when global is on — no migration."""
557+
current = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_ON)
558558

559-
result = get_migration_type(current, None)
559+
result = get_migration_type(current, None, global_flag_enabled=True)
560560

561561
self.assertIsNone(result)
562562

563-
def test_no_change_stay_active(self):
564-
"""Case: Both records are enabled and forced on (No change)."""
563+
def test_creation_new_record_disabled_matches_global(self):
564+
"""Disabled row defers to global, no previous row means same effective state as global."""
565+
current = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_ON)
566+
567+
self.assertIsNone(get_migration_type(current, None, global_flag_enabled=False))
568+
self.assertIsNone(get_migration_type(current, None, global_flag_enabled=True))
569+
570+
def test_no_change_stay_active_force_on(self):
571+
"""Both enabled FORCE_ON — effective stays on."""
565572
prev = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_ON)
566573
curr = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_ON)
567574

568-
result = get_migration_type(curr, prev)
569-
570-
self.assertIsNone(result)
575+
self.assertIsNone(get_migration_type(curr, prev, global_flag_enabled=False))
576+
self.assertIsNone(get_migration_type(curr, prev, global_flag_enabled=True))
571577

578+
def test_no_change_stay_active_force_off(self):
579+
"""Both enabled FORCE_OFF — effective stays off."""
572580
prev = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_OFF)
573581
curr = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_OFF)
574582

575-
result = get_migration_type(curr, prev)
576-
577-
self.assertIsNone(result)
583+
self.assertIsNone(get_migration_type(curr, prev, global_flag_enabled=False))
584+
self.assertIsNone(get_migration_type(curr, prev, global_flag_enabled=True))
578585

579586
def test_no_change_stay_inactive(self):
580-
"""Case: Both records are disabled (No change)."""
587+
"""Both rows disabled — both follow global, so no effective change."""
581588
prev = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_ON)
582589
curr = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_ON)
583590

584-
result = get_migration_type(curr, prev)
591+
self.assertIsNone(get_migration_type(curr, prev, global_flag_enabled=False))
592+
self.assertIsNone(get_migration_type(curr, prev, global_flag_enabled=True))
585593

586-
self.assertIsNone(result)
587-
588-
def test_transition_to_forward(self):
589-
"""Case: Transition from disabled to enabled/forced on."""
594+
def test_transition_disabled_to_enabled_force_on_global_off(self):
595+
"""Row becomes active FORCE_ON while global is off — effective off → on."""
590596
prev = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_ON)
591597
curr = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_ON)
592598

593-
result = get_migration_type(curr, prev)
599+
result = get_migration_type(curr, prev, global_flag_enabled=False)
594600

595601
self.assertEqual(result, MigrationType.FORWARD)
596602

597-
def test_transition_to_rollback(self):
598-
"""Case: Transition from enabled/forced on to disabled."""
603+
def test_transition_disabled_to_enabled_force_on_global_on(self):
604+
"""Previously inactive row followed global (on), turning FORCE_ON on stays on — no op."""
605+
prev = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_ON)
606+
curr = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_ON)
607+
608+
result = get_migration_type(curr, prev, global_flag_enabled=True)
609+
610+
self.assertIsNone(result)
611+
612+
def test_transition_enabled_force_on_to_disabled_global_off(self):
613+
"""FORCE_ON row disabled, global off — effective on → off (rollback)."""
599614
prev = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_ON)
600615
curr = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_ON)
601616

602-
result = get_migration_type(curr, prev)
617+
result = get_migration_type(curr, prev, global_flag_enabled=False)
603618

604619
self.assertEqual(result, MigrationType.ROLLBACK)
605620

606-
def test_change_choice_to_rollback(self):
607-
"""Case: Enabled remains True, but choice changes from forced to something else."""
621+
def test_transition_enabled_force_on_to_disabled_global_on(self):
622+
"""FORCE_ON row disabled but global still on — effective stays on, no migration."""
623+
prev = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_ON)
624+
curr = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_ON)
625+
626+
result = get_migration_type(curr, prev, global_flag_enabled=True)
627+
628+
self.assertIsNone(result)
629+
630+
def test_change_choice_force_on_to_force_off(self):
631+
"""Enabled FORCE_ON → FORCE_OFF — effective on → off."""
608632
prev = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_ON)
609633
curr = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_OFF)
610634

611-
result = get_migration_type(curr, prev)
635+
self.assertEqual(
636+
get_migration_type(curr, prev, global_flag_enabled=False),
637+
MigrationType.ROLLBACK,
638+
)
639+
self.assertEqual(
640+
get_migration_type(curr, prev, global_flag_enabled=True),
641+
MigrationType.ROLLBACK,
642+
)
643+
644+
def test_change_choice_force_off_to_force_on(self):
645+
"""Enabled FORCE_OFF → FORCE_ON — effective off → on."""
646+
prev = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_OFF)
647+
curr = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_ON)
648+
649+
self.assertEqual(
650+
get_migration_type(curr, prev, global_flag_enabled=False),
651+
MigrationType.FORWARD,
652+
)
653+
self.assertEqual(
654+
get_migration_type(curr, prev, global_flag_enabled=True),
655+
MigrationType.FORWARD,
656+
)
657+
658+
def test_remove_force_off_override_when_global_on(self):
659+
"""Deleting FORCE_OFF behavior by disabling row restores global on — forward migration."""
660+
prev = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_OFF)
661+
curr = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_OFF)
662+
663+
result = get_migration_type(curr, prev, global_flag_enabled=True)
664+
665+
self.assertEqual(result, MigrationType.FORWARD)
666+
667+
def test_remove_force_off_override_when_global_off(self):
668+
"""Disabling FORCE_OFF row while global off — still off, no migration."""
669+
prev = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_OFF)
670+
curr = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_OFF)
671+
672+
result = get_migration_type(curr, prev, global_flag_enabled=False)
673+
674+
self.assertIsNone(result)
675+
676+
def test_add_force_off_override_when_global_on(self):
677+
"""New active FORCE_OFF while global on — effective on → off."""
678+
prev = self.create_mock_record(False, WAFFLE_OVERRIDE_FORCE_OFF)
679+
curr = self.create_mock_record(True, WAFFLE_OVERRIDE_FORCE_OFF)
680+
681+
result = get_migration_type(curr, prev, global_flag_enabled=True)
612682

613683
self.assertEqual(result, MigrationType.ROLLBACK)
684+
685+
def test_unknown_override_choice_follows_global(self):
686+
"""Non on/off choice falls back to global — toggling only matters vs that baseline."""
687+
prev = self.create_mock_record(True, "unset")
688+
curr = self.create_mock_record(True, "unset")
689+
690+
self.assertIsNone(get_migration_type(curr, prev, global_flag_enabled=False))
691+
self.assertIsNone(get_migration_type(curr, prev, global_flag_enabled=True))

0 commit comments

Comments
 (0)