2018-03-22 23:34:40 +01:00
|
|
|
set_global('$', global.make_zjquery());
|
|
|
|
set_global('document', 'document-stub');
|
|
|
|
|
|
|
|
zrequire('message_fetch');
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const noop = () => {};
|
2018-03-22 23:34:40 +01:00
|
|
|
|
|
|
|
set_global('MessageListView', function () { return {}; });
|
|
|
|
|
|
|
|
zrequire('FetchStatus', 'js/fetch_status');
|
|
|
|
zrequire('Filter', 'js/filter');
|
2018-05-04 12:44:28 +02:00
|
|
|
zrequire('MessageListData', 'js/message_list_data');
|
2018-03-22 23:34:40 +01:00
|
|
|
zrequire('message_list');
|
2019-07-11 18:54:28 +02:00
|
|
|
zrequire('people');
|
2018-03-22 23:34:40 +01:00
|
|
|
|
|
|
|
set_global('page_params', {
|
|
|
|
have_initial_messages: true,
|
|
|
|
pointer: 444,
|
|
|
|
});
|
2018-02-25 13:01:38 +01:00
|
|
|
set_global('ui_report', {
|
|
|
|
hide_error: noop,
|
|
|
|
});
|
2018-03-22 23:34:40 +01:00
|
|
|
set_global('activity', {});
|
|
|
|
set_global('channel', {});
|
|
|
|
set_global('document', 'document-stub');
|
|
|
|
set_global('message_util', {});
|
|
|
|
set_global('message_store', {});
|
2018-03-23 17:32:24 +01:00
|
|
|
set_global('narrow_state', {});
|
2018-10-01 20:27:22 +02:00
|
|
|
set_global('notifications', {
|
|
|
|
hide_or_show_history_limit_message: () => {},
|
|
|
|
});
|
2018-03-22 23:34:40 +01:00
|
|
|
set_global('pm_list', {});
|
|
|
|
set_global('resize', {});
|
|
|
|
set_global('server_events', {});
|
2018-07-06 20:23:20 +02:00
|
|
|
set_global('stream_list', {
|
|
|
|
maybe_scroll_narrow_into_view: () => {},
|
|
|
|
});
|
2018-03-22 23:34:40 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const alice = {
|
2019-07-11 18:54:28 +02:00
|
|
|
email: 'alice@example.com',
|
|
|
|
user_id: 7,
|
|
|
|
full_name: 'Alice',
|
|
|
|
};
|
|
|
|
people.add(alice);
|
|
|
|
|
2018-03-22 23:34:40 +01:00
|
|
|
resize.resize_bottom_whitespace = noop;
|
|
|
|
server_events.home_view_loaded = noop;
|
|
|
|
|
|
|
|
function stub_message_view(list) {
|
|
|
|
list.view.append = noop;
|
|
|
|
list.view.maybe_rerender = noop;
|
|
|
|
list.view.prepend = noop;
|
|
|
|
}
|
|
|
|
|
|
|
|
function make_home_msg_list() {
|
2019-11-02 00:06:25 +01:00
|
|
|
const table_name = 'whatever';
|
|
|
|
const filter = new Filter();
|
2018-03-22 23:34:40 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const list = new message_list.MessageList({
|
2018-05-14 15:46:25 +02:00
|
|
|
table_name: table_name,
|
|
|
|
filter: filter,
|
|
|
|
});
|
2018-03-22 23:34:40 +01:00
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
function make_all_list() {
|
2018-05-14 15:46:25 +02:00
|
|
|
return new message_list.MessageList({});
|
2018-03-22 23:34:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function reset_lists() {
|
|
|
|
set_global('home_msg_list', make_home_msg_list());
|
|
|
|
set_global('current_msg_list', home_msg_list);
|
|
|
|
message_list.all = make_all_list();
|
|
|
|
stub_message_view(home_msg_list);
|
|
|
|
stub_message_view(message_list.all);
|
|
|
|
}
|
|
|
|
|
|
|
|
function config_fake_channel(conf) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const self = {};
|
|
|
|
let called;
|
2018-03-22 23:34:40 +01:00
|
|
|
|
|
|
|
channel.get = function (opts) {
|
|
|
|
if (called) {
|
|
|
|
throw "only use this for one call";
|
|
|
|
}
|
|
|
|
assert(self.success === undefined);
|
|
|
|
assert.equal(opts.url, '/json/messages');
|
|
|
|
assert.deepEqual(opts.data, conf.expected_opts_data);
|
|
|
|
self.success = opts.success;
|
|
|
|
called = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
function config_process_results(messages) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const self = {};
|
2018-03-22 23:34:40 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const messages_processed_for_bools = [];
|
2018-03-22 23:34:40 +01:00
|
|
|
|
|
|
|
message_store.set_message_booleans = function (message) {
|
|
|
|
messages_processed_for_bools.push(message);
|
|
|
|
};
|
|
|
|
|
2020-02-08 01:27:04 +01:00
|
|
|
message_store.add_message_metadata = message => message;
|
|
|
|
|
2018-03-22 23:34:40 +01:00
|
|
|
message_util.do_unread_count_updates = function (arg) {
|
|
|
|
assert.deepEqual(arg, messages);
|
|
|
|
};
|
|
|
|
|
2019-01-08 01:26:02 +01:00
|
|
|
message_util.add_old_messages = function (new_messages, msg_list) {
|
2018-03-22 23:34:40 +01:00
|
|
|
assert.deepEqual(new_messages, messages);
|
2019-01-08 01:26:02 +01:00
|
|
|
msg_list.add_messages(new_messages);
|
2018-03-22 23:34:40 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
activity.process_loaded_messages = function (arg) {
|
|
|
|
assert.deepEqual(arg, messages);
|
|
|
|
};
|
|
|
|
|
|
|
|
stream_list.update_streams_sidebar = noop;
|
|
|
|
|
|
|
|
pm_list.update_private_messages = noop;
|
|
|
|
|
|
|
|
self.verify = function () {
|
|
|
|
assert.deepEqual(messages_processed_for_bools, messages);
|
|
|
|
};
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
function message_range(start, end) {
|
js: Convert _.map(a, …) to a.map(…).
And convert the corresponding function expressions to arrow style
while we’re here.
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 K from "ast-types/gen/kinds";
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);
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;
recast.visit(ast, {
visitCallExpression(path) {
const { callee, arguments: args } = path.node;
if (
n.MemberExpression.check(callee) &&
!callee.computed &&
n.Identifier.check(callee.object) &&
callee.object.name === "_" &&
n.Identifier.check(callee.property) &&
callee.property.name === "map" &&
args.length === 2 &&
checkExpression(args[0]) &&
checkExpression(args[1])
) {
const [arr, fn] = args;
path.replace(
b.callExpression(b.memberExpression(arr, b.identifier("map")), [
n.FunctionExpression.check(fn) ||
n.ArrowFunctionExpression.check(fn)
? b.arrowFunctionExpression(
fn.params,
n.BlockStatement.check(fn.body) &&
fn.body.body.length === 1 &&
n.ReturnStatement.check(fn.body.body[0])
? fn.body.body[0].argument || b.identifier("undefined")
: fn.body
)
: fn,
])
);
changed = true;
}
this.traverse(path);
},
});
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-08 02:43:49 +01:00
|
|
|
return _.range(start, end).map(idx => ({
|
|
|
|
id: idx,
|
|
|
|
}));
|
2018-03-22 23:34:40 +01:00
|
|
|
}
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const initialize_data = {
|
2018-03-22 23:34:40 +01:00
|
|
|
initial_fetch: {
|
|
|
|
req: {
|
|
|
|
anchor: 444,
|
|
|
|
num_before: 200,
|
|
|
|
num_after: 200,
|
|
|
|
client_gravatar: true,
|
|
|
|
},
|
|
|
|
resp: {
|
|
|
|
messages: message_range(201, 801),
|
|
|
|
found_newest: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
forward_fill: {
|
|
|
|
req: {
|
|
|
|
anchor: '800',
|
|
|
|
num_before: 0,
|
|
|
|
num_after: 1000,
|
|
|
|
client_gravatar: true,
|
|
|
|
},
|
|
|
|
resp: {
|
|
|
|
messages: message_range(800, 1000),
|
|
|
|
found_newest: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
back_fill: {
|
|
|
|
req: {
|
|
|
|
anchor: '201',
|
|
|
|
num_before: 1000,
|
|
|
|
num_after: 0,
|
|
|
|
client_gravatar: true,
|
|
|
|
},
|
|
|
|
resp: {
|
|
|
|
messages: message_range(100, 200),
|
|
|
|
found_oldest: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
function test_fetch_success(opts) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const response = opts.response;
|
|
|
|
const messages = response.messages;
|
2018-03-22 23:34:40 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const process_results = config_process_results(messages);
|
2018-03-22 23:34:40 +01:00
|
|
|
opts.fetch.success(response);
|
|
|
|
process_results.verify();
|
|
|
|
}
|
|
|
|
|
|
|
|
function initial_fetch_step() {
|
2019-11-02 00:06:25 +01:00
|
|
|
const self = {};
|
2018-03-22 23:34:40 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
let fetch;
|
|
|
|
const response = initialize_data.initial_fetch.resp;
|
2018-03-22 23:34:40 +01:00
|
|
|
|
|
|
|
self.prep = function () {
|
|
|
|
fetch = config_fake_channel({
|
|
|
|
expected_opts_data: initialize_data.initial_fetch.req,
|
|
|
|
});
|
|
|
|
|
|
|
|
message_fetch.initialize();
|
|
|
|
};
|
|
|
|
|
|
|
|
self.finish = function () {
|
|
|
|
test_fetch_success({
|
|
|
|
fetch: fetch,
|
|
|
|
response: response,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
function forward_fill_step() {
|
2019-11-02 00:06:25 +01:00
|
|
|
const self = {};
|
2018-03-22 23:34:40 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
let fetch;
|
2018-03-22 23:34:40 +01:00
|
|
|
|
|
|
|
self.prep = function () {
|
|
|
|
fetch = config_fake_channel({
|
|
|
|
expected_opts_data: initialize_data.forward_fill.req,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
self.finish = function () {
|
2019-11-02 00:06:25 +01:00
|
|
|
const response = initialize_data.forward_fill.resp;
|
2018-03-22 23:34:40 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
let idle_config;
|
2018-03-22 23:34:40 +01:00
|
|
|
$('document-stub').idle = function (config) {
|
|
|
|
idle_config = config;
|
|
|
|
};
|
|
|
|
|
|
|
|
test_fetch_success({
|
|
|
|
fetch: fetch,
|
|
|
|
response: response,
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(idle_config.idle, 10000);
|
|
|
|
|
|
|
|
return idle_config;
|
|
|
|
};
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_backfill_idle(idle_config) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const fetch = config_fake_channel({
|
2018-03-22 23:34:40 +01:00
|
|
|
expected_opts_data: initialize_data.back_fill.req,
|
|
|
|
});
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const response = initialize_data.back_fill.resp;
|
2018-03-22 23:34:40 +01:00
|
|
|
|
|
|
|
idle_config.onIdle();
|
|
|
|
|
|
|
|
test_fetch_success({
|
|
|
|
fetch: fetch,
|
|
|
|
response: response,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-05-15 12:40:07 +02:00
|
|
|
run_test('initialize', () => {
|
2018-03-22 23:34:40 +01:00
|
|
|
reset_lists();
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const step1 = initial_fetch_step();
|
2018-03-22 23:34:40 +01:00
|
|
|
|
|
|
|
step1.prep();
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const step2 = forward_fill_step();
|
2018-03-22 23:34:40 +01:00
|
|
|
|
|
|
|
step2.prep();
|
|
|
|
step1.finish();
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const idle_config = step2.finish();
|
2018-03-22 23:34:40 +01:00
|
|
|
|
|
|
|
test_backfill_idle(idle_config);
|
2018-05-15 12:40:07 +02:00
|
|
|
});
|
2018-03-23 17:32:24 +01:00
|
|
|
|
|
|
|
function simulate_narrow() {
|
2019-11-02 00:06:25 +01:00
|
|
|
const filter = {
|
2020-02-08 03:20:02 +01:00
|
|
|
predicate: () => () => false,
|
2018-03-23 17:32:24 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
narrow_state.active = function () { return true; };
|
|
|
|
narrow_state.public_operators = function () {
|
2019-07-11 18:54:28 +02:00
|
|
|
return [{ operator: 'pm-with', operand: alice.email }];
|
2018-03-23 17:32:24 +01:00
|
|
|
};
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const msg_list = new message_list.MessageList({
|
2018-05-14 15:46:25 +02:00
|
|
|
table_name: 'zfilt',
|
|
|
|
filter: filter,
|
|
|
|
});
|
2018-03-23 17:32:24 +01:00
|
|
|
set_global('current_msg_list', msg_list);
|
|
|
|
|
|
|
|
return msg_list;
|
|
|
|
}
|
|
|
|
|
2018-05-15 12:40:07 +02:00
|
|
|
run_test('loading_newer', () => {
|
2018-03-23 17:32:24 +01:00
|
|
|
function test_dup_new_fetch(msg_list) {
|
|
|
|
assert.equal(msg_list.fetch_status.can_load_newer_messages(), false);
|
|
|
|
message_fetch.maybe_load_newer_messages({
|
|
|
|
msg_list: msg_list,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function test_happy_path(opts) {
|
2019-11-02 00:06:25 +01:00
|
|
|
const msg_list = opts.msg_list;
|
|
|
|
const data = opts.data;
|
2018-03-23 17:32:24 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const fetch = config_fake_channel({
|
2018-03-23 17:32:24 +01:00
|
|
|
expected_opts_data: data.req,
|
|
|
|
});
|
|
|
|
|
|
|
|
message_fetch.maybe_load_newer_messages({
|
|
|
|
msg_list: msg_list,
|
|
|
|
});
|
|
|
|
|
|
|
|
test_dup_new_fetch(msg_list);
|
|
|
|
|
|
|
|
test_fetch_success({
|
|
|
|
fetch: fetch,
|
|
|
|
response: data.resp,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
(function test_narrow() {
|
2019-11-02 00:06:25 +01:00
|
|
|
const msg_list = simulate_narrow();
|
2018-03-23 17:32:24 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const data = {
|
2018-03-23 17:32:24 +01:00
|
|
|
req: {
|
|
|
|
anchor: '444',
|
|
|
|
num_before: 0,
|
|
|
|
num_after: 100,
|
2019-07-11 18:54:28 +02:00
|
|
|
narrow: `[{"operator":"pm-with","operand":[${alice.user_id}]}]`,
|
2018-03-23 17:32:24 +01:00
|
|
|
client_gravatar: true,
|
|
|
|
},
|
|
|
|
resp: {
|
|
|
|
messages: message_range(500, 600),
|
|
|
|
found_newest: false,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
test_happy_path({
|
|
|
|
msg_list: msg_list,
|
|
|
|
data: data,
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(msg_list.fetch_status.can_load_newer_messages(), true);
|
|
|
|
}());
|
|
|
|
|
|
|
|
(function test_home() {
|
|
|
|
reset_lists();
|
2019-11-02 00:06:25 +01:00
|
|
|
const msg_list = home_msg_list;
|
2018-03-23 17:32:24 +01:00
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const data = [
|
2018-03-23 17:32:24 +01:00
|
|
|
{
|
|
|
|
req: {
|
|
|
|
anchor: '444',
|
|
|
|
num_before: 0,
|
|
|
|
num_after: 100,
|
|
|
|
client_gravatar: true,
|
|
|
|
},
|
|
|
|
resp: {
|
|
|
|
messages: message_range(500, 600),
|
|
|
|
found_newest: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
req: {
|
|
|
|
anchor: '599',
|
|
|
|
num_before: 0,
|
|
|
|
num_after: 100,
|
|
|
|
client_gravatar: true,
|
|
|
|
},
|
|
|
|
resp: {
|
|
|
|
messages: message_range(700, 800),
|
|
|
|
found_newest: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
test_happy_path({
|
|
|
|
msg_list: msg_list,
|
|
|
|
data: data[0],
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(msg_list.fetch_status.can_load_newer_messages(), true);
|
|
|
|
|
|
|
|
test_happy_path({
|
|
|
|
msg_list: msg_list,
|
|
|
|
data: data[1],
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(msg_list.fetch_status.can_load_newer_messages(), false);
|
|
|
|
|
|
|
|
}());
|
|
|
|
|
2018-05-15 12:40:07 +02:00
|
|
|
});
|