Files
zulip/zerver/tests/test_migrations.py
Harshit Bansal b553507412 subscriptions: Migrate notification setting defaults model.
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.
2019-05-08 17:45:10 -07:00

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)