diff --git a/frontend_tests/node_tests/search.js b/frontend_tests/node_tests/search.js new file mode 100644 index 0000000000..c5ba1eae61 --- /dev/null +++ b/frontend_tests/node_tests/search.js @@ -0,0 +1,270 @@ +zrequire('search'); + +const noop = () => {}; +const return_true = () => true; +const return_false = () => false; + +set_global('$', global.make_zjquery()); +set_global('narrow_state', {}); +set_global('search_suggestion', {}); +set_global('ui_util', { + change_tab_to: noop, +}); +set_global('narrow', {}); +set_global('Filter', {}); + +global.patch_builtin('setTimeout', func => func()); + +run_test('update_button_visibility', () => { + const search_query = $('#search_query'); + const search_button = $('.search_button'); + + search_query.is = return_false; + search_query.val(''); + narrow_state.active = return_false; + search_button.prop('disabled', false); + search.update_button_visibility(); + assert(search_button.prop('disabled')); + + search_query.is = return_true; + search_query.val(''); + narrow_state.active = return_false; + search_button.prop('disabled', true); + search.update_button_visibility(); + assert(!search_button.prop('disabled')); + + search_query.is = return_false; + search_query.val('Test search term'); + narrow_state.active = return_false; + search_button.prop('disabled', true); + search.update_button_visibility(); + assert(!search_button.prop('disabled')); + + search_query.is = return_false; + search_query.val(''); + narrow_state.active = return_true; + search_button.prop('disabled', true); + search.update_button_visibility(); + assert(!search_button.prop('disabled')); +}); + +run_test('initizalize', () => { + const search_query_box = $('#search_query'); + const searchbox_form = $('#searchbox_form'); + const search_button = $('.search_button'); + + searchbox_form.on = (event, func) => { + assert.equal(event, 'compositionend'); + search.is_using_input_method = false; + func(); + assert(search.is_using_input_method); + }; + + search_query_box.typeahead = (opts) => { + assert.equal(opts.fixed, true); + assert.equal(opts.items, 12); + assert.equal(opts.naturalSearch, true); + assert.equal(opts.helpOnEmptyStrings, true); + assert.equal(opts.matcher(), true); + + { + const search_suggestions = { + lookup_table: { + 'stream:Verona': { + description: 'Stream Verona', + 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 Verona'; + 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; + search_query_box.blur = () => { + is_blurred = true; + }; + /* Test updater */ + const _setup = (search_box_val) => { + is_blurred = 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'}); + }; + }; + + operators = [{ + negated: false, + operator: 'search', + operand: 'ver', + }]; + _setup('ver'); + assert.equal(opts.updater('ver'), 'ver'); + assert(is_blurred); + + operators = [{ + negated: false, + operator: 'stream', + operand: 'Verona', + }]; + _setup('stream:Verona'); + assert.equal(opts.updater('stream:Verona'), 'stream:Verona'); + assert(is_blurred); + + search.is_using_input_method = true; + _setup('stream:Verona'); + assert.equal(opts.updater('stream:Verona'), 'stream:Verona'); + assert(!is_blurred); + } + }; + + searchbox_form.keydown = (func) => { + const ev = { + which: 15, + }; + search_query_box.is = return_false; + assert.equal(func(ev), undefined); + + ev.which = 13; + assert.equal(func(ev), undefined); + + ev.which = 13; + search_query_box.is = return_true; + assert.equal(func(ev), false); + + return search_query_box; + }; + + search_query_box.keyup = (func) => { + const ev = {}; + let operators; + let is_blurred; + narrow_state.active = return_false; + search_query_box.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'}); + }; + }; + + + operators = [{ + negated: false, + operator: 'search', + operand: '', + }]; + _setup(''); + + ev.which = 15; + search_query_box.is = return_false; + func(ev); + + assert(!is_blurred); + assert(!search_button.prop('disabled')); + + ev.which = 13; + search_query_box.is = return_false; + func(ev); + + assert(!is_blurred); + assert(!search_button.prop('disabled')); + + ev.which = 13; + search_query_box.is = return_true; + func(ev); + assert(is_blurred); + assert(search_button.prop('disabled')); + + + _setup('ver'); + search.is_using_input_method = true; + func(ev); + // No change on enter keyup event when using input tool + assert(!is_blurred); + assert(!search_button.prop('disabled')); + + + _setup('ver'); + ev.which = 13; + search_query_box.is = return_true; + func(ev); + assert(is_blurred); + assert(!search_button.prop('disabled')); + }; + + search_query_box.on = (event, callback) => { + if (event === 'focus') { + search_button.prop('disabled', true); + callback(); + assert(!search_button.prop('disabled')); + } else if (event === 'blur') { + search_query_box.val("test string"); + narrow_state.search_string = () => 'ver'; + callback(); + assert.equal(search_query_box.val(), 'ver'); + } + }; + + $('#search_exit').on = (event, callback) => { + assert.equal(event, 'click'); + let is_deactivated = false; + let is_blurred = false; + narrow.deactivate = () => { + is_deactivated = true; + }; + search_query_box.blur = () => { + is_blurred = true; + }; + callback(); + assert(is_blurred); + assert(is_deactivated); + }; + + search.initialize(); +}); + +run_test('initiate_search', () => { + let is_searchbox_selected = false; + $('#search_query').select = () => { + is_searchbox_selected = true; + }; + search.initiate_search(); + assert(is_searchbox_selected); +}); diff --git a/tools/test-js-with-node b/tools/test-js-with-node index dfe92f6bee..3b6f7c467e 100755 --- a/tools/test-js-with-node +++ b/tools/test-js-with-node @@ -56,6 +56,7 @@ enforce_fully_covered = { 'static/js/rtl.js', 'static/js/schema.js', 'static/js/scroll_util.js', + 'static/js/search.js', 'static/js/search_suggestion.js', # Removed because we're migrating code from uncovered other settings pages to here. # 'static/js/settings_ui.js',