stream edit: Extract stream_data.potential_subscribers().

We want to move more logic to stream_data to facilitate
testing.

Both before and after this commit, we essentially build a
new list of users for typeahead, but now the new list
excludes subscribed users.  We can do even better than
this in a follow-up commit.
This commit is contained in:
Steve Howell
2020-03-21 14:22:40 +00:00
committed by Tim Abbott
parent 7088d09094
commit 156ff33d22
4 changed files with 70 additions and 8 deletions

View File

@@ -182,9 +182,23 @@ run_test('subscribers', () => {
full_name: 'George',
user_id: 103,
};
people.add(fred);
people.add(not_fred);
people.add(george);
people.add_in_realm(fred);
people.add_in_realm(not_fred);
people.add_in_realm(george);
function potential_subscriber_ids() {
const users = stream_data.potential_subscribers(sub);
return users.map((u) => u.user_id).sort();
}
assert.deepEqual(
potential_subscriber_ids(),
[
fred.user_id,
not_fred.user_id,
george.user_id,
]
);
stream_data.set_subscribers(sub, [fred.user_id, george.user_id]);
stream_data.update_calculated_fields(sub);
@@ -192,6 +206,13 @@ run_test('subscribers', () => {
assert(stream_data.is_user_subscribed('Rome', george.user_id));
assert(!stream_data.is_user_subscribed('Rome', not_fred.user_id));
assert.deepEqual(
potential_subscriber_ids(),
[
not_fred.user_id,
]
);
stream_data.set_subscribers(sub, []);
const brutus = {

View File

@@ -675,6 +675,16 @@ exports.filter_all_persons = function (pred) {
return ret;
};
exports.filter_all_users = function (pred) {
const ret = [];
for (const person of active_user_dict.values()) {
if (pred(person)) {
ret.push(person);
}
}
return ret;
};
exports.get_realm_persons = function () {
return Array.from(active_user_dict.values());
};

View File

@@ -371,6 +371,39 @@ exports.update_subscribers_count = function (sub) {
sub.subscriber_count = count;
};
exports.potential_subscribers = function (sub) {
/*
This is a list of unsubscribed users
for the current stream, who the current
user could potentially subscribe to the
stream. This may include some bots.
We currently use it for typeahead in
stream_edit.js.
This may be a superset of the actual
subscribers that you can change in some cases
(like if you're a guest?); we should refine this
going forward, especially if we use it for something
other than typeahead. (The guest use case
may be moot now for other reasons.)
*/
function is_potential_subscriber(person) {
// Use verbose style to force better test
// coverage, plus we may add more conditions over
// time.
if (sub.subscribers.has(person.user_id)) {
return false;
}
return true;
}
return people.filter_all_users(is_potential_subscriber);
};
exports.update_stream_email_address = function (sub, email) {
sub.email_address = email;
};

View File

@@ -216,7 +216,7 @@ function show_subscription_settings(sub_row) {
}).init();
sub_settings.find('input[name="principal"]').typeahead({
source: people.get_realm_persons, // This is a function.
source: () => stream_data.potential_subscribers(sub),
items: 5,
highlighter: function (item) {
return typeahead_helper.render_person(item);
@@ -227,10 +227,8 @@ function show_subscription_settings(sub_row) {
return false;
}
// Case-insensitive.
const item_matches = item.email.toLowerCase().includes(query) ||
item.full_name.toLowerCase().includes(query);
const is_subscribed = stream_data.is_user_subscribed(sub.name, item.user_id);
return item_matches && !is_subscribed;
return item.email.toLowerCase().includes(query) ||
item.full_name.toLowerCase().includes(query);
},
sorter: function (matches) {
const current_stream = compose_state.stream_name();