1010from django .conf import settings
1111from django .contrib .auth .models import AnonymousUser , User # lint-amnesty, pylint: disable=imported-auth-user
1212from django .core .cache import cache
13+ from django .db import connection
1314from django .db .models .functions import Lower
1415from django .test import TestCase , override_settings
16+ from django .test .utils import CaptureQueriesContext
1517from edx_toggles .toggles .testutils import override_waffle_flag
1618from freezegun import freeze_time
1719from opaque_keys .edx .keys import CourseKey
@@ -740,24 +742,21 @@ def test_retire_recovery_email(self):
740742 AccountRecoveryFactory (user = user , secondary_email = 'recovery@example.com' )
741743 assert len (AccountRecovery .objects .filter (user_id = user .id )) == 1
742744
743- from django .db .models .signals import pre_delete
744- saved_emails = []
745-
746- def capture_pre_delete (sender , instance , ** kwargs ):
747- saved_emails .append (instance .secondary_email )
748-
749- pre_delete .connect (capture_pre_delete , sender = AccountRecovery )
750- try :
745+ with CaptureQueriesContext (connection ) as ctx :
751746 AccountRecovery .retire_recovery_email (user_id = user .id )
752- finally :
753- pre_delete .disconnect (capture_pre_delete , sender = AccountRecovery )
747+
748+ sql_list = [query ['sql' ].upper () for query in ctx ]
749+ table_name = 'AUTH_ACCOUNTRECOVERY'
750+ update_indices = [i for i , sql in enumerate (sql_list ) if 'UPDATE' in sql and table_name in sql ]
751+ delete_indices = [i for i , sql in enumerate (sql_list ) if 'DELETE' in sql and table_name in sql ]
752+ assert update_indices , f'Expected at least one UPDATE on { table_name } '
753+ assert delete_indices , f'Expected at least one DELETE on { table_name } '
754+ assert any (update_idx < delete_idx for update_idx in update_indices for delete_idx in delete_indices ), (
755+ 'Expected at least one UPDATE to precede at least one DELETE'
756+ )
754757
755758 # Record must be gone
756759 assert len (AccountRecovery .objects .filter (user_id = user .id )) == 0
757- # Redacted value was saved (not the original) before deletion
758- assert len (saved_emails ) == 1
759- assert saved_emails [0 ] != 'recovery@example.com'
760- assert 'example.com' not in saved_emails [0 ]
761760
762761
763762class TestPendingSecondaryEmailChange (TestCase ):
@@ -773,24 +772,21 @@ def test_redact_and_delete_pending_secondary_email(self):
773772 )
774773 assert len (PendingSecondaryEmailChange .objects .filter (user_id = user .id )) == 1
775774
776- from django .db .models .signals import pre_delete
777- saved_emails = []
778-
779- def capture_pre_delete (sender , instance , ** kwargs ):
780- saved_emails .append (instance .new_secondary_email )
781-
782- pre_delete .connect (capture_pre_delete , sender = PendingSecondaryEmailChange )
783- try :
775+ with CaptureQueriesContext (connection ) as ctx :
784776 PendingSecondaryEmailChange .redact_and_delete_pending_secondary_email (user_id = user .id )
785- finally :
786- pre_delete .disconnect (capture_pre_delete , sender = PendingSecondaryEmailChange )
777+
778+ sql_list = [query ['sql' ].upper () for query in ctx ]
779+ table_name = 'STUDENT_PENDINGSECONDARYEMAILCHANGE'
780+ update_indices = [i for i , sql in enumerate (sql_list ) if 'UPDATE' in sql and table_name in sql ]
781+ delete_indices = [i for i , sql in enumerate (sql_list ) if 'DELETE' in sql and table_name in sql ]
782+ assert update_indices , f'Expected at least one UPDATE on { table_name } '
783+ assert delete_indices , f'Expected at least one DELETE on { table_name } '
784+ assert any (update_idx < delete_idx for update_idx in update_indices for delete_idx in delete_indices ), (
785+ 'Expected at least one UPDATE to precede at least one DELETE'
786+ )
787787
788788 # Record must be gone
789789 assert len (PendingSecondaryEmailChange .objects .filter (user_id = user .id )) == 0
790- # Redacted value was saved (not the original) before deletion
791- assert len (saved_emails ) == 1
792- assert saved_emails [0 ] != 'new-secondary@example.com'
793- assert 'example.com' not in saved_emails [0 ]
794790
795791 def test_redact_and_delete_pending_secondary_email_when_no_record (self ):
796792 """Assert retirement cleanup returns True when no pending secondary row exists."""
0 commit comments