Project import generated by Copybara.
GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/static_src/elements/framework/mr-header/mr-search-bar.test.js b/static_src/elements/framework/mr-header/mr-search-bar.test.js
new file mode 100644
index 0000000..c758a41
--- /dev/null
+++ b/static_src/elements/framework/mr-header/mr-search-bar.test.js
@@ -0,0 +1,244 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {assert} from 'chai';
+import sinon from 'sinon';
+
+import {MrSearchBar} from './mr-search-bar.js';
+import {prpcClient} from 'prpc-client-instance.js';
+import {issueRefToUrl} from 'shared/convertersV0.js';
+import {clientLoggerFake} from 'shared/test/fakes.js';
+
+
+window.CS_env = {
+ token: 'foo-token',
+};
+
+let element;
+
+describe('mr-search-bar', () => {
+ beforeEach(() => {
+ element = document.createElement('mr-search-bar');
+ document.body.appendChild(element);
+ });
+
+ afterEach(() => {
+ document.body.removeChild(element);
+ });
+
+ it('initializes', () => {
+ assert.instanceOf(element, MrSearchBar);
+ });
+
+ it('render user saved queries', async () => {
+ element.userDisplayName = 'test@user.com';
+ element.userSavedQueries = [
+ {name: 'test query', queryId: 101},
+ {name: 'hello world', queryId: 202},
+ ];
+
+ await element.updateComplete;
+
+ const queryOptions = element.shadowRoot.querySelectorAll(
+ '.user-query');
+
+ assert.equal(queryOptions.length, 2);
+
+ assert.equal(queryOptions[0].value, '101');
+ assert.equal(queryOptions[0].textContent, 'test query');
+
+ assert.equal(queryOptions[1].value, '202');
+ assert.equal(queryOptions[1].textContent, 'hello world');
+ });
+
+ it('render project saved queries', async () => {
+ element.userDisplayName = 'test@user.com';
+ element.projectSavedQueries = [
+ {name: 'test query', queryId: 101},
+ {name: 'hello world', queryId: 202},
+ ];
+
+ await element.updateComplete;
+
+ const queryOptions = element.shadowRoot.querySelectorAll(
+ '.project-query');
+
+ assert.equal(queryOptions.length, 2);
+
+ assert.equal(queryOptions[0].value, '101');
+ assert.equal(queryOptions[0].textContent, 'test query');
+
+ assert.equal(queryOptions[1].value, '202');
+ assert.equal(queryOptions[1].textContent, 'hello world');
+ });
+
+ it('search input resets form value when initialQuery changes', async () => {
+ element.initialQuery = 'first query';
+ await element.updateComplete;
+
+ const queryInput = element.shadowRoot.querySelector('#searchq');
+
+ assert.equal(queryInput.value, 'first query');
+
+ // Simulate a user typing something into the search form.
+ queryInput.value = 'blah';
+
+ element.initialQuery = 'second query';
+ await element.updateComplete;
+
+ // 'blah' disappears because the new initialQuery causes the form to
+ // reset.
+ assert.equal(queryInput.value, 'second query');
+ });
+
+ it('unrelated property changes do not reset query form', async () => {
+ element.initialQuery = 'first query';
+ await element.updateComplete;
+
+ const queryInput = element.shadowRoot.querySelector('#searchq');
+
+ assert.equal(queryInput.value, 'first query');
+
+ // Simulate a user typing something into the search form.
+ queryInput.value = 'blah';
+
+ element.initialCan = '5';
+ await element.updateComplete;
+
+ assert.equal(queryInput.value, 'blah');
+ });
+
+ it('spell check is off for search bar', async () => {
+ await element.updateComplete;
+ const searchElement = element.shadowRoot.querySelector('#searchq');
+ assert.equal(searchElement.getAttribute('spellcheck'), 'false');
+ });
+
+ describe('search form submit', () => {
+ let prpcClientStub;
+ beforeEach(() => {
+ element.clientLogger = clientLoggerFake();
+
+ element._page = sinon.stub();
+ sinon.stub(window, 'open');
+
+ element.projectName = 'chromium';
+ prpcClientStub = sinon.stub(prpcClient, 'call');
+ });
+
+ afterEach(() => {
+ window.open.restore();
+ prpcClient.call.restore();
+ });
+
+ it('prevents default', async () => {
+ await element.updateComplete;
+
+ const form = element.shadowRoot.querySelector('form');
+
+ // Note: HTMLFormElement's submit function does not run submit handlers
+ // but clicking a submit buttons programmatically works.
+ const event = new Event('submit');
+ sinon.stub(event, 'preventDefault');
+ form.dispatchEvent(event);
+
+ sinon.assert.calledOnce(event.preventDefault);
+ });
+
+ it('uses initial values when no form changes', async () => {
+ element.initialQuery = 'test query';
+ element.initialCan = '3';
+
+ await element.updateComplete;
+
+ const form = element.shadowRoot.querySelector('form');
+
+ form.dispatchEvent(new Event('submit'));
+
+ sinon.assert.calledOnce(element._page);
+ sinon.assert.calledWith(element._page,
+ '/p/chromium/issues/list?q=test%20query&can=3');
+ });
+
+ it('adds form values to url', async () => {
+ await element.updateComplete;
+
+ const form = element.shadowRoot.querySelector('form');
+
+ form.q.value = 'test';
+ form.can.value = '1';
+
+ form.dispatchEvent(new Event('submit'));
+
+ sinon.assert.calledOnce(element._page);
+ sinon.assert.calledWith(element._page,
+ '/p/chromium/issues/list?q=test&can=1');
+ });
+
+ it('trims query', async () => {
+ await element.updateComplete;
+
+ const form = element.shadowRoot.querySelector('form');
+
+ form.q.value = ' abc ';
+ form.can.value = '1';
+
+ form.dispatchEvent(new Event('submit'));
+
+ sinon.assert.calledOnce(element._page);
+ sinon.assert.calledWith(element._page,
+ '/p/chromium/issues/list?q=abc&can=1');
+ });
+
+ it('jumps to issue for digit-only query', async () => {
+ prpcClientStub.returns(Promise.resolve({issue: 'hello world'}));
+
+ await element.updateComplete;
+
+ const form = element.shadowRoot.querySelector('form');
+
+ form.q.value = '123';
+ form.can.value = '1';
+
+ form.dispatchEvent(new Event('submit'));
+
+ await element._navigateToNext;
+
+ const expected = issueRefToUrl('hello world', {q: '123', can: '1'});
+ sinon.assert.calledWith(element._page, expected);
+ });
+
+ it('only keeps kept query params', async () => {
+ element.queryParams = {fakeParam: 'test', x: 'Status'};
+ element.keptParams = ['x'];
+
+ await element.updateComplete;
+
+ const form = element.shadowRoot.querySelector('form');
+
+ form.dispatchEvent(new Event('submit'));
+
+ sinon.assert.calledOnce(element._page);
+ sinon.assert.calledWith(element._page,
+ '/p/chromium/issues/list?x=Status&q=&can=2');
+ });
+
+ it('on shift+enter opens search in new tab', async () => {
+ await element.updateComplete;
+
+ const form = element.shadowRoot.querySelector('form');
+
+ form.q.value = 'test';
+ form.can.value = '1';
+
+ // Dispatch event from an input in the form.
+ form.q.dispatchEvent(new KeyboardEvent('keypress',
+ {key: 'Enter', shiftKey: true, bubbles: true}));
+
+ sinon.assert.calledOnce(window.open);
+ sinon.assert.calledWith(window.open,
+ '/p/chromium/issues/list?q=test&can=1', '_blank', 'noopener');
+ });
+ });
+});