2021-01-27 17:15:55 +01:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
/*
|
|
|
|
This mostly tests the peer_data module, but it
|
|
|
|
also tests some stream_data functions that are
|
|
|
|
glorified wrappers for peer_data functions.
|
|
|
|
*/
|
|
|
|
|
2024-10-09 00:25:41 +02:00
|
|
|
const assert = require("node:assert/strict");
|
2021-01-27 17:15:55 +01:00
|
|
|
|
2023-02-22 23:04:10 +01:00
|
|
|
const {zrequire} = require("./lib/namespace");
|
|
|
|
const {run_test} = require("./lib/test");
|
|
|
|
const blueslip = require("./lib/zblueslip");
|
2024-10-09 21:21:41 +02:00
|
|
|
const {page_params} = require("./lib/zpage_params");
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
const peer_data = zrequire("peer_data");
|
|
|
|
const people = zrequire("people");
|
2024-10-09 22:44:13 +02:00
|
|
|
const {set_current_user} = zrequire("state_data");
|
2021-02-10 04:53:22 +01:00
|
|
|
const stream_data = zrequire("stream_data");
|
2021-01-27 17:15:55 +01:00
|
|
|
|
2024-10-09 22:44:13 +02:00
|
|
|
set_current_user({});
|
|
|
|
|
2021-03-25 22:35:45 +01:00
|
|
|
page_params.realm_users = [];
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
const me = {
|
|
|
|
email: "me@zulip.com",
|
|
|
|
full_name: "Current User",
|
|
|
|
user_id: 100,
|
|
|
|
};
|
|
|
|
|
|
|
|
// set up user data
|
2021-01-31 14:53:30 +01:00
|
|
|
const fred = {
|
|
|
|
email: "fred@zulip.com",
|
|
|
|
full_name: "Fred",
|
|
|
|
user_id: 101,
|
|
|
|
};
|
|
|
|
const gail = {
|
|
|
|
email: "gail@zulip.com",
|
|
|
|
full_name: "Gail",
|
|
|
|
user_id: 102,
|
|
|
|
};
|
|
|
|
const george = {
|
|
|
|
email: "george@zulip.com",
|
|
|
|
full_name: "George",
|
|
|
|
user_id: 103,
|
|
|
|
};
|
2024-10-09 18:30:33 +02:00
|
|
|
const bot_botson = {
|
|
|
|
email: "botson-bot@example.com",
|
|
|
|
user_id: 35,
|
|
|
|
full_name: "Bot Botson",
|
|
|
|
is_bot: true,
|
|
|
|
role: 300,
|
|
|
|
};
|
2021-01-31 14:53:30 +01:00
|
|
|
|
2021-01-27 17:15:55 +01:00
|
|
|
function contains_sub(subs, sub) {
|
|
|
|
return subs.some((s) => s.name === sub.name);
|
|
|
|
}
|
|
|
|
|
2021-03-09 16:02:52 +01:00
|
|
|
function test(label, f) {
|
2021-06-16 14:38:37 +02:00
|
|
|
run_test(label, ({override}) => {
|
2021-03-09 16:02:52 +01:00
|
|
|
peer_data.clear_for_testing();
|
|
|
|
stream_data.clear_subscriptions();
|
|
|
|
|
|
|
|
people.init();
|
|
|
|
people.add_active_user(me);
|
|
|
|
people.initialize_current_user(me.user_id);
|
|
|
|
|
2021-06-16 14:38:37 +02:00
|
|
|
f({override});
|
2021-03-09 16:02:52 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
test("unsubscribe", () => {
|
|
|
|
const devel = {name: "devel", subscribed: false, stream_id: 1};
|
|
|
|
stream_data.add_sub(devel);
|
|
|
|
|
2021-01-31 14:53:30 +01:00
|
|
|
// verify clean slate
|
2024-08-03 03:05:34 +02:00
|
|
|
assert.ok(!stream_data.is_subscribed(devel.stream_id));
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// set up our subscription
|
2021-01-31 14:53:30 +01:00
|
|
|
devel.subscribed = true;
|
|
|
|
peer_data.set_subscribers(devel.stream_id, [me.user_id]);
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// ensure our setup is accurate
|
2024-08-03 03:05:34 +02:00
|
|
|
assert.ok(stream_data.is_subscribed(devel.stream_id));
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// DO THE UNSUBSCRIBE HERE
|
2021-01-31 14:53:30 +01:00
|
|
|
stream_data.unsubscribe_myself(devel);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!devel.subscribed);
|
2024-08-03 03:05:34 +02:00
|
|
|
assert.ok(!stream_data.is_subscribed(devel.stream_id));
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!contains_sub(stream_data.subscribed_subs(), devel));
|
|
|
|
assert.ok(contains_sub(stream_data.unsubscribed_subs(), devel));
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// make sure subsequent calls work
|
2021-01-31 14:53:30 +01:00
|
|
|
const sub = stream_data.get_sub("devel");
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!sub.subscribed);
|
2021-01-27 17:15:55 +01:00
|
|
|
});
|
|
|
|
|
2021-03-09 16:02:52 +01:00
|
|
|
test("subscribers", () => {
|
|
|
|
const sub = {name: "Rome", subscribed: true, stream_id: 1001};
|
|
|
|
stream_data.add_sub(sub);
|
|
|
|
|
|
|
|
people.add_active_user(fred);
|
|
|
|
people.add_active_user(gail);
|
|
|
|
people.add_active_user(george);
|
2021-01-27 17:15:55 +01:00
|
|
|
|
2021-01-31 14:53:30 +01:00
|
|
|
// verify setup
|
2024-08-03 03:05:34 +02:00
|
|
|
assert.ok(stream_data.is_subscribed(sub.stream_id));
|
2021-01-27 17:15:55 +01:00
|
|
|
|
2021-04-05 14:13:03 +02:00
|
|
|
const stream_id = sub.stream_id;
|
|
|
|
|
2021-01-27 17:15:55 +01:00
|
|
|
function potential_subscriber_ids() {
|
2021-04-05 14:13:03 +02:00
|
|
|
const users = peer_data.potential_subscribers(stream_id);
|
2021-01-27 17:15:55 +01:00
|
|
|
return users.map((u) => u.user_id).sort();
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.deepEqual(potential_subscriber_ids(), [
|
|
|
|
me.user_id,
|
|
|
|
fred.user_id,
|
2021-01-31 14:53:30 +01:00
|
|
|
gail.user_id,
|
2021-01-27 17:15:55 +01:00
|
|
|
george.user_id,
|
|
|
|
]);
|
|
|
|
|
2021-04-05 14:13:03 +02:00
|
|
|
peer_data.set_subscribers(stream_id, [me.user_id, fred.user_id, george.user_id]);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(stream_data.is_user_subscribed(stream_id, me.user_id));
|
|
|
|
assert.ok(stream_data.is_user_subscribed(stream_id, fred.user_id));
|
|
|
|
assert.ok(stream_data.is_user_subscribed(stream_id, george.user_id));
|
|
|
|
assert.ok(!stream_data.is_user_subscribed(stream_id, gail.user_id));
|
2021-01-27 17:15:55 +01:00
|
|
|
|
2021-01-31 14:53:30 +01:00
|
|
|
assert.deepEqual(potential_subscriber_ids(), [gail.user_id]);
|
2021-01-27 17:15:55 +01:00
|
|
|
|
2021-04-05 14:13:03 +02:00
|
|
|
peer_data.set_subscribers(stream_id, []);
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
const brutus = {
|
|
|
|
email: "brutus@zulip.com",
|
|
|
|
full_name: "Brutus",
|
|
|
|
user_id: 104,
|
|
|
|
};
|
|
|
|
people.add_active_user(brutus);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!stream_data.is_user_subscribed(stream_id, brutus.user_id));
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// add
|
2021-04-05 14:13:03 +02:00
|
|
|
peer_data.add_subscriber(stream_id, brutus.user_id);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(stream_data.is_user_subscribed(stream_id, brutus.user_id));
|
2021-04-05 14:13:03 +02:00
|
|
|
assert.equal(peer_data.get_subscriber_count(stream_id), 1);
|
2021-01-27 17:15:55 +01:00
|
|
|
const sub_email = "Rome:214125235@zulipdev.com:9991";
|
|
|
|
stream_data.update_stream_email_address(sub, sub_email);
|
|
|
|
assert.equal(sub.email_address, sub_email);
|
|
|
|
|
|
|
|
// verify that adding an already-added subscriber is a noop
|
2021-04-05 14:13:03 +02:00
|
|
|
peer_data.add_subscriber(stream_id, brutus.user_id);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(stream_data.is_user_subscribed(stream_id, brutus.user_id));
|
2021-04-05 14:13:03 +02:00
|
|
|
assert.equal(peer_data.get_subscriber_count(stream_id), 1);
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// remove
|
2021-04-05 14:13:03 +02:00
|
|
|
let ok = peer_data.remove_subscriber(stream_id, brutus.user_id);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(ok);
|
|
|
|
assert.ok(!stream_data.is_user_subscribed(stream_id, brutus.user_id));
|
2021-04-05 14:13:03 +02:00
|
|
|
assert.equal(peer_data.get_subscriber_count(stream_id), 0);
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// verify that checking subscription with undefined user id
|
|
|
|
|
|
|
|
blueslip.expect("warn", "Undefined user_id passed to function is_user_subscribed");
|
2023-12-22 01:37:24 +01:00
|
|
|
assert.ok(!stream_data.is_user_subscribed(stream_id, undefined));
|
2021-01-29 17:17:32 +01:00
|
|
|
blueslip.reset();
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// Verify noop for bad stream when removing subscriber
|
|
|
|
const bad_stream_id = 999999;
|
2021-01-29 17:17:32 +01:00
|
|
|
blueslip.expect("warn", "We called get_user_set for an untracked stream: " + bad_stream_id);
|
|
|
|
blueslip.expect("warn", "We tried to remove invalid subscriber: 104");
|
2021-01-27 17:15:55 +01:00
|
|
|
ok = peer_data.remove_subscriber(bad_stream_id, brutus.user_id);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!ok);
|
2021-01-29 17:17:32 +01:00
|
|
|
blueslip.reset();
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// verify that removing an already-removed subscriber is a noop
|
|
|
|
blueslip.expect("warn", "We tried to remove invalid subscriber: 104");
|
2021-04-05 14:13:03 +02:00
|
|
|
ok = peer_data.remove_subscriber(stream_id, brutus.user_id);
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(!ok);
|
|
|
|
assert.ok(!stream_data.is_user_subscribed(stream_id, brutus.user_id));
|
2021-04-05 14:13:03 +02:00
|
|
|
assert.equal(peer_data.get_subscriber_count(stream_id), 0);
|
2021-01-29 17:17:32 +01:00
|
|
|
blueslip.reset();
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// Verify defensive code in set_subscribers, where the second parameter
|
|
|
|
// can be undefined.
|
|
|
|
stream_data.add_sub(sub);
|
2021-04-05 14:13:03 +02:00
|
|
|
peer_data.add_subscriber(stream_id, brutus.user_id);
|
2021-01-27 17:15:55 +01:00
|
|
|
sub.subscribed = true;
|
2021-06-10 08:32:54 +02:00
|
|
|
assert.ok(stream_data.is_user_subscribed(stream_id, brutus.user_id));
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
// Verify that we noop and don't crash when unsubscribed.
|
|
|
|
sub.subscribed = false;
|
2021-04-05 14:13:03 +02:00
|
|
|
peer_data.add_subscriber(stream_id, brutus.user_id);
|
|
|
|
assert.equal(stream_data.is_user_subscribed(stream_id, brutus.user_id), true);
|
|
|
|
peer_data.remove_subscriber(stream_id, brutus.user_id);
|
|
|
|
assert.equal(stream_data.is_user_subscribed(stream_id, brutus.user_id), false);
|
|
|
|
peer_data.add_subscriber(stream_id, brutus.user_id);
|
|
|
|
assert.equal(stream_data.is_user_subscribed(stream_id, brutus.user_id), true);
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
blueslip.expect(
|
|
|
|
"warn",
|
|
|
|
"We got a is_user_subscribed call for a non-existent or inaccessible stream.",
|
|
|
|
2,
|
|
|
|
);
|
|
|
|
sub.invite_only = true;
|
2023-12-22 01:37:24 +01:00
|
|
|
assert.ok(!stream_data.is_user_subscribed(stream_id, brutus.user_id));
|
2021-04-05 14:13:03 +02:00
|
|
|
peer_data.remove_subscriber(stream_id, brutus.user_id);
|
2023-12-22 01:37:24 +01:00
|
|
|
assert.ok(!stream_data.is_user_subscribed(stream_id, brutus.user_id));
|
2021-01-29 17:17:32 +01:00
|
|
|
blueslip.reset();
|
|
|
|
|
|
|
|
// Verify that we don't crash for a bad stream.
|
|
|
|
blueslip.expect("warn", "We called get_user_set for an untracked stream: 9999999");
|
|
|
|
peer_data.add_subscriber(9999999, brutus.user_id);
|
|
|
|
blueslip.reset();
|
|
|
|
|
|
|
|
// Verify that we don't crash for a bad user id.
|
2023-06-16 15:23:45 +02:00
|
|
|
blueslip.expect("error", "Unknown user_id in maybe_get_user_by_id");
|
2021-01-29 17:17:32 +01:00
|
|
|
blueslip.expect("warn", "We tried to add invalid subscriber: 88888");
|
2021-04-05 14:13:03 +02:00
|
|
|
peer_data.add_subscriber(stream_id, 88888);
|
2021-01-29 17:17:32 +01:00
|
|
|
blueslip.reset();
|
2021-01-27 17:15:55 +01:00
|
|
|
});
|
|
|
|
|
2021-03-09 16:02:52 +01:00
|
|
|
test("get_subscriber_count", () => {
|
|
|
|
people.add_active_user(fred);
|
|
|
|
people.add_active_user(gail);
|
|
|
|
people.add_active_user(george);
|
2024-02-06 22:12:26 +01:00
|
|
|
const welcome_bot = {
|
|
|
|
email: "welcome-bot@example.com",
|
|
|
|
user_id: 40,
|
|
|
|
full_name: "Welcome Bot",
|
|
|
|
is_bot: true,
|
|
|
|
};
|
|
|
|
people.add_active_user(welcome_bot);
|
2021-03-09 16:02:52 +01:00
|
|
|
|
2021-01-27 17:15:55 +01:00
|
|
|
const india = {
|
|
|
|
stream_id: 102,
|
|
|
|
name: "India",
|
|
|
|
subscribed: true,
|
|
|
|
};
|
|
|
|
stream_data.clear_subscriptions();
|
|
|
|
|
2021-01-29 17:17:32 +01:00
|
|
|
blueslip.expect("warn", "We called get_user_set for an untracked stream: 102");
|
|
|
|
assert.equal(peer_data.get_subscriber_count(india.stream_id), 0);
|
2021-01-27 17:15:55 +01:00
|
|
|
|
|
|
|
stream_data.add_sub(india);
|
|
|
|
assert.equal(peer_data.get_subscriber_count(india.stream_id), 0);
|
|
|
|
|
2021-01-31 14:53:30 +01:00
|
|
|
peer_data.add_subscriber(india.stream_id, fred.user_id);
|
2021-01-27 17:15:55 +01:00
|
|
|
assert.equal(peer_data.get_subscriber_count(india.stream_id), 1);
|
2021-01-31 14:53:30 +01:00
|
|
|
peer_data.add_subscriber(india.stream_id, george.user_id);
|
2021-01-27 17:15:55 +01:00
|
|
|
assert.equal(peer_data.get_subscriber_count(india.stream_id), 2);
|
|
|
|
|
2021-01-31 14:53:30 +01:00
|
|
|
peer_data.remove_subscriber(india.stream_id, george.user_id);
|
2021-01-27 17:15:55 +01:00
|
|
|
assert.deepStrictEqual(peer_data.get_subscriber_count(india.stream_id), 1);
|
2024-02-06 22:12:26 +01:00
|
|
|
|
|
|
|
peer_data.add_subscriber(india.stream_id, welcome_bot.user_id);
|
|
|
|
assert.deepStrictEqual(peer_data.get_subscriber_count(india.stream_id), 2);
|
|
|
|
// Get the count without bots
|
|
|
|
assert.deepStrictEqual(peer_data.get_subscriber_count(india.stream_id, false), 1);
|
2021-01-27 17:15:55 +01:00
|
|
|
});
|
|
|
|
|
2021-03-09 16:02:52 +01:00
|
|
|
test("is_subscriber_subset", () => {
|
2021-01-27 17:15:55 +01:00
|
|
|
function make_sub(stream_id, user_ids) {
|
2021-01-30 13:38:55 +01:00
|
|
|
const sub = {
|
|
|
|
stream_id,
|
|
|
|
name: `stream ${stream_id}`,
|
|
|
|
};
|
|
|
|
stream_data.add_sub(sub);
|
2021-01-27 17:15:55 +01:00
|
|
|
peer_data.set_subscribers(sub.stream_id, user_ids);
|
|
|
|
return sub;
|
|
|
|
}
|
|
|
|
|
|
|
|
const sub_a = make_sub(301, [1, 2]);
|
|
|
|
const sub_b = make_sub(302, [2, 3]);
|
|
|
|
const sub_c = make_sub(303, [1, 2, 3]);
|
|
|
|
|
|
|
|
const matrix = [
|
|
|
|
[sub_a, sub_a, true],
|
|
|
|
[sub_a, sub_b, false],
|
|
|
|
[sub_a, sub_c, true],
|
|
|
|
[sub_b, sub_a, false],
|
|
|
|
[sub_b, sub_b, true],
|
|
|
|
[sub_b, sub_c, true],
|
|
|
|
[sub_c, sub_a, false],
|
|
|
|
[sub_c, sub_b, false],
|
|
|
|
[sub_c, sub_c, true],
|
|
|
|
];
|
|
|
|
|
|
|
|
for (const row of matrix) {
|
|
|
|
assert.equal(peer_data.is_subscriber_subset(row[0].stream_id, row[1].stream_id), row[2]);
|
|
|
|
}
|
|
|
|
|
2021-01-29 17:17:32 +01:00
|
|
|
// Two untracked streams should never be passed into us.
|
|
|
|
blueslip.expect("warn", "We called get_user_set for an untracked stream: 88888");
|
|
|
|
blueslip.expect("warn", "We called get_user_set for an untracked stream: 99999");
|
|
|
|
peer_data.is_subscriber_subset(99999, 88888);
|
|
|
|
blueslip.reset();
|
|
|
|
|
|
|
|
// Warn about hypothetical undefined stream_ids.
|
|
|
|
blueslip.expect("warn", "We called get_user_set for an untracked stream: undefined");
|
|
|
|
peer_data.is_subscriber_subset(undefined, sub_a.stream_id);
|
|
|
|
blueslip.reset();
|
2021-01-27 17:15:55 +01:00
|
|
|
});
|
2024-10-09 18:30:33 +02:00
|
|
|
|
|
|
|
test("get_unique_subscriber_count_for_streams", () => {
|
|
|
|
const sub = {name: "Rome", subscribed: true, stream_id: 1001};
|
|
|
|
stream_data.add_sub(sub);
|
|
|
|
|
|
|
|
people.add_active_user(fred);
|
|
|
|
people.add_active_user(gail);
|
|
|
|
people.add_active_user(george);
|
|
|
|
people.add_active_user(bot_botson);
|
|
|
|
|
|
|
|
const stream_id = sub.stream_id;
|
|
|
|
peer_data.set_subscribers(stream_id, [me.user_id, fred.user_id, bot_botson.user_id]);
|
|
|
|
|
|
|
|
const count = peer_data.get_unique_subscriber_count_for_streams([stream_id]);
|
|
|
|
|
|
|
|
assert.equal(count, 2);
|
|
|
|
});
|