mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-30 19:43:47 +00:00 
			
		
		
		
	This commit migrates the Subscription's notification fields from a BooleanField to a NullBooleanField where a value of None means to inherit the value from user's profile. Also includes a migrations to set the corresponding settings to None if they match the user profile's values. This migration helps us in getting rid of the weird "Apply to all" widget that we offered on subscription settings page. The mobile apps can't handle None appearing as the stream-level notification settings, so for backwards-compatibility we arrange to only send True/False to the mobile apps by applying those defaults server-side. We introduce a notification_settings_null value within a client_capabilities structure that newer versions of the mobile apps can use to request the new model. This mobile compatibility code is pretty effectively tested by the existing test_events tests for the subscriptions subsystem.
		
			
				
	
	
		
			83 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			83 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # 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 zerver.lib.test_classes import MigrationsTestCase
 | |
| from zerver.lib.test_helpers import use_db_models
 | |
| from django.db.migrations.state import StateApps
 | |
| 
 | |
| 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
 | |
| 
 | |
| class SubsNotificationSettingsTestCase(MigrationsTestCase):
 | |
| 
 | |
|     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)
 |