# These are tests for Zulip's database migrations. System documented at: # https://zulip.readthedocs.io/en/latest/subsystems/schema-migrations.html # # You can also read # https://www.caktusgroup.com/blog/2016/02/02/writing-unit-tests-django-migrations/ # to get a tutorial on the framework that inspired this feature. from django.db.migrations.state import StateApps from zerver.lib.test_classes import MigrationsTestCase from zerver.lib.test_helpers import use_db_models from zerver.models import get_stream # Important note: These tests are very expensive, and details of # Django's database transaction model mean it does not super work to # have a lot of migrations tested in this file at once; so we usually # delete the old migration tests when adding a new one, so this file # always has a single migration test in it as an example. # # The error you get with multiple similar tests doing migrations on # the same table is this (table name may vary): # # django.db.utils.OperationalError: cannot ALTER TABLE # "zerver_subscription" because it has pending trigger events # # As a result, we generally mark these tests as skipped once they have # been tested for a migration being merged. class SubsNotificationSettingsTestCase(MigrationsTestCase): # nocoverage __unittest_skip__ = True migrate_from = '0220_subscription_notification_settings' migrate_to = '0221_subscription_notifications_data_migration' RECIPIENT_PERSONAL = 1 RECIPIENT_STREAM = 2 @use_db_models def setUpBeforeMigration(self, apps: StateApps) -> None: Recipient = apps.get_model('zerver', 'Recipient') Subscription = apps.get_model('zerver', 'Subscription') iago = self.example_user('iago') iago.enable_stream_desktop_notifications = True iago.enable_stream_audible_notifications = False iago.enable_desktop_notifications = True iago.enable_online_push_notifications = True iago.enable_sounds = False iago.save() stream_name = 'Denmark' denmark = get_stream(stream_name, iago.realm) denmark_recipient = Recipient.objects.get(type=self.RECIPIENT_STREAM, type_id=denmark.id) denmark_sub = Subscription.objects.get(user_profile=iago, recipient=denmark_recipient) denmark_sub.desktop_notifications = False denmark_sub.audible_notifications = False denmark_sub.save(update_fields=['desktop_notifications', 'audible_notifications']) iago_recipient = Recipient.objects.get(type=self.RECIPIENT_PERSONAL, type_id=iago.id) iago_sub = Subscription.objects.get(user_profile=iago, recipient=iago_recipient) iago_sub.desktop_notifications = False iago_sub.audible_notifications = False iago_sub.push_notifications = True iago_sub.save( update_fields=['desktop_notifications', 'audible_notifications', 'push_notifications'] ) def test_subs_migrated(self) -> None: UserProfile = self.apps.get_model('zerver', 'UserProfile') Recipient = self.apps.get_model('zerver', 'Recipient') Realm = self.apps.get_model('zerver', 'Realm') Subscription = self.apps.get_model('zerver', 'Subscription') Stream = self.apps.get_model('zerver', 'Stream') realm = Realm.objects.get(string_id='zulip') iago = UserProfile.objects.get(email='iago@zulip.com', realm=realm) stream_name = 'Denmark' denmark = Stream.objects.get(realm=iago.realm, name=stream_name) denmark_recipient = Recipient.objects.get(type=self.RECIPIENT_STREAM, type_id=denmark.id) denmark_sub = Subscription.objects.get(user_profile=iago, recipient=denmark_recipient) self.assertEqual(denmark_sub.desktop_notifications, False) self.assertIsNone(denmark_sub.audible_notifications) # Zulip ignores subscription's notification related settings for PMs so don't migrate them. iago_recipient = Recipient.objects.get(type=self.RECIPIENT_PERSONAL, type_id=iago.id) iago_sub = Subscription.objects.get(user_profile=iago, recipient=iago_recipient) self.assertEqual(iago_sub.desktop_notifications, False) self.assertEqual(iago_sub.audible_notifications, False) self.assertEqual(iago_sub.push_notifications, True)