subscribers: Extract subscriber_api.

This simplifies some of our dependencies.

As an example, we really don't want compose.js
to depend on stream_subscribers_ui.js, since
the former doesn't use any actual UI code from
the latter.

We also rename the two functions here:

    invite_user_to_stream -> add_user_ids_to_stream
    remove_user_from_stream -> remove_user_id_from_stream

(The notion of "inviting" somebody to a stream is
somewhat misleading, since there is really no invitation
mechanism; you just add them.)

Apart from naming changes this is a verbatim code move.

Finally, we eliminate a little bit of test cruft--the
`override` helper already ensures that a function gets
called at least once during a test.
This commit is contained in:
Steve Howell
2022-02-21 14:28:56 +00:00
committed by Tim Abbott
parent 57398c9933
commit 65b51ae3bd
6 changed files with 54 additions and 38 deletions

View File

@@ -37,7 +37,7 @@ const resize = mock_esm("../../static/js/resize");
const sent_messages = mock_esm("../../static/js/sent_messages");
const server_events = mock_esm("../../static/js/server_events");
const stream_settings_ui = mock_esm("../../static/js/stream_settings_ui");
const stream_subscribers_ui = mock_esm("../../static/js/stream_subscribers_ui");
const subscriber_api = mock_esm("../../static/js/subscriber_api");
const transmit = mock_esm("../../static/js/transmit");
const compose_closed_ui = zrequire("compose_closed_ui");
@@ -621,9 +621,7 @@ test_ui("on_events", ({override, override_rewire}) => {
};
people.add_active_user(mentioned);
let invite_user_to_stream_called = false;
override(stream_subscribers_ui, "invite_user_to_stream", (user_ids, sub, success) => {
invite_user_to_stream_called = true;
override(subscriber_api, "add_user_ids_to_stream", (user_ids, sub, success) => {
assert.deepEqual(user_ids, [mentioned.user_id]);
assert.equal(sub, subscription);
success(); // This will check success callback path.
@@ -660,7 +658,6 @@ test_ui("on_events", ({override, override_rewire}) => {
assert.ok(helper.container_was_removed());
assert.ok(!$("#compose_invite_users").visible());
assert.ok(invite_user_to_stream_called);
assert.ok(all_invite_children_called);
})();

View File

@@ -27,8 +27,8 @@ import * as sent_messages from "./sent_messages";
import * as server_events from "./server_events";
import * as stream_data from "./stream_data";
import * as stream_settings_ui from "./stream_settings_ui";
import * as stream_subscribers_ui from "./stream_subscribers_ui";
import * as sub_store from "./sub_store";
import * as subscriber_api from "./subscriber_api";
import * as transmit from "./transmit";
import * as ui_report from "./ui_report";
import * as upload from "./upload";
@@ -507,7 +507,7 @@ export function initialize() {
const sub = sub_store.get(stream_id);
stream_subscribers_ui.invite_user_to_stream([user_id], sub, success, xhr_failure);
subscriber_api.add_user_ids_to_stream([user_id], sub, success, xhr_failure);
});
$("#compose_invite_users").on("click", ".compose_invite_close", (event) => {

View File

@@ -5,7 +5,6 @@ import render_stream_member_list_entry from "../templates/stream_settings/stream
import render_stream_subscription_request_result from "../templates/stream_settings/stream_subscription_request_result.hbs";
import * as blueslip from "./blueslip";
import * as channel from "./channel";
import * as confirm_dialog from "./confirm_dialog";
import * as hash_util from "./hash_util";
import {$t, $t_html} from "./i18n";
@@ -19,6 +18,7 @@ import * as settings_data from "./settings_data";
import * as stream_data from "./stream_data";
import * as stream_pill from "./stream_pill";
import * as sub_store from "./sub_store";
import * as subscriber_api from "./subscriber_api";
import * as ui from "./ui";
import * as user_group_pill from "./user_group_pill";
import * as user_pill from "./user_pill";
@@ -171,31 +171,6 @@ function make_list_widget({parent_container, name, user_ids}) {
});
}
export function invite_user_to_stream(user_ids, sub, success, failure) {
// TODO: use stream_id when backend supports it
const stream_name = sub.name;
return channel.post({
url: "/json/users/me/subscriptions",
data: {
subscriptions: JSON.stringify([{name: stream_name}]),
principals: JSON.stringify(user_ids),
},
success,
error: failure,
});
}
export function remove_user_from_stream(user_id, sub, success, failure) {
// TODO: use stream_id when backend supports it
const stream_name = sub.name;
return channel.del({
url: "/json/users/me/subscriptions",
data: {subscriptions: JSON.stringify([stream_name]), principals: JSON.stringify([user_id])},
success,
error: failure,
});
}
export function get_pill_user_ids() {
const user_ids = user_pill.get_user_ids(pill_widget);
const stream_user_ids = stream_pill.get_user_ids(pill_widget);
@@ -274,7 +249,7 @@ function submit_add_subscriber_form(stream_id) {
});
}
invite_user_to_stream(user_ids, sub, invite_success, invite_failure);
subscriber_api.add_user_ids_to_stream(user_ids, sub, invite_success, invite_failure);
}
function remove_subscriber({stream_id, target_user_id, list_entry}) {
@@ -315,7 +290,12 @@ function remove_subscriber({stream_id, target_user_id, list_entry}) {
}
function remove_user_from_private_stream() {
remove_user_from_stream(target_user_id, sub, removal_success, removal_failure);
subscriber_api.remove_user_id_from_stream(
target_user_id,
sub,
removal_success,
removal_failure,
);
}
if (sub.invite_only && people.is_my_user_id(target_user_id)) {
@@ -332,7 +312,12 @@ function remove_subscriber({stream_id, target_user_id, list_entry}) {
return;
}
remove_user_from_stream(target_user_id, sub, removal_success, removal_failure);
subscriber_api.remove_user_id_from_stream(
target_user_id,
sub,
removal_success,
removal_failure,
);
}
export function update_subscribers_list(sub) {

View File

@@ -0,0 +1,33 @@
import * as channel from "./channel";
/*
This module simply encapsulates our legacy API for subscribing
or unsubscribing users from streams. Callers don't need to
know the strange names of "subscriptions" and "principals",
nor how to JSON.stringify things, nor the URL scheme.
*/
export function add_user_ids_to_stream(user_ids, sub, success, failure) {
// TODO: use stream_id when backend supports it
const stream_name = sub.name;
return channel.post({
url: "/json/users/me/subscriptions",
data: {
subscriptions: JSON.stringify([{name: stream_name}]),
principals: JSON.stringify(user_ids),
},
success,
error: failure,
});
}
export function remove_user_id_from_stream(user_id, sub, success, failure) {
// TODO: use stream_id when backend supports it
const stream_name = sub.name;
return channel.del({
url: "/json/users/me/subscriptions",
data: {subscriptions: JSON.stringify([stream_name]), principals: JSON.stringify([user_id])},
success,
error: failure,
});
}

View File

@@ -20,8 +20,8 @@ import * as settings_account from "./settings_account";
import * as settings_data from "./settings_data";
import * as settings_profile_fields from "./settings_profile_fields";
import * as stream_data from "./stream_data";
import * as stream_subscribers_ui from "./stream_subscribers_ui";
import * as sub_store from "./sub_store";
import * as subscriber_api from "./subscriber_api";
import * as ui_report from "./ui_report";
import * as user_groups from "./user_groups";
import * as util from "./util";
@@ -213,7 +213,7 @@ function handle_remove_stream_subscription(target_user_id, sub, success, failure
});
} else {
// Unsubscribed by admin.
stream_subscribers_ui.remove_user_from_stream(target_user_id, sub, success, failure);
subscriber_api.remove_user_id_from_stream(target_user_id, sub, success, failure);
}
}

View File

@@ -175,6 +175,7 @@ EXEMPT_FILES = make_set(
"static/js/stream_subscribers_ui.js",
"static/js/stream_ui_updates.js",
"static/js/submessage.js",
"static/js/subscriber_api.js",
"static/js/timerender.ts",
"static/js/tippyjs.js",
"static/js/todo_widget.js",