zulip/frontend_tests/node_tests/search_suggestion_legacy.js
Tim Abbott 3d6af7a3c8 typeahead: Fetch stream topic history from server.
Long ago, we changed Zulip to inspect server-provided topic history in
our compose and search typeahead modules, but did not trigger a query
to the server to fetch data.

This could result in confusing experiences where someone thought that
a topic doesn't exist that just isn't present in recent history.

Once we merge this, we may want to adjust the messaging in typeahead
to advertise that the first option will create a new topic, since this
change may make it feel more like creating topics is a heavyweight
operation.

Fixes #9857.
2021-05-12 15:21:25 -07:00

860 lines
29 KiB
JavaScript

"use strict";
const {strict: assert} = require("assert");
const {mock_esm, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
const {page_params} = require("../zjsunit/zpage_params");
const stream_topic_history_util = mock_esm("../../static/js/stream_topic_history_util");
const settings_config = zrequire("settings_config");
const huddle_data = zrequire("huddle_data");
const narrow_state = zrequire("narrow_state");
const stream_data = zrequire("stream_data");
const stream_topic_history = zrequire("stream_topic_history");
const people = zrequire("people");
const search = zrequire("search_suggestion");
search.__Rewire__("max_num_of_search_results", 15);
const me = {
email: "[email protected]",
full_name: "Me Myself",
user_id: 41,
};
const bob = {
email: "[email protected]",
full_name: "Bob Roberts",
user_id: 42,
};
const ted = {
email: "[email protected]",
user_id: 101,
full_name: "Ted Smith",
};
const alice = {
email: "[email protected]",
user_id: 102,
full_name: "Alice Ignore",
};
const jeff = {
email: "[email protected]",
user_id: 103,
full_name: "Jeff Zoolipson",
};
function init() {
page_params.is_admin = true;
page_params.search_pills_enabled = false;
page_params.realm_email_address_visibility =
settings_config.email_address_visibility_values.admins_only.code;
people.init();
people.add_active_user(bob);
people.add_active_user(me);
people.add_active_user(ted);
people.add_active_user(alice);
people.add_active_user(jeff);
people.initialize_current_user(me.user_id);
stream_topic_history.reset();
huddle_data.clear_for_testing();
}
function get_suggestions(base_query, query) {
return search.get_suggestions(base_query, query);
}
function test(label, f) {
run_test(label, (override) => {
init();
f(override);
});
}
test("basic_get_suggestions", (override) => {
const query = "fred";
override(stream_data, "subscribed_streams", () => []);
override(narrow_state, "stream", () => "office");
const suggestions = get_suggestions("", query);
const expected = ["fred"];
assert.deepEqual(suggestions.strings, expected);
});
test("subset_suggestions", () => {
const query = "stream:Denmark topic:Hamlet shakespeare";
const suggestions = get_suggestions("", query);
const expected = [
"stream:Denmark topic:Hamlet shakespeare",
"stream:Denmark topic:Hamlet",
"stream:Denmark",
];
assert.deepEqual(suggestions.strings, expected);
});
test("private_suggestions", () => {
let query = "is:private";
let suggestions = get_suggestions("", query);
let expected = [
"is:private",
"pm-with:[email protected]",
"pm-with:[email protected]",
"pm-with:[email protected]",
"pm-with:[email protected]",
"pm-with:[email protected]",
];
assert.deepEqual(suggestions.strings, expected);
query = "is:private al";
suggestions = get_suggestions("", query);
expected = [
"is:private al",
"is:private is:alerted",
"is:private sender:[email protected]",
"is:private pm-with:[email protected]",
"is:private group-pm-with:[email protected]",
"is:private",
];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:t";
suggestions = get_suggestions("", query);
expected = ["pm-with:t", "pm-with:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:t";
suggestions = get_suggestions("", query);
expected = ["-pm-with:t", "is:private -pm-with:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:[email protected]";
suggestions = get_suggestions("", query);
expected = ["pm-with:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "sender:ted";
suggestions = get_suggestions("", query);
expected = ["sender:ted", "sender:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "sender:te";
suggestions = get_suggestions("", query);
expected = ["sender:te", "sender:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "-sender:te";
suggestions = get_suggestions("", query);
expected = ["-sender:te", "-sender:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "sender:[email protected]";
suggestions = get_suggestions("", query);
expected = ["sender:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "is:unread from:ted";
suggestions = get_suggestions("", query);
expected = ["is:unread from:ted", "is:unread from:[email protected]", "is:unread"];
assert.deepEqual(suggestions.strings, expected);
// Users can enter bizarre queries, and if they do, we want to
// be conservative with suggestions.
query = "is:private near:3";
suggestions = get_suggestions("", query);
expected = ["is:private near:3", "is:private"];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:[email protected] near:3";
suggestions = get_suggestions("", query);
expected = ["pm-with:[email protected] near:3", "pm-with:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
// Make sure suggestions still work if preceding tokens
query = "is:alerted sender:[email protected]";
suggestions = get_suggestions("", query);
expected = ["is:alerted sender:[email protected]", "is:alerted"];
assert.deepEqual(suggestions.strings, expected);
query = "is:starred has:link is:private al";
suggestions = get_suggestions("", query);
expected = [
"is:starred has:link is:private al",
"is:starred has:link is:private is:alerted",
"is:starred has:link is:private sender:[email protected]",
"is:starred has:link is:private pm-with:[email protected]",
"is:starred has:link is:private group-pm-with:[email protected]",
"is:starred has:link is:private",
"is:starred has:link",
"is:starred",
];
assert.deepEqual(suggestions.strings, expected);
// Make sure it handles past context correctly
query = "stream:Denmark pm-with:";
suggestions = get_suggestions("", query);
expected = ["stream:Denmark pm-with:", "stream:Denmark"];
assert.deepEqual(suggestions.strings, expected);
query = "sender:[email protected] sender:";
suggestions = get_suggestions("", query);
expected = ["sender:[email protected] sender:", "sender:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
});
test("group_suggestions", () => {
// Entering a comma in a pm-with query should immediately generate
// suggestions for the next person.
let query = "pm-with:[email protected],";
let suggestions = get_suggestions("", query);
let expected = [
"pm-with:[email protected],",
"pm-with:[email protected],[email protected]",
"pm-with:[email protected],[email protected]",
"pm-with:[email protected],[email protected]",
];
assert.deepEqual(suggestions.strings, expected);
// Only the last part of a comma-separated pm-with query should be used to
// generate suggestions.
query = "pm-with:[email protected],t";
suggestions = get_suggestions("", query);
expected = ["pm-with:[email protected],t", "pm-with:[email protected],[email protected]"];
assert.deepEqual(suggestions.strings, expected);
// Smit should also generate [email protected] (Ted Smith) as a suggestion.
query = "pm-with:[email protected],Smit";
suggestions = get_suggestions("", query);
expected = ["pm-with:[email protected],Smit", "pm-with:[email protected],[email protected]"];
assert.deepEqual(suggestions.strings, expected);
// Do not suggest "[email protected]" (the name of the current user)
query = "pm-with:[email protected],my";
suggestions = get_suggestions("", query);
expected = ["pm-with:[email protected],my"];
assert.deepEqual(suggestions.strings, expected);
// No superfluous suggestions should be generated.
query = "pm-with:[email protected],red";
suggestions = get_suggestions("", query);
expected = ["pm-with:[email protected],red"];
assert.deepEqual(suggestions.strings, expected);
// is:private should be properly prepended to each suggestion if the pm-with
// operator is negated.
query = "-pm-with:[email protected],";
suggestions = get_suggestions("", query);
expected = [
"-pm-with:[email protected],",
"is:private -pm-with:[email protected],[email protected]",
"is:private -pm-with:[email protected],[email protected]",
"is:private -pm-with:[email protected],[email protected]",
];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:[email protected],t";
suggestions = get_suggestions("", query);
expected = ["-pm-with:[email protected],t", "is:private -pm-with:[email protected],[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:[email protected],Smit";
suggestions = get_suggestions("", query);
expected = ["-pm-with:[email protected],Smit", "is:private -pm-with:[email protected],[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:[email protected],red";
suggestions = get_suggestions("", query);
expected = ["-pm-with:[email protected],red"];
assert.deepEqual(suggestions.strings, expected);
// Test multiple operators
query = "is:starred has:link pm-with:[email protected],Smit";
suggestions = get_suggestions("", query);
expected = [
"is:starred has:link pm-with:[email protected],Smit",
"is:starred has:link pm-with:[email protected],[email protected]",
"is:starred has:link",
"is:starred",
];
assert.deepEqual(suggestions.strings, expected);
query = "stream:Denmark has:link pm-with:[email protected],Smit";
suggestions = get_suggestions("", query);
expected = [
"stream:Denmark has:link pm-with:[email protected],Smit",
"stream:Denmark has:link",
"stream:Denmark",
];
assert.deepEqual(suggestions.strings, expected);
function message(user_ids, timestamp) {
return {
type: "private",
display_recipient: user_ids.map((id) => ({
id,
})),
timestamp,
};
}
huddle_data.process_loaded_messages([
message([bob.user_id, ted.user_id], 99),
message([bob.user_id, ted.user_id, jeff.user_id], 98),
]);
// Simulate a past huddle which should now prioritize ted over alice
query = "pm-with:[email protected],";
suggestions = get_suggestions("", query);
expected = [
"pm-with:[email protected],",
"pm-with:[email protected],[email protected]",
"pm-with:[email protected],[email protected]",
"pm-with:[email protected],[email protected]",
];
assert.deepEqual(suggestions.strings, expected);
// bob,ted,jeff is already an existing huddle, so prioritize this one
query = "pm-with:[email protected],[email protected],";
suggestions = get_suggestions("", query);
expected = [
"pm-with:[email protected],[email protected],",
"pm-with:[email protected],[email protected],[email protected]",
"pm-with:[email protected],[email protected],[email protected]",
];
assert.deepEqual(suggestions.strings, expected);
// bob,ted,jeff is already an existing huddle, but if we start with just jeff,
// then don't prioritize ted over alice because it doesn't complete the full huddle.
query = "pm-with:[email protected],";
suggestions = get_suggestions("", query);
expected = [
"pm-with:[email protected],",
"pm-with:[email protected],[email protected]",
"pm-with:[email protected],[email protected]",
"pm-with:[email protected],[email protected]",
];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:[email protected],[email protected] hi";
suggestions = get_suggestions("", query);
expected = ["pm-with:[email protected],[email protected] hi", "pm-with:[email protected],[email protected]"];
assert.deepEqual(suggestions.strings, expected);
});
test("empty_query_suggestions", (override) => {
const query = "";
override(stream_data, "subscribed_streams", () => ["devel", "office"]);
const suggestions = get_suggestions("", query);
const expected = [
"",
"streams:public",
"is:private",
"is:starred",
"is:mentioned",
"is:alerted",
"is:unread",
"sender:[email protected]",
"stream:devel",
"stream:office",
"has:link",
"has:image",
"has:attachment",
];
assert.deepEqual(suggestions.strings, expected);
function describe(q) {
return suggestions.lookup_table.get(q).description;
}
assert.equal(describe("is:private"), "Private messages");
assert.equal(describe("is:starred"), "Starred messages");
assert.equal(describe("is:mentioned"), "@-mentions");
assert.equal(describe("is:alerted"), "Alerted messages");
assert.equal(describe("is:unread"), "Unread messages");
assert.equal(describe("sender:[email protected]"), "Sent by me");
assert.equal(describe("has:link"), "Messages with one or more link");
assert.equal(describe("has:image"), "Messages with one or more image");
assert.equal(describe("has:attachment"), "Messages with one or more attachment");
});
test("has_suggestions", (override) => {
// Checks that category wise suggestions are displayed instead of a single
// default suggestion when suggesting `has` operator.
let query = "h";
override(stream_data, "subscribed_streams", () => ["devel", "office"]);
override(narrow_state, "stream", () => {});
let suggestions = get_suggestions("", query);
let expected = ["h", "has:link", "has:image", "has:attachment"];
assert.deepEqual(suggestions.strings, expected);
function describe(q) {
return suggestions.lookup_table.get(q).description;
}
assert.equal(describe("has:link"), "Messages with one or more link");
assert.equal(describe("has:image"), "Messages with one or more image");
assert.equal(describe("has:attachment"), "Messages with one or more attachment");
query = "-h";
suggestions = get_suggestions("", query);
expected = ["-h", "-has:link", "-has:image", "-has:attachment"];
assert.deepEqual(suggestions.strings, expected);
assert.equal(describe("-has:link"), "Exclude messages with one or more link");
assert.equal(describe("-has:image"), "Exclude messages with one or more image");
assert.equal(describe("-has:attachment"), "Exclude messages with one or more attachment");
// operand suggestions follow.
query = "has:";
suggestions = get_suggestions("", query);
expected = ["has:link", "has:image", "has:attachment"];
assert.deepEqual(suggestions.strings, expected);
query = "has:im";
suggestions = get_suggestions("", query);
expected = ["has:image"];
assert.deepEqual(suggestions.strings, expected);
query = "-has:im";
suggestions = get_suggestions("", query);
expected = ["-has:image"];
assert.deepEqual(suggestions.strings, expected);
query = "att";
suggestions = get_suggestions("", query);
expected = ["att", "has:attachment"];
assert.deepEqual(suggestions.strings, expected);
query = "stream:Denmark is:alerted has:lin";
suggestions = get_suggestions("", query);
expected = [
"stream:Denmark is:alerted has:link",
"stream:Denmark is:alerted",
"stream:Denmark",
];
assert.deepEqual(suggestions.strings, expected);
});
test("check_is_suggestions", (override) => {
override(stream_data, "subscribed_streams", () => ["devel", "office"]);
override(narrow_state, "stream", () => {});
let query = "i";
let suggestions = get_suggestions("", query);
let expected = [
"i",
"is:private",
"is:starred",
"is:mentioned",
"is:alerted",
"is:unread",
"sender:[email protected]",
"pm-with:[email protected]",
"group-pm-with:[email protected]",
"has:image",
];
assert.deepEqual(suggestions.strings, expected);
function describe(q) {
return suggestions.lookup_table.get(q).description;
}
assert.equal(describe("is:private"), "Private messages");
assert.equal(describe("is:starred"), "Starred messages");
assert.equal(describe("is:mentioned"), "@-mentions");
assert.equal(describe("is:alerted"), "Alerted messages");
assert.equal(describe("is:unread"), "Unread messages");
query = "-i";
suggestions = get_suggestions("", query);
expected = ["-i", "-is:private", "-is:starred", "-is:mentioned", "-is:alerted", "-is:unread"];
assert.deepEqual(suggestions.strings, expected);
assert.equal(describe("-is:private"), "Exclude private messages");
assert.equal(describe("-is:starred"), "Exclude starred messages");
assert.equal(describe("-is:mentioned"), "Exclude @-mentions");
assert.equal(describe("-is:alerted"), "Exclude alerted messages");
assert.equal(describe("-is:unread"), "Exclude unread messages");
// operand suggestions follow.
query = "is:";
suggestions = get_suggestions("", query);
expected = ["is:private", "is:starred", "is:mentioned", "is:alerted", "is:unread"];
assert.deepEqual(suggestions.strings, expected);
query = "is:st";
suggestions = get_suggestions("", query);
expected = ["is:starred"];
assert.deepEqual(suggestions.strings, expected);
query = "-is:st";
suggestions = get_suggestions("", query);
expected = ["-is:starred"];
assert.deepEqual(suggestions.strings, expected);
query = "st";
suggestions = get_suggestions("", query);
expected = ["st", "streams:public", "is:starred", "stream:"];
assert.deepEqual(suggestions.strings, expected);
query = "stream:Denmark has:link is:sta";
suggestions = get_suggestions("", query);
expected = ["stream:Denmark has:link is:starred", "stream:Denmark has:link", "stream:Denmark"];
assert.deepEqual(suggestions.strings, expected);
});
test("sent_by_me_suggestions", (override) => {
override(stream_data, "subscribed_streams", () => []);
override(narrow_state, "stream", () => {});
let query = "";
let suggestions = get_suggestions("", query);
assert(suggestions.strings.includes("sender:[email protected]"));
assert.equal(suggestions.lookup_table.get("sender:[email protected]").description, "Sent by me");
query = "sender";
suggestions = get_suggestions("", query);
let expected = ["sender", "sender:[email protected]", "sender:"];
assert.deepEqual(suggestions.strings, expected);
query = "-sender";
suggestions = get_suggestions("", query);
expected = ["-sender", "-sender:[email protected]", "-sender:"];
assert.deepEqual(suggestions.strings, expected);
query = "from";
suggestions = get_suggestions("", query);
expected = ["from", "from:[email protected]", "from:"];
assert.deepEqual(suggestions.strings, expected);
query = "-from";
suggestions = get_suggestions("", query);
expected = ["-from", "-from:[email protected]", "-from:"];
assert.deepEqual(suggestions.strings, expected);
query = "sender:[email protected]";
suggestions = get_suggestions("", query);
expected = ["sender:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "from:[email protected]";
suggestions = get_suggestions("", query);
expected = ["from:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "sent";
suggestions = get_suggestions("", query);
expected = ["sent", "sender:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "-sent";
suggestions = get_suggestions("", query);
expected = ["-sent", "-sender:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
query = "stream:Denmark topic:Denmark1 sent";
suggestions = get_suggestions("", query);
expected = [
"stream:Denmark topic:Denmark1 sent",
"stream:Denmark topic:Denmark1 sender:[email protected]",
"stream:Denmark topic:Denmark1",
"stream:Denmark",
];
assert.deepEqual(suggestions.strings, expected);
query = "is:starred sender:m";
suggestions = get_suggestions("", query);
expected = ["is:starred sender:m", "is:starred sender:[email protected]", "is:starred"];
assert.deepEqual(suggestions.strings, expected);
query = "sender:[email protected] sender:";
suggestions = get_suggestions("", query);
expected = ["sender:[email protected] sender:", "sender:[email protected]"];
assert.deepEqual(suggestions.strings, expected);
});
test("topic_suggestions", (override) => {
let suggestions;
let expected;
override(stream_topic_history_util, "get_server_history", () => {});
override(stream_data, "subscribed_streams", () => ["office"]);
override(narrow_state, "stream", () => "office");
const devel_id = 44;
const office_id = 77;
override(stream_data, "get_stream_id", (stream_name) => {
switch (stream_name) {
case "office":
return office_id;
case "devel":
return devel_id;
default:
return undefined;
}
});
suggestions = get_suggestions("", "te");
expected = [
"te",
"sender:[email protected]",
"pm-with:[email protected]",
"group-pm-with:[email protected]",
];
assert.deepEqual(suggestions.strings, expected);
stream_topic_history.add_message({
stream_id: devel_id,
topic_name: "REXX",
});
for (const topic_name of ["team", "ignore", "test"]) {
stream_topic_history.add_message({
stream_id: office_id,
topic_name,
});
}
suggestions = get_suggestions("", "te");
expected = [
"te",
"sender:[email protected]",
"pm-with:[email protected]",
"group-pm-with:[email protected]",
"stream:office topic:team",
"stream:office topic:test",
];
assert.deepEqual(suggestions.strings, expected);
function describe(q) {
return suggestions.lookup_table.get(q).description;
}
assert.equal(describe("te"), "Search for te");
assert.equal(describe("stream:office topic:team"), "Stream office > team");
suggestions = get_suggestions("", "topic:staplers stream:office");
expected = ["topic:staplers stream:office", "topic:staplers"];
assert.deepEqual(suggestions.strings, expected);
suggestions = get_suggestions("", "stream:devel topic:");
expected = ["stream:devel topic:", "stream:devel topic:REXX", "stream:devel"];
assert.deepEqual(suggestions.strings, expected);
suggestions = get_suggestions("", "stream:devel -topic:");
expected = ["stream:devel -topic:", "stream:devel -topic:REXX", "stream:devel"];
assert.deepEqual(suggestions.strings, expected);
suggestions = get_suggestions("", "-topic:te");
expected = ["-topic:te", "stream:office -topic:team", "stream:office -topic:test"];
assert.deepEqual(suggestions.strings, expected);
suggestions = get_suggestions("", "is:alerted stream:devel is:starred topic:");
expected = [
"is:alerted stream:devel is:starred topic:",
"is:alerted stream:devel is:starred topic:REXX",
"is:alerted stream:devel is:starred",
"is:alerted stream:devel",
"is:alerted",
];
assert.deepEqual(suggestions.strings, expected);
suggestions = get_suggestions("", "is:private stream:devel topic:");
expected = ["is:private stream:devel topic:", "is:private stream:devel", "is:private"];
assert.deepEqual(suggestions.strings, expected);
suggestions = get_suggestions("", "topic:REXX stream:devel topic:");
expected = ["topic:REXX stream:devel topic:", "topic:REXX stream:devel", "topic:REXX"];
assert.deepEqual(suggestions.strings, expected);
});
test("whitespace_glitch", (override) => {
const query = "stream:office "; // note trailing space
override(stream_data, "subscribed_streams", () => ["office"]);
const suggestions = get_suggestions("", query);
const expected = ["stream:office"];
assert.deepEqual(suggestions.strings, expected);
});
test("stream_completion", (override) => {
override(stream_data, "subscribed_streams", () => ["office", "dev help"]);
override(narrow_state, "stream", () => {});
let query = "stream:of";
let suggestions = get_suggestions("", query);
let expected = ["stream:of", "stream:office"];
assert.deepEqual(suggestions.strings, expected);
query = "-stream:of";
suggestions = get_suggestions("", query);
expected = ["-stream:of", "-stream:office"];
assert.deepEqual(suggestions.strings, expected);
query = "hel";
suggestions = get_suggestions("", query);
expected = ["hel", "stream:dev+help"];
assert.deepEqual(suggestions.strings, expected);
});
test("people_suggestions", (override) => {
let query = "te";
override(stream_data, "subscribed_streams", () => []);
override(narrow_state, "stream", () => {});
const ted = {
email: "[email protected]",
user_id: 201,
full_name: "Ted Smith",
};
const bob = {
email: "[email protected]",
user_id: 202,
full_name: "Bob Térry",
};
const alice = {
email: "[email protected]",
user_id: 203,
full_name: "Alice Ignore",
};
people.add_active_user(ted);
people.add_active_user(bob);
people.add_active_user(alice);
let suggestions = get_suggestions("", query);
let expected = [
"te",
"sender:[email protected]",
"sender:[email protected]",
"pm-with:[email protected]", // bob térry
"pm-with:[email protected]",
"group-pm-with:[email protected]",
"group-pm-with:[email protected]",
];
assert.deepEqual(suggestions.strings, expected);
function describe(q) {
return suggestions.lookup_table.get(q).description;
}
assert.equal(
describe("pm-with:[email protected]"),
"Private messages with <strong>Te</strong>d Smith &lt;<strong>te</strong>[email protected]&gt;",
);
assert.equal(
describe("sender:[email protected]"),
"Sent by <strong>Te</strong>d Smith &lt;<strong>te</strong>[email protected]&gt;",
);
suggestions = get_suggestions("", "Ted "); // note space
expected = [
"Ted",
"sender:[email protected]",
"pm-with:[email protected]",
"group-pm-with:[email protected]",
];
assert.deepEqual(suggestions.strings, expected);
query = "sender:ted sm";
expected = ["sender:ted+sm", "sender:[email protected]"];
suggestions = get_suggestions("", query);
assert.deepEqual(suggestions.strings, expected);
query = "sender:[email protected] new";
expected = ["sender:[email protected] new", "sender:[email protected]"];
suggestions = get_suggestions("", query);
assert.deepEqual(suggestions.strings, expected);
query = "sender:[email protected] new";
expected = ["sender:[email protected]+new"];
suggestions = get_suggestions("", query);
assert.deepEqual(suggestions.strings, expected);
});
test("operator_suggestions", () => {
// Completed operator should return nothing
let query = "stream:";
let suggestions = get_suggestions("", query);
let expected = ["stream:"];
assert.deepEqual(suggestions.strings, expected);
query = "st";
suggestions = get_suggestions("", query);
expected = ["st", "streams:public", "is:starred", "stream:"];
assert.deepEqual(suggestions.strings, expected);
query = "group-";
suggestions = get_suggestions("", query);
expected = ["group-", "group-pm-with:"];
assert.deepEqual(suggestions.strings, expected);
query = "-s";
suggestions = get_suggestions("", query);
expected = ["-s", "-streams:public", "-sender:[email protected]", "-stream:", "-sender:"];
assert.deepEqual(suggestions.strings, expected);
query = "stream:Denmark is:alerted -f";
suggestions = get_suggestions("", query);
expected = [
"stream:Denmark is:alerted -f",
"stream:Denmark is:alerted -from:[email protected]",
"stream:Denmark is:alerted -from:",
"stream:Denmark is:alerted",
"stream:Denmark",
];
assert.deepEqual(suggestions.strings, expected);
});
test("queries_with_spaces", (override) => {
override(stream_data, "subscribed_streams", () => ["office", "dev help"]);
// test allowing spaces with quotes surrounding operand
let query = 'stream:"dev he"';
let suggestions = get_suggestions("", query);
let expected = ["stream:dev+he", "stream:dev+help"];
assert.deepEqual(suggestions.strings, expected);
// test mismatched quote
query = 'stream:"dev h';
suggestions = get_suggestions("", query);
expected = ["stream:dev+h", "stream:dev+help"];
assert.deepEqual(suggestions.strings, expected);
// test extra space after operator still works
query = "stream: offi";
suggestions = get_suggestions("", query);
expected = ["stream:offi", "stream:office"];
assert.deepEqual(suggestions.strings, expected);
});