2020-08-01 03:43:15 +02:00
|
|
|
"use strict";
|
|
|
|
|
2020-11-30 23:46:45 +01:00
|
|
|
const {strict: assert} = require("assert");
|
|
|
|
|
2020-07-25 02:02:35 +02:00
|
|
|
const _ = require("lodash");
|
|
|
|
|
2023-02-22 23:04:10 +01:00
|
|
|
const {mock_esm, zrequire} = require("./lib/namespace");
|
|
|
|
const {run_test} = require("./lib/test");
|
2020-12-01 00:02:16 +01:00
|
|
|
|
2023-02-22 23:04:10 +01:00
|
|
|
mock_esm("../src/message_store", {
|
2022-10-14 17:37:47 +02:00
|
|
|
get() {
|
|
|
|
return {
|
|
|
|
stream_id: 556,
|
|
|
|
topic: "general",
|
|
|
|
};
|
|
|
|
},
|
|
|
|
});
|
2023-02-22 23:04:10 +01:00
|
|
|
const user_topics = mock_esm("../src/user_topics", {
|
2021-02-24 17:24:06 +01:00
|
|
|
is_topic_muted() {
|
|
|
|
return false;
|
|
|
|
},
|
2021-03-07 13:57:14 +01:00
|
|
|
});
|
2023-02-22 23:04:10 +01:00
|
|
|
const narrow_state = mock_esm("../src/narrow_state", {
|
2021-03-07 13:57:14 +01:00
|
|
|
topic() {},
|
|
|
|
});
|
2021-03-06 17:37:51 +01:00
|
|
|
|
2023-02-22 23:04:10 +01:00
|
|
|
const topic_list = mock_esm("../src/topic_list", {
|
2021-06-08 18:42:06 +02:00
|
|
|
get_topic_search_term() {},
|
|
|
|
});
|
|
|
|
|
2021-03-07 13:57:14 +01:00
|
|
|
const stream_data = zrequire("stream_data");
|
2021-02-10 04:53:22 +01:00
|
|
|
const stream_topic_history = zrequire("stream_topic_history");
|
2020-07-15 01:29:15 +02:00
|
|
|
const topic_list_data = zrequire("topic_list_data");
|
2021-03-07 13:57:14 +01:00
|
|
|
const unread = zrequire("unread");
|
2016-11-05 16:36:30 +01:00
|
|
|
|
2020-01-18 12:06:56 +01:00
|
|
|
const general = {
|
|
|
|
stream_id: 556,
|
2020-07-15 01:29:15 +02:00
|
|
|
name: "general",
|
2020-01-18 12:06:56 +01:00
|
|
|
};
|
2018-12-13 22:26:10 +01:00
|
|
|
|
2020-02-09 22:02:55 +01:00
|
|
|
stream_data.add_sub(general);
|
2016-11-05 16:36:30 +01:00
|
|
|
|
2020-01-18 13:53:12 +01:00
|
|
|
function get_list_info(zoomed) {
|
2020-01-18 12:06:56 +01:00
|
|
|
const stream_id = general.stream_id;
|
2020-07-15 00:34:28 +02:00
|
|
|
return topic_list_data.get_list_info(stream_id, zoomed);
|
2020-01-18 12:06:56 +01:00
|
|
|
}
|
|
|
|
|
2021-03-12 23:47:39 +01:00
|
|
|
function test(label, f) {
|
2022-07-10 01:06:33 +02:00
|
|
|
run_test(label, (helpers) => {
|
2021-03-12 23:47:39 +01:00
|
|
|
stream_topic_history.reset();
|
2022-07-10 01:06:33 +02:00
|
|
|
f(helpers);
|
2021-03-12 23:47:39 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-06-16 14:38:37 +02:00
|
|
|
test("get_list_info w/real stream_topic_history", ({override}) => {
|
2020-01-18 14:03:08 +01:00
|
|
|
let list_info;
|
2020-01-18 12:06:56 +01:00
|
|
|
const empty_list_info = get_list_info();
|
|
|
|
|
|
|
|
assert.deepEqual(empty_list_info, {
|
|
|
|
items: [],
|
2022-08-21 23:05:56 +02:00
|
|
|
more_topics_have_unread_mention_messages: false,
|
2020-01-18 12:06:56 +01:00
|
|
|
more_topics_unreads: 0,
|
|
|
|
num_possible_topics: 0,
|
2017-07-24 22:16:13 +02:00
|
|
|
});
|
|
|
|
|
2021-06-08 18:42:06 +02:00
|
|
|
function add_topic_message(topic_name, message_id) {
|
2020-03-22 18:40:05 +01:00
|
|
|
stream_topic_history.add_message({
|
2020-01-18 12:06:56 +01:00
|
|
|
stream_id: general.stream_id,
|
2020-07-20 22:18:43 +02:00
|
|
|
topic_name,
|
2021-06-08 18:42:06 +02:00
|
|
|
message_id,
|
2020-01-18 12:06:56 +01:00
|
|
|
});
|
js: Automatically convert _.each to for…of.
This commit was automatically generated by the following script,
followed by lint --fix and a few small manual lint-related cleanups.
import * as babelParser from "recast/parsers/babel";
import * as recast from "recast";
import * as tsParser from "recast/parsers/typescript";
import { builders as b, namedTypes as n } from "ast-types";
import { Context } from "ast-types/lib/path-visitor";
import K from "ast-types/gen/kinds";
import { NodePath } from "ast-types/lib/node-path";
import assert from "assert";
import fs from "fs";
import path from "path";
import process from "process";
const checkExpression = (node: n.Node): node is K.ExpressionKind =>
n.Expression.check(node);
const checkStatement = (node: n.Node): node is K.StatementKind =>
n.Statement.check(node);
for (const file of process.argv.slice(2)) {
console.log("Parsing", file);
const ast = recast.parse(fs.readFileSync(file, { encoding: "utf8" }), {
parser: path.extname(file) === ".ts" ? tsParser : babelParser,
});
let changed = false;
let inLoop = false;
let replaceReturn = false;
const visitLoop = (...args: string[]) =>
function(this: Context, path: NodePath) {
for (const arg of args) {
this.visit(path.get(arg));
}
const old = { inLoop };
inLoop = true;
this.visit(path.get("body"));
inLoop = old.inLoop;
return false;
};
recast.visit(ast, {
visitDoWhileStatement: visitLoop("test"),
visitExpressionStatement(path) {
const { expression, comments } = path.node;
let valueOnly;
if (
n.CallExpression.check(expression) &&
n.MemberExpression.check(expression.callee) &&
!expression.callee.computed &&
n.Identifier.check(expression.callee.object) &&
expression.callee.object.name === "_" &&
n.Identifier.check(expression.callee.property) &&
["each", "forEach"].includes(expression.callee.property.name) &&
[2, 3].includes(expression.arguments.length) &&
checkExpression(expression.arguments[0]) &&
(n.FunctionExpression.check(expression.arguments[1]) ||
n.ArrowFunctionExpression.check(expression.arguments[1])) &&
[1, 2].includes(expression.arguments[1].params.length) &&
n.Identifier.check(expression.arguments[1].params[0]) &&
((valueOnly = expression.arguments[1].params[1] === undefined) ||
n.Identifier.check(expression.arguments[1].params[1])) &&
(expression.arguments[2] === undefined ||
n.ThisExpression.check(expression.arguments[2]))
) {
const old = { inLoop, replaceReturn };
inLoop = false;
replaceReturn = true;
this.visit(
path
.get("expression")
.get("arguments")
.get(1)
.get("body")
);
inLoop = old.inLoop;
replaceReturn = old.replaceReturn;
const [right, { body, params }] = expression.arguments;
const loop = b.forOfStatement(
b.variableDeclaration("let", [
b.variableDeclarator(
valueOnly ? params[0] : b.arrayPattern([params[1], params[0]])
),
]),
valueOnly
? right
: b.callExpression(
b.memberExpression(right, b.identifier("entries")),
[]
),
checkStatement(body) ? body : b.expressionStatement(body)
);
loop.comments = comments;
path.replace(loop);
changed = true;
}
this.traverse(path);
},
visitForStatement: visitLoop("init", "test", "update"),
visitForInStatement: visitLoop("left", "right"),
visitForOfStatement: visitLoop("left", "right"),
visitFunction(path) {
this.visit(path.get("params"));
const old = { replaceReturn };
replaceReturn = false;
this.visit(path.get("body"));
replaceReturn = old.replaceReturn;
return false;
},
visitReturnStatement(path) {
if (replaceReturn) {
assert(!inLoop); // could use labeled continue if this ever fires
const { argument, comments } = path.node;
if (argument === null) {
const s = b.continueStatement();
s.comments = comments;
path.replace(s);
} else {
const s = b.expressionStatement(argument);
s.comments = comments;
path.replace(s, b.continueStatement());
}
return false;
}
this.traverse(path);
},
visitWhileStatement: visitLoop("test"),
});
if (changed) {
console.log("Writing", file);
fs.writeFileSync(file, recast.print(ast).code, { encoding: "utf8" });
}
}
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-02-06 06:19:47 +01:00
|
|
|
}
|
2021-06-08 18:42:06 +02:00
|
|
|
for (const i of _.range(7)) {
|
2021-07-01 10:19:59 +02:00
|
|
|
let topic_name;
|
|
|
|
// All odd topics are resolved.
|
|
|
|
if (i % 2) {
|
|
|
|
topic_name = "✔ topic ";
|
|
|
|
} else {
|
|
|
|
topic_name = "topic ";
|
|
|
|
}
|
|
|
|
add_topic_message(topic_name + i, 1000 + i);
|
2021-06-08 18:42:06 +02:00
|
|
|
}
|
2020-01-18 12:06:56 +01:00
|
|
|
|
2021-02-24 17:24:06 +01:00
|
|
|
override(narrow_state, "topic", () => "topic 6");
|
2020-01-18 14:03:08 +01:00
|
|
|
|
|
|
|
list_info = get_list_info();
|
2020-01-18 12:06:56 +01:00
|
|
|
assert.equal(list_info.items.length, 5);
|
|
|
|
assert.equal(list_info.more_topics_unreads, 0);
|
2022-08-21 23:05:56 +02:00
|
|
|
assert.equal(list_info.more_topics_have_unread_mention_messages, false);
|
2020-01-18 12:06:56 +01:00
|
|
|
assert.equal(list_info.num_possible_topics, 7);
|
|
|
|
|
|
|
|
assert.deepEqual(list_info.items[0], {
|
2022-08-21 23:05:56 +02:00
|
|
|
contains_unread_mention: false,
|
2020-01-18 14:03:08 +01:00
|
|
|
is_active_topic: true,
|
2020-01-18 12:06:56 +01:00
|
|
|
is_muted: false,
|
|
|
|
is_zero: true,
|
2021-07-01 10:19:59 +02:00
|
|
|
topic_display_name: "topic 6",
|
2020-07-15 01:29:15 +02:00
|
|
|
topic_name: "topic 6",
|
2022-03-08 05:05:47 +01:00
|
|
|
topic_resolved_prefix: "",
|
2020-01-18 12:06:56 +01:00
|
|
|
unread: 0,
|
2020-07-15 01:29:15 +02:00
|
|
|
url: "#narrow/stream/556-general/topic/topic.206",
|
2020-01-18 12:06:56 +01:00
|
|
|
});
|
2020-01-18 14:03:08 +01:00
|
|
|
|
2021-07-01 10:19:59 +02:00
|
|
|
assert.deepEqual(list_info.items[1], {
|
2022-08-21 23:05:56 +02:00
|
|
|
contains_unread_mention: false,
|
2021-07-01 10:19:59 +02:00
|
|
|
is_active_topic: false,
|
|
|
|
is_muted: false,
|
|
|
|
is_zero: true,
|
|
|
|
topic_display_name: "topic 5",
|
|
|
|
topic_name: "✔ topic 5",
|
2022-03-08 05:05:47 +01:00
|
|
|
topic_resolved_prefix: "✔ ",
|
2021-07-01 10:19:59 +02:00
|
|
|
unread: 0,
|
|
|
|
url: "#narrow/stream/556-general/topic/.E2.9C.94.20topic.205",
|
|
|
|
});
|
2021-06-08 18:42:06 +02:00
|
|
|
// If we zoom in, our results based on topic filter.
|
|
|
|
// If topic search input is empty, we show all 7 topics.
|
|
|
|
|
2020-01-18 14:03:08 +01:00
|
|
|
const zoomed = true;
|
2021-06-08 18:42:06 +02:00
|
|
|
override(topic_list, "get_topic_search_term", () => "");
|
2020-01-18 14:03:08 +01:00
|
|
|
list_info = get_list_info(zoomed);
|
|
|
|
assert.equal(list_info.items.length, 7);
|
|
|
|
assert.equal(list_info.more_topics_unreads, 0);
|
2022-08-21 23:05:56 +02:00
|
|
|
assert.equal(list_info.more_topics_have_unread_mention_messages, false);
|
2020-01-18 14:03:08 +01:00
|
|
|
assert.equal(list_info.num_possible_topics, 7);
|
2021-06-08 18:42:06 +02:00
|
|
|
|
|
|
|
add_topic_message("After Brooklyn", 1008);
|
|
|
|
add_topic_message("Catering", 1009);
|
|
|
|
// when topic search is open then we list topics based on search term.
|
|
|
|
override(topic_list, "get_topic_search_term", () => "b,c");
|
|
|
|
list_info = get_list_info(zoomed);
|
|
|
|
assert.equal(list_info.items.length, 2);
|
|
|
|
assert.equal(list_info.more_topics_unreads, 0);
|
2022-08-21 23:05:56 +02:00
|
|
|
assert.equal(list_info.more_topics_have_unread_mention_messages, false);
|
2021-06-08 18:42:06 +02:00
|
|
|
assert.equal(list_info.num_possible_topics, 2);
|
2020-01-18 12:06:56 +01:00
|
|
|
});
|
|
|
|
|
2022-07-10 01:06:33 +02:00
|
|
|
test("get_list_info unreads", ({override}) => {
|
2020-01-18 12:06:56 +01:00
|
|
|
let list_info;
|
|
|
|
|
2022-07-10 01:06:33 +02:00
|
|
|
let message_id = 0;
|
|
|
|
for (let i = 14; i >= 0; i -= 1) {
|
|
|
|
stream_topic_history.add_message({
|
|
|
|
stream_id: general.stream_id,
|
|
|
|
message_id: (message_id += 1),
|
|
|
|
topic_name: `topic ${i}`,
|
|
|
|
});
|
|
|
|
}
|
2020-01-18 12:06:56 +01:00
|
|
|
|
2022-07-10 01:06:33 +02:00
|
|
|
function add_unreads(topic, count) {
|
|
|
|
unread.process_loaded_messages(
|
|
|
|
Array.from({length: count}, () => ({
|
|
|
|
id: (message_id += 1),
|
|
|
|
stream_id: general.stream_id,
|
|
|
|
topic,
|
|
|
|
type: "stream",
|
|
|
|
unread: true,
|
|
|
|
})),
|
|
|
|
);
|
|
|
|
}
|
2020-01-18 12:06:56 +01:00
|
|
|
|
2022-08-21 23:05:56 +02:00
|
|
|
function add_unreads_with_mention(topic, count) {
|
|
|
|
unread.process_loaded_messages(
|
|
|
|
Array.from({length: count}, () => ({
|
|
|
|
id: (message_id += 1),
|
|
|
|
stream_id: general.stream_id,
|
|
|
|
topic,
|
|
|
|
type: "stream",
|
|
|
|
unread: true,
|
|
|
|
mentioned: true,
|
|
|
|
mentioned_me_directly: true,
|
|
|
|
})),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-01-18 12:06:56 +01:00
|
|
|
/*
|
|
|
|
We have 15 topics, but we only show up
|
|
|
|
to 8 topics, depending on how many have
|
|
|
|
unread counts. We only show a max of 5
|
|
|
|
fully-read topics.
|
|
|
|
|
|
|
|
So first we'll get 7 topics, where 2 are
|
|
|
|
unread.
|
|
|
|
*/
|
2022-07-10 01:06:33 +02:00
|
|
|
add_unreads("topic 8", 8);
|
|
|
|
add_unreads("topic 9", 9);
|
2020-01-18 12:06:56 +01:00
|
|
|
|
2022-08-21 23:05:56 +02:00
|
|
|
/*
|
|
|
|
We added 9 unread messages in 'topic 9',
|
|
|
|
but now we would add a unread message
|
|
|
|
with `mention` for user, to test
|
|
|
|
`more_topics_have_unread_mention_messages`.
|
|
|
|
*/
|
|
|
|
add_unreads_with_mention("topic 9", 1);
|
|
|
|
|
2020-01-18 12:06:56 +01:00
|
|
|
list_info = get_list_info();
|
|
|
|
assert.equal(list_info.items.length, 7);
|
|
|
|
assert.equal(list_info.more_topics_unreads, 0);
|
2022-08-21 23:05:56 +02:00
|
|
|
assert.equal(list_info.more_topics_have_unread_mention_messages, false);
|
2020-01-18 12:06:56 +01:00
|
|
|
assert.equal(list_info.num_possible_topics, 15);
|
|
|
|
|
|
|
|
assert.deepEqual(
|
2020-07-02 01:39:34 +02:00
|
|
|
list_info.items.map((li) => li.topic_name),
|
2020-07-15 00:34:28 +02:00
|
|
|
["topic 0", "topic 1", "topic 2", "topic 3", "topic 4", "topic 8", "topic 9"],
|
|
|
|
);
|
2020-01-18 12:06:56 +01:00
|
|
|
|
2022-07-10 01:06:33 +02:00
|
|
|
add_unreads("topic 6", 6);
|
|
|
|
add_unreads("topic 7", 7);
|
2020-01-18 12:06:56 +01:00
|
|
|
|
|
|
|
list_info = get_list_info();
|
|
|
|
assert.equal(list_info.items.length, 8);
|
2022-08-21 23:05:56 +02:00
|
|
|
assert.equal(list_info.more_topics_unreads, 10);
|
|
|
|
assert.equal(list_info.more_topics_have_unread_mention_messages, true);
|
2020-01-18 12:06:56 +01:00
|
|
|
assert.equal(list_info.num_possible_topics, 15);
|
|
|
|
|
|
|
|
assert.deepEqual(
|
2020-07-02 01:39:34 +02:00
|
|
|
list_info.items.map((li) => li.topic_name),
|
2020-07-15 00:34:28 +02:00
|
|
|
["topic 0", "topic 1", "topic 2", "topic 3", "topic 4", "topic 6", "topic 7", "topic 8"],
|
|
|
|
);
|
2020-01-18 12:48:04 +01:00
|
|
|
|
2022-07-10 01:06:33 +02:00
|
|
|
add_unreads("topic 4", 4);
|
|
|
|
add_unreads("topic 5", 5);
|
|
|
|
add_unreads("topic 13", 13);
|
2020-01-18 12:48:04 +01:00
|
|
|
|
2022-08-14 15:33:13 +02:00
|
|
|
override(user_topics, "is_topic_muted", (stream_id, topic_name) => {
|
2020-01-18 12:48:04 +01:00
|
|
|
assert.equal(stream_id, general.stream_id);
|
2020-07-15 01:29:15 +02:00
|
|
|
return topic_name === "topic 4";
|
2021-02-24 17:24:06 +01:00
|
|
|
});
|
2020-01-18 12:48:04 +01:00
|
|
|
|
|
|
|
list_info = get_list_info();
|
|
|
|
assert.equal(list_info.items.length, 8);
|
2022-08-21 23:05:56 +02:00
|
|
|
assert.equal(list_info.more_topics_unreads, 10 + 13);
|
|
|
|
assert.equal(list_info.more_topics_have_unread_mention_messages, true);
|
2020-01-18 12:48:04 +01:00
|
|
|
assert.equal(list_info.num_possible_topics, 15);
|
|
|
|
|
|
|
|
assert.deepEqual(
|
2020-07-02 01:39:34 +02:00
|
|
|
list_info.items.map((li) => li.topic_name),
|
2020-07-15 00:34:28 +02:00
|
|
|
["topic 0", "topic 1", "topic 2", "topic 3", "topic 5", "topic 6", "topic 7", "topic 8"],
|
|
|
|
);
|
2020-01-18 12:06:56 +01:00
|
|
|
});
|