blob: d8db7887b1d916bc05e0a54535a4835ad456ca78 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// 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');
});
});
});