zulip/frontend_tests/node_tests/search.js
Steve Howell 94ffef4de9 zjquery: Eliminate css() helper.
We use css() pretty rarely in our codebase, and
it can sometimes be used mistakenly, when a better
alternative is to toggle a class for external css.

It's hard to support the full API in zjquery, so
we just punt and tell folks to create their own
stubs.

Most of the existing tests that were "fixed" here
weren't actually verifying the behavior of the css()
calls, and for those I just create no-op stubs.

In a few places I verify that css() was called as
expected.
2021-06-04 20:08:19 -07:00

361 lines
11 KiB
JavaScript

"use strict";
const {strict: assert} = require("assert");
const {mock_cjs, mock_esm, set_global, zrequire} = require("../zjsunit/namespace");
const {run_test} = require("../zjsunit/test");
const $ = require("../zjsunit/zjquery");
const {page_params} = require("../zjsunit/zpage_params");
const noop = () => {};
mock_cjs("jquery", $);
const narrow = mock_esm("../../static/js/narrow");
const narrow_state = mock_esm("../../static/js/narrow_state", {
filter: () => false,
});
const search_suggestion = mock_esm("../../static/js/search_suggestion");
mock_esm("../../static/js/search_pill_widget", {
widget: {
getByID: () => true,
},
});
mock_esm("../../static/js/ui_util", {
change_tab_to: noop,
place_caret_at_end: noop,
});
set_global("setTimeout", (func) => func());
const search = zrequire("search");
const search_pill = zrequire("search_pill");
const {Filter} = zrequire("../js/filter");
function test(label, f) {
run_test(label, (override) => {
page_params.search_pills_enabled = true;
f(override);
});
}
test("clear_search_form", () => {
$("#search_query").val("noise");
$("#search_query").trigger("focus");
$(".search_button").prop("disabled", false);
search.clear_search_form();
assert.equal($("#search_query").is_focused(), false);
assert.equal($("#search_query").val(), "");
assert.equal($(".search_button").prop("disabled"), true);
});
test("update_button_visibility", () => {
const search_query = $("#search_query");
const search_button = $(".search_button");
search_query.is = () => false;
search_query.val("");
narrow_state.active = () => false;
search_button.prop("disabled", true);
search.update_button_visibility();
assert(search_button.prop("disabled"));
search_query.is = () => true;
search_query.val("");
narrow_state.active = () => false;
search_button.prop("disabled", true);
search.update_button_visibility();
assert(!search_button.prop("disabled"));
search_query.is = () => false;
search_query.val("Test search term");
narrow_state.active = () => false;
search_button.prop("disabled", true);
search.update_button_visibility();
assert(!search_button.prop("disabled"));
search_query.is = () => false;
search_query.val("");
narrow_state.active = () => true;
search_button.prop("disabled", true);
search.update_button_visibility();
assert(!search_button.prop("disabled"));
});
test("initialize", () => {
const search_query_box = $("#search_query");
const searchbox_form = $("#searchbox_form");
const search_button = $(".search_button");
const searchbox = $("#searchbox");
search_query_box[0] = "stub";
search_pill.get_search_string_for_current_filter = () => "is:starred";
search_suggestion.max_num_of_search_results = 99;
search_query_box.typeahead = (opts) => {
assert.equal(opts.fixed, true);
assert.equal(opts.items, 99);
assert.equal(opts.naturalSearch, true);
assert.equal(opts.helpOnEmptyStrings, true);
assert.equal(opts.matcher(), true);
opts.on_move();
{
const search_suggestions = {
lookup_table: new Map([
[
"stream:Verona",
{
description: "Stream <strong>Ver</strong>ona",
search_string: "stream:Verona",
},
],
[
"ver",
{
description: "Search for ver",
search_string: "ver",
},
],
]),
strings: ["ver", "stream:Verona"],
};
/* Test source */
search_suggestion.get_suggestions = () => search_suggestions;
const expected_source_value = search_suggestions.strings;
const source = opts.source("ver");
assert.equal(source, expected_source_value);
/* Test highlighter */
let expected_value = "Search for ver";
assert.equal(opts.highlighter(source[0]), expected_value);
expected_value = "Stream <strong>Ver</strong>ona";
assert.equal(opts.highlighter(source[1]), expected_value);
/* Test sorter */
assert.equal(opts.sorter(search_suggestions.strings), search_suggestions.strings);
}
{
let operators;
let is_blurred;
let is_append_search_string_called;
search_query_box.on("blur", () => {
is_blurred = true;
});
search_pill.append_search_string = () => {
is_append_search_string_called = true;
};
/* Test updater */
const _setup = (search_box_val) => {
is_blurred = false;
is_append_search_string_called = false;
search_query_box.val(search_box_val);
Filter.parse = (search_string) => {
assert.equal(search_string, search_box_val);
return operators;
};
narrow.activate = (raw_operators, options) => {
assert.deepEqual(raw_operators, operators);
assert.deepEqual(options, {trigger: "search"});
};
search_pill.get_search_string_for_current_filter = () => search_box_val;
};
operators = [
{
negated: false,
operator: "search",
operand: "ver",
},
];
_setup("ver");
assert.equal(opts.updater("ver"), "ver");
assert(!is_blurred);
assert(is_append_search_string_called);
operators = [
{
negated: false,
operator: "stream",
operand: "Verona",
},
];
_setup("stream:Verona");
assert.equal(opts.updater("stream:Verona"), "stream:Verona");
assert(!is_blurred);
assert(is_append_search_string_called);
search.__Rewire__("is_using_input_method", true);
_setup("stream:Verona");
assert.equal(opts.updater("stream:Verona"), "stream:Verona");
assert(!is_blurred);
assert(is_append_search_string_called);
search_query_box.off("blur");
}
};
search.initialize();
const search_pill_stub = $.create(".pill");
search_pill_stub.closest = () => ({data: noop});
const stub_event = {
relatedTarget: search_pill_stub,
};
search_query_box.val("test string");
narrow_state.search_string = () => "ver";
search_query_box.trigger(new $.Event("blur", stub_event));
assert.equal(search_query_box.val(), "test string");
let css_args;
searchbox.css = (args) => {
css_args = args;
};
searchbox.trigger("focusout");
assert.deepEqual(css_args, {"box-shadow": "unset"});
search.__Rewire__("is_using_input_method", false);
searchbox_form.trigger("compositionend");
assert(search.is_using_input_method);
const keydown = searchbox_form.get_on_handler("keydown");
let default_prevented = false;
let ev = {
type: "keydown",
key: "a",
preventDefault() {
default_prevented = true;
},
};
search_query_box.is = () => false;
assert.equal(keydown(ev), undefined);
assert(!default_prevented);
ev.key = "Enter";
assert.equal(keydown(ev), undefined);
assert(!default_prevented);
ev.key = "Enter";
search_query_box.is = () => true;
assert.equal(keydown(ev), undefined);
assert(default_prevented);
let operators;
let is_blurred;
narrow_state.active = () => false;
search_query_box.off("blur");
search_query_box.on("blur", () => {
is_blurred = true;
});
const _setup = (search_box_val) => {
is_blurred = false;
search_button.prop("disabled", false);
search_query_box.val(search_box_val);
Filter.parse = (search_string) => {
assert.equal(search_string, search_box_val);
return operators;
};
narrow.activate = (raw_operators, options) => {
assert.deepEqual(raw_operators, operators);
assert.deepEqual(options, {trigger: "search"});
};
search_pill.get_search_string_for_current_filter = () => search_box_val;
};
operators = [
{
negated: false,
operator: "search",
operand: "",
},
];
_setup("");
ev = {
type: "keyup",
which: 15,
};
search_query_box.is = () => false;
searchbox_form.trigger(ev);
assert(!is_blurred);
assert(!search_button.prop("disabled"));
ev.key = "Enter";
search_query_box.is = () => false;
searchbox_form.trigger(ev);
assert(!is_blurred);
assert(!search_button.prop("disabled"));
ev.key = "Enter";
search_query_box.is = () => true;
searchbox_form.trigger(ev);
assert(is_blurred);
_setup("ver");
search.__Rewire__("is_using_input_method", true);
searchbox_form.trigger(ev);
// No change on Enter keyup event when using input tool
assert(!is_blurred);
assert(!search_button.prop("disabled"));
_setup("ver");
ev.key = "Enter";
search_query_box.is = () => true;
searchbox_form.trigger(ev);
assert(is_blurred);
assert(!search_button.prop("disabled"));
search_button.prop("disabled", true);
search_query_box.trigger("focus");
assert(!search_button.prop("disabled"));
});
test("initiate_search", () => {
// open typeahead and select text when navbar is open
// this implicitly expects the code to used the chained
// function calls, which is something to keep in mind if
// this test ever fails unexpectedly.
let typeahead_forced_open = false;
let is_searchbox_text_selected = false;
let is_searchbox_focused = false;
$("#search_query").off("focus");
$("#search_query").on("focus", () => {
is_searchbox_focused = true;
});
$("#search_query").typeahead = (lookup) => {
if (lookup === "lookup") {
typeahead_forced_open = true;
}
return $("#search_query");
};
$("#search_query").on("select", () => {
is_searchbox_text_selected = true;
});
$("#search_query")[0] = "stub";
const searchbox = $("#searchbox");
let css_args;
searchbox.css = (args) => {
css_args = args;
};
search.initiate_search();
assert(typeahead_forced_open);
assert(is_searchbox_text_selected);
assert(is_searchbox_focused);
assert.deepEqual(css_args, {"box-shadow": "inset 0px 0px 0px 2px hsl(204, 20%, 74%)"});
});