From 02a1b2e26bd2cd9480da41dd8498d7b3c8cd5bc4 Mon Sep 17 00:00:00 2001 From: Yashashvi Dave Date: Thu, 2 May 2019 23:13:27 +0530 Subject: [PATCH] server events: Add realm-time-sync event to update stream privacy. Add event to update stream settings whenever stream privacy is changed accordingly. Fixes #9470 --- frontend_tests/node_tests/stream_data.js | 15 ++++++++++ frontend_tests/node_tests/stream_events.js | 26 +++++++++++++++++ static/js/server_events_dispatch.js | 1 + static/js/stream_edit.js | 6 +--- static/js/stream_events.js | 9 ++++++ zerver/lib/actions.py | 19 +++++++++++++ zerver/tests/test_events.py | 33 ++++++++++++++++++++++ 7 files changed, 104 insertions(+), 5 deletions(-) diff --git a/frontend_tests/node_tests/stream_data.js b/frontend_tests/node_tests/stream_data.js index 9ad05d146d..a0e99bb740 100644 --- a/frontend_tests/node_tests/stream_data.js +++ b/frontend_tests/node_tests/stream_data.js @@ -393,6 +393,8 @@ run_test('stream_settings', () => { color: 'amber', subscribed: true, invite_only: true, + history_public_to_subscribers: true, + is_announcement_only: true, }; stream_data.clear_subscriptions(); stream_data.add_sub(cinnamon.name, cinnamon); @@ -412,6 +414,19 @@ run_test('stream_settings', () => { assert.equal(sub_rows[1].invite_only, false); assert.equal(sub_rows[2].invite_only, false); + assert.equal(sub_rows[0].history_public_to_subscribers, true); + assert.equal(sub_rows[0].is_announcement_only, true); + + var sub = stream_data.get_sub('a'); + stream_data.update_stream_privacy(sub, { + invite_only: false, + history_public_to_subscribers: false, + }); + stream_data.update_stream_announcement_only(sub, false); + stream_data.update_calculated_fields(sub); + assert.equal(sub.invite_only, false); + assert.equal(sub.history_public_to_subscribers, false); + assert.equal(sub.is_announcement_only, false); }); run_test('default_stream_names', () => { diff --git a/frontend_tests/node_tests/stream_events.js b/frontend_tests/node_tests/stream_events.js index 37d46c8b45..c3eea4de8d 100644 --- a/frontend_tests/node_tests/stream_events.js +++ b/frontend_tests/node_tests/stream_events.js @@ -128,6 +128,32 @@ run_test('update_property', () => { assert.equal(checkbox.prop('checked'), true); }); + // Test stream privacy change event + with_overrides(function (override) { + global.with_stub(function (stub) { + override('subs.update_stream_privacy', stub.f); + stream_events.update_property(1, 'invite_only', true, { + history_public_to_subscribers: true, + }); + var args = stub.get_args('sub', 'val'); + assert.equal(args.sub.stream_id, 1); + assert.deepEqual(args.val, { + invite_only: true, + history_public_to_subscribers: true, + }); + }); + }); + + // Test stream is_announcement_only change event + with_overrides(function (override) { + global.with_stub(function (stub) { + override('subs.update_stream_announcement_only', stub.f); + stream_events.update_property(1, 'is_announcement_only', true); + var args = stub.get_args('sub', 'val'); + assert.equal(args.sub.stream_id, 1); + assert.equal(args.val, true); + }); + }); }); run_test('marked_subscribed', () => { diff --git a/static/js/server_events_dispatch.js b/static/js/server_events_dispatch.js index a8021277f0..2fdc991238 100644 --- a/static/js/server_events_dispatch.js +++ b/static/js/server_events_dispatch.js @@ -268,6 +268,7 @@ exports.dispatch_normal_event = function dispatch_normal_event(event) { event.value, { rendered_description: event.rendered_description, + history_public_to_subscribers: event.history_public_to_subscribers, }); settings_streams.update_default_streams_table(); } else if (event.op === 'create') { diff --git a/static/js/stream_edit.js b/static/js/stream_edit.js index 95c4e627e0..b9115525c3 100644 --- a/static/js/stream_edit.js +++ b/static/js/stream_edit.js @@ -329,12 +329,8 @@ function change_stream_privacy(e) { url: "/json/streams/" + stream_id, data: data, success: function () { - subs.update_stream_privacy(sub, { - invite_only: invite_only, - history_public_to_subscribers: history_public_to_subscribers, - }); - subs.update_stream_announcement_only(sub, is_announcement_only); $("#stream_privacy_modal").remove(); + // The rest will be done by update stream event we will get. }, error: function () { $("#change-stream-privacy-button").text(i18n.t("Try again")); diff --git a/static/js/stream_events.js b/static/js/stream_events.js index bd682a894d..b9da3dc384 100644 --- a/static/js/stream_events.js +++ b/static/js/stream_events.js @@ -74,6 +74,15 @@ exports.update_property = function (stream_id, property, value, other_values) { update_stream_pin(sub, value); stream_list.refresh_pinned_or_unpinned_stream(sub); break; + case 'invite_only': + subs.update_stream_privacy(sub, { + invite_only: value, + history_public_to_subscribers: other_values.history_public_to_subscribers, + }); + break; + case 'is_announcement_only': + subs.update_stream_announcement_only(sub, value); + break; default: blueslip.warn("Unexpected subscription property type", {property: property, value: value}); diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index 62b0f08d54..81059a2f28 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -3441,6 +3441,16 @@ def do_change_stream_invite_only(stream: Stream, invite_only: bool, stream.invite_only = invite_only stream.history_public_to_subscribers = history_public_to_subscribers stream.save(update_fields=['invite_only', 'history_public_to_subscribers']) + event = dict( + op="update", + type="stream", + property="invite_only", + value=invite_only, + history_public_to_subscribers=history_public_to_subscribers, + stream_id=stream.id, + name=stream.name, + ) + send_event(stream.realm, event, can_access_stream_user_ids(stream)) def do_change_stream_web_public(stream: Stream, is_web_public: bool) -> None: stream.is_web_public = is_web_public @@ -3449,6 +3459,15 @@ def do_change_stream_web_public(stream: Stream, is_web_public: bool) -> None: def do_change_stream_announcement_only(stream: Stream, is_announcement_only: bool) -> None: stream.is_announcement_only = is_announcement_only stream.save(update_fields=['is_announcement_only']) + event = dict( + op="update", + type="stream", + property="is_announcement_only", + value=is_announcement_only, + stream_id=stream.id, + name=stream.name, + ) + send_event(stream.realm, event, can_access_stream_user_ids(stream)) def do_rename_stream(stream: Stream, new_name: str, diff --git a/zerver/tests/test_events.py b/zerver/tests/test_events.py index 46c4c054ff..6688ad0845 100644 --- a/zerver/tests/test_events.py +++ b/zerver/tests/test_events.py @@ -50,6 +50,8 @@ from zerver.lib.actions import ( do_change_notification_settings, do_change_realm_domain, do_change_stream_description, + do_change_stream_invite_only, + do_change_stream_announcement_only, do_change_subscription_property, do_change_user_delivery_email, do_create_user, @@ -2406,6 +2408,23 @@ class EventsRegisterTest(ZulipTestCase): ('stream_id', check_int), ('name', check_string), ]) + stream_update_invite_only_schema_checker = self.check_events_dict([ + ('type', equals('stream')), + ('op', equals('update')), + ('property', equals('invite_only')), + ('stream_id', check_int), + ('name', check_string), + ('value', check_bool), + ('history_public_to_subscribers', check_bool), + ]) + stream_update_is_announcement_only_schema_checker = self.check_events_dict([ + ('type', equals('stream')), + ('op', equals('update')), + ('property', equals('is_announcement_only')), + ('stream_id', check_int), + ('name', check_string), + ('value', check_bool), + ]) # Subscribe to a totally new stream, so it's just Hamlet on it action = lambda: self.subscribe(self.example_user("hamlet"), "test_stream") # type: Callable[[], Any] @@ -2462,6 +2481,20 @@ class EventsRegisterTest(ZulipTestCase): error = stream_update_schema_checker('events[0]', events[0]) self.assert_on_error(error) + # Update stream privacy + action = lambda: do_change_stream_invite_only(stream, True, history_public_to_subscribers=True) + events = self.do_test(action, + include_subscribers=include_subscribers) + error = stream_update_invite_only_schema_checker('events[0]', events[0]) + self.assert_on_error(error) + + # Update stream is_announcement_only property + action = lambda: do_change_stream_announcement_only(stream, True) + events = self.do_test(action, + include_subscribers=include_subscribers) + error = stream_update_is_announcement_only_schema_checker('events[0]', events[0]) + self.assert_on_error(error) + # Subscribe to a totally new invite-only stream, so it's just Hamlet on it stream = self.make_stream("private", self.user_profile.realm, invite_only=True) user_profile = self.example_user('hamlet')