models: Rename Subscription.in_home_view field to is_muted.

This renames Subscription.in_home_view field to is_muted, for greater
clarity as to what it does just from seeing the setting name, without
having to look it up.

Also disabled an obsolete test_migrations test.

Fixes #10042.
This commit is contained in:
Roman Godov 2018-08-03 00:46:05 +03:00 committed by Tim Abbott
parent 5ec8f6e812
commit a50824e031
15 changed files with 159 additions and 29 deletions

View File

@ -130,7 +130,7 @@ class Command(BaseCommand):
user_profile__in=user_profiles, active=True)
# Streams not in home view
non_home_view = active_user_subs.filter(in_home_view=False).values(
non_home_view = active_user_subs.filter(is_muted=True).values(
"user_profile").annotate(count=Count("user_profile"))
print("%d users have %d streams not in home view" % (
len(non_home_view), sum([elt["count"] for elt in non_home_view])))

View File

@ -978,7 +978,7 @@ def get_recipient_info(recipient: Recipient,
'email_notifications',
'user_profile_email_notifications',
'user_profile_push_notifications',
'in_home_view',
'is_muted',
).order_by('user_profile_id')
message_to_user_ids = [
@ -990,7 +990,7 @@ def get_recipient_info(recipient: Recipient,
# This implements the structure that the UserProfile stream notification settings
# are defaults, which can be overridden by the stream-level settings (if those
# values are not null).
if not row['in_home_view']:
if row['is_muted']:
return False
if row[setting] is not None:
return row[setting]
@ -2662,7 +2662,8 @@ def notify_subscriptions_added(user_profile: UserProfile,
# Send a notification to the user who subscribed.
payload = [dict(name=stream.name,
stream_id=stream.id,
in_home_view=subscription.in_home_view,
in_home_view=not subscription.is_muted,
is_muted=subscription.is_muted,
invite_only=stream.invite_only,
is_announcement_only=stream.is_announcement_only,
color=subscription.color,
@ -3090,16 +3091,30 @@ def log_subscription_property_change(user_email: str, stream_name: str, property
def do_change_subscription_property(user_profile: UserProfile, sub: Subscription,
stream: Stream, property_name: str, value: Any
) -> None:
setattr(sub, property_name, value)
sub.save(update_fields=[property_name])
log_subscription_property_change(user_profile.email, stream.name,
property_name, value)
database_property_name = property_name
event_property_name = property_name
database_value = value
event_value = value
# For this property, is_muted is used in the database, but
# in_home_view in the API, since we haven't migrated the events
# API to the new name yet.
if property_name == "in_home_view":
database_property_name = "is_muted"
database_value = not value
if property_name == "is_muted":
event_property_name = "in_home_view"
event_value = not value
setattr(sub, database_property_name, database_value)
sub.save(update_fields=[database_property_name])
log_subscription_property_change(user_profile.email, stream.name,
database_property_name, database_value)
event = dict(type="subscription",
op="update",
email=user_profile.email,
property=property_name,
value=value,
property=event_property_name,
value=event_value,
stream_id=stream.id,
name=stream.name)
send_event(user_profile.realm, event, [user_profile.id])
@ -4525,7 +4540,7 @@ def get_web_public_subs(realm: Realm) -> SubHelperT:
subscribed = [
{'name': stream.name,
'in_home_view': True,
'is_muted': False,
'invite_only': False,
'is_announcement_only': stream.is_announcement_only,
'color': get_next_color(),
@ -4552,7 +4567,7 @@ def get_web_public_subs(realm: Realm) -> SubHelperT:
def gather_subscriptions_helper(user_profile: UserProfile,
include_subscribers: bool=True) -> SubHelperT:
sub_dicts = get_stream_subscriptions_for_user(user_profile).values(
"recipient_id", "in_home_view", "color", "desktop_notifications",
"recipient_id", "is_muted", "color", "desktop_notifications",
"audible_notifications", "push_notifications", "email_notifications",
"active", "pin_to_top"
).order_by("recipient_id")
@ -4628,7 +4643,8 @@ def gather_subscriptions_helper(user_profile: UserProfile,
subscribers = None
stream_dict = {'name': stream["name"],
'in_home_view': sub["in_home_view"],
'in_home_view': not sub["is_muted"],
'is_muted': sub["is_muted"],
'invite_only': stream["invite_only"],
'is_announcement_only': stream["is_announcement_only"],
'color': sub["color"],
@ -4683,7 +4699,6 @@ def gather_subscriptions_helper(user_profile: UserProfile,
if subscribers is not None:
stream_dict['subscribers'] = subscribers
never_subscribed.append(stream_dict)
return (sorted(subscribed, key=lambda x: x['name']),
sorted(unsubscribed, key=lambda x: x['name']),
sorted(never_subscribed, key=lambda x: x['name']))

View File

@ -179,7 +179,7 @@ def handle_digest_email(user_profile_id: int, cutoff: float,
user_profile=user_profile,
recipient__type=Recipient.STREAM,
active=True,
in_home_view=True).values_list('recipient__type_id', flat=True)
is_muted=False).values_list('recipient__type_id', flat=True)
if not user_profile.long_term_idle:
stream_ids = home_view_streams

View File

@ -166,7 +166,7 @@ def fix_pre_pointer(cursor: CursorObj, user_profile: UserProfile) -> None:
WHERE (
zerver_subscription.user_profile_id = '%s' AND
zerver_recipient.type = 2 AND
zerver_subscription.in_home_view AND
(NOT zerver_subscription.is_muted) AND
zerver_subscription.active
)
'''

View File

@ -737,7 +737,7 @@ def get_inactive_recipient_ids(user_profile: UserProfile) -> List[int]:
def get_muted_stream_ids(user_profile: UserProfile) -> List[int]:
rows = get_stream_subscriptions_for_user(user_profile).filter(
active=True,
in_home_view=False,
is_muted=True,
).values(
'recipient__type_id'
)

View File

@ -36,7 +36,7 @@ def get_muted_streams(user_profile: UserProfile, stream_ids: Set[int]) -> Set[in
rows = Subscription.objects.filter(
user_profile=user_profile,
recipient__type_id__in=stream_ids,
in_home_view=False,
is_muted=True,
).values(
'recipient__type_id'
)

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.14 on 2018-08-10 16:04
from __future__ import unicode_literals
from django.db import migrations, models
from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor
from django.db.migrations.state import StateApps
from django.db.models import Case, Value, When
def set_initial_value_for_is_muted(apps: StateApps, schema_editor: DatabaseSchemaEditor) -> None:
Subscription = apps.get_model("zerver", "Subscription")
Subscription.objects.update(is_muted=Case(
When(in_home_view=True, then=Value(False)),
When(in_home_view=False, then=Value(True)),
))
def reverse_code(apps: StateApps, schema_editor: DatabaseSchemaEditor) -> None:
Subscription = apps.get_model("zerver", "Subscription")
Subscription.objects.update(in_home_view=Case(
When(is_muted=True, then=Value(False)),
When(is_muted=False, then=Value(True)),
))
class Migration(migrations.Migration):
atomic = False
dependencies = [
('zerver', '0222_userprofile_fluid_layout_width'),
]
operations = [
migrations.AddField(
model_name='subscription',
name='is_muted',
field=models.NullBooleanField(default=False),
),
migrations.RunPython(
set_initial_value_for_is_muted,
reverse_code=reverse_code
),
migrations.RemoveField(
model_name='subscription',
name='in_home_view',
),
]

View File

@ -1880,8 +1880,8 @@ class Subscription(models.Model):
# resubscribes.
active = models.BooleanField(default=True) # type: bool
# Whether the stream is muted. TODO: Remove to !muted.
in_home_view = models.NullBooleanField(default=True) # type: Optional[bool]
# Whether this user had muted this stream.
is_muted = models.NullBooleanField(default=False) # type: Optional[bool]
DEFAULT_STREAM_COLOR = u"#c2c2c2"
color = models.CharField(max_length=10, default=DEFAULT_STREAM_COLOR) # type: str

View File

@ -310,7 +310,7 @@ class MissedMessageNotificationsTest(ZulipTestCase):
'email_notifications': True})
client_descriptor.event_queue.pop()
self.assertTrue(client_descriptor.event_queue.empty())
change_subscription_properties(user_profile, stream, sub, {'in_home_view': False})
change_subscription_properties(user_profile, stream, sub, {'is_muted': True})
msg_id = self.send_stream_message(self.example_email("iago"), "Denmark",
content="what's up everyone?")
with mock.patch("zerver.tornado.event_queue.maybe_enqueue_notifications") as mock_enqueue:
@ -326,7 +326,7 @@ class MissedMessageNotificationsTest(ZulipTestCase):
# Clean up the state we just changed (not necessary unless we add more test code below)
change_subscription_properties(user_profile, stream, sub,
{'push_notifications': True,
'in_home_view': True})
'is_muted': False})
class FileReloadLogicTest(ZulipTestCase):
def test_persistent_queue_filename(self) -> None:

View File

@ -2382,6 +2382,7 @@ class EventsRegisterTest(ZulipTestCase):
('email_address', check_string),
('invite_only', check_bool),
('is_announcement_only', check_bool),
('is_muted', check_bool),
('in_home_view', check_bool),
('name', check_string),
('audible_notifications', check_none_or(check_bool)),
@ -2734,7 +2735,7 @@ class GetUnreadMsgsTest(ZulipTestCase):
user_profile=user_profile,
recipient=recipient
)
subscription.in_home_view = False
subscription.is_muted = True
subscription.save()
def mute_topic(self, user_profile: UserProfile, stream_name: str,

View File

@ -67,7 +67,7 @@ def mute_stream(realm: Realm, user_profile: str, stream_name: str) -> None:
stream = get_stream(stream_name, realm)
recipient = get_stream_recipient(stream.id)
subscription = Subscription.objects.get(recipient=recipient, user_profile=user_profile)
subscription.in_home_view = False
subscription.is_muted = True
subscription.save()
def first_visible_id_as(message_id: int) -> Any:

View File

@ -1585,6 +1585,66 @@ class SubscriptionPropertiesTest(ZulipTestCase):
self.assertIsNotNone(updated_sub)
self.assertEqual(updated_sub.pin_to_top, new_pin_to_top)
def test_change_is_muted(self) -> None:
test_user = self.example_user('hamlet')
test_email = test_user.email
self.login(test_email)
subs = gather_subscriptions(test_user)[0]
sub = Subscription.objects.get(recipient__type=Recipient.STREAM,
recipient__type_id=subs[0]["stream_id"],
user_profile=test_user)
self.assertEqual(sub.is_muted, False)
events = [] # type: List[Mapping[str, Any]]
property_name = "is_muted"
with tornado_redirected_to_list(events):
result = self.api_post(test_email, "/api/v1/users/me/subscriptions/properties",
{"subscription_data": ujson.dumps([{"property": property_name,
"value": True,
"stream_id": subs[0]["stream_id"]}])})
self.assert_json_success(result)
self.assert_length(events, 1)
self.assertEqual(events[0]['event']['property'], 'in_home_view')
self.assertEqual(events[0]['event']['value'], False)
sub = Subscription.objects.get(recipient__type=Recipient.STREAM,
recipient__type_id=subs[0]["stream_id"],
user_profile=test_user)
self.assertEqual(sub.is_muted, True)
events = []
legacy_property_name = 'in_home_view'
with tornado_redirected_to_list(events):
result = self.api_post(test_email, "/api/v1/users/me/subscriptions/properties",
{"subscription_data": ujson.dumps([{"property": legacy_property_name,
"value": True,
"stream_id": subs[0]["stream_id"]}])})
self.assert_json_success(result)
self.assert_length(events, 1)
self.assertEqual(events[0]['event']['property'], 'in_home_view')
self.assertEqual(events[0]['event']['value'], True)
self.assert_json_success(result)
sub = Subscription.objects.get(recipient__type=Recipient.STREAM,
recipient__type_id=subs[0]["stream_id"],
user_profile=test_user)
self.assertEqual(sub.is_muted, False)
events = []
with tornado_redirected_to_list(events):
result = self.api_post(test_email, "/api/v1/users/me/subscriptions/properties",
{"subscription_data": ujson.dumps([{"property": legacy_property_name,
"value": False,
"stream_id": subs[0]["stream_id"]}])})
self.assert_json_success(result)
self.assert_length(events, 1)
self.assertEqual(events[0]['event']['property'], 'in_home_view')
self.assertEqual(events[0]['event']['value'], False)
sub = Subscription.objects.get(recipient__type=Recipient.STREAM,
recipient__type_id=subs[0]["stream_id"],
user_profile=test_user)
self.assertEqual(sub.is_muted, True)
def test_set_subscription_property_incorrect(self) -> None:
"""
Trying to set a property incorrectly returns a JSON error.
@ -1594,6 +1654,14 @@ class SubscriptionPropertiesTest(ZulipTestCase):
self.login(test_email)
subs = gather_subscriptions(test_user)[0]
property_name = "is_muted"
result = self.api_post(test_email, "/api/v1/users/me/subscriptions/properties",
{"subscription_data": ujson.dumps([{"property": property_name,
"value": "bad",
"stream_id": subs[0]["stream_id"]}])})
self.assert_json_error(result,
'%s is not a boolean' % (property_name,))
property_name = "in_home_view"
result = self.api_post(test_email, "/api/v1/users/me/subscriptions/properties",
{"subscription_data": ujson.dumps([{"property": property_name,
@ -1648,7 +1716,7 @@ class SubscriptionPropertiesTest(ZulipTestCase):
stream_id = 1000
result = self.api_post(test_email, "/api/v1/users/me/subscriptions/properties",
{"subscription_data": ujson.dumps([{"property": "in_home_view",
{"subscription_data": ujson.dumps([{"property": "is_muted",
"stream_id": stream_id,
"value": False}])})
self.assert_json_error(result, "Invalid stream id")
@ -1746,7 +1814,7 @@ class SubscriptionRestApiTest(ZulipTestCase):
test_email = self.example_email("hamlet")
self.login(test_email)
result = self.api_patch(test_email, "/api/v1/users/me/subscriptions/121",
{'property': 'in_home_view', 'value': 'somevalue'})
{'property': 'is_muted', 'value': 'somevalue'})
self.assert_json_error(result,
"Invalid stream id")

View File

@ -388,7 +388,7 @@ class FixUnreadTests(ZulipTestCase):
user_profile=user,
recipient=recipient
)
subscription.in_home_view = False
subscription.is_muted = True
subscription.save()
def mute_topic(stream_name: str, topic_name: str) -> None:

View File

@ -567,7 +567,7 @@ def exclude_muting_conditions(user_profile: UserProfile,
rows = Subscription.objects.filter(
user_profile=user_profile,
active=True,
in_home_view=False,
is_muted=True,
recipient__type=Recipient.STREAM
).values('recipient_id')
muted_recipient_ids = [row['recipient_id'] for row in rows]

View File

@ -549,10 +549,11 @@ def update_subscription_properties_backend(
Requests are of the form:
[{"stream_id": "1", "property": "in_home_view", "value": False},
[{"stream_id": "1", "property": "is_muted", "value": False},
{"stream_id": "1", "property": "color", "value": "#c2c2c2"}]
"""
property_converters = {"color": check_color, "in_home_view": check_bool,
"is_muted": check_bool,
"desktop_notifications": check_bool,
"audible_notifications": check_bool,
"push_notifications": check_bool,