text: /**
   * @license
   * Copyright (C) 2015 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  import '../../../test/common-test-setup-karma.js';
  import './gr-search-bar.js';
  import '../../../scripts/util.js';
  import {TestKeyboardShortcutBinder} from '../../../test/test-utils.js';
  import {Shortcut} from '../../../mixins/keyboard-shortcut-mixin/keyboard-shortcut-mixin.js';
  import {_testOnly_clearDocsBaseUrlCache} from '../../../utils/url-util.js';
  
  const basicFixture = fixtureFromElement('gr-search-bar');
  
  suite('gr-search-bar tests', () => {
    let element;
  
    suiteSetup(() => {
      const kb = TestKeyboardShortcutBinder.push();
      kb.bindShortcut(Shortcut.SEARCH, '/');
    });
  
    suiteTeardown(() => {
      TestKeyboardShortcutBinder.pop();
    });
  
    setup(done => {
      element = basicFixture.instantiate();
      flush(done);
    });
  
    test('value is propagated to _inputVal', () => {
      element.value = 'foo';
      assert.equal(element._inputVal, 'foo');
    });
  
    const getActiveElement = () => (document.activeElement.shadowRoot ?
      document.activeElement.shadowRoot.activeElement :
      document.activeElement);
  
    test('enter in search input fires event', done => {
      element.addEventListener('handle-search', () => {
        assert.notEqual(getActiveElement(), element.$.searchInput);
        assert.notEqual(getActiveElement(), element.$.searchButton);
        done();
      });
      element.value = 'test';
      MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13,
          null, 'enter');
    });
  
    test('input blurred after commit', () => {
      const blurSpy = sinon.spy(element.$.searchInput.$.input, 'blur');
      element.$.searchInput.text = 'fate/stay';
      MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13,
          null, 'enter');
      assert.isTrue(blurSpy.called);
    });
  
    test('empty search query does not trigger nav', () => {
      const searchSpy = sinon.spy();
      element.addEventListener('handle-search', searchSpy);
      element.value = '';
      MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13,
          null, 'enter');
      assert.isFalse(searchSpy.called);
    });
  
    test('Predefined query op with no predication doesnt trigger nav', () => {
      const searchSpy = sinon.spy();
      element.addEventListener('handle-search', searchSpy);
      element.value = 'added:';
      MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13,
          null, 'enter');
      assert.isFalse(searchSpy.called);
    });
  
    test('predefined predicate query triggers nav', () => {
      const searchSpy = sinon.spy();
      element.addEventListener('handle-search', searchSpy);
      element.value = 'age:1week';
      MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13,
          null, 'enter');
      assert.isTrue(searchSpy.called);
    });
  
    test('undefined predicate query triggers nav', () => {
      const searchSpy = sinon.spy();
      element.addEventListener('handle-search', searchSpy);
      element.value = 'random:1week';
      MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13,
          null, 'enter');
      assert.isTrue(searchSpy.called);
    });
  
    test('empty undefined predicate query triggers nav', () => {
      const searchSpy = sinon.spy();
      element.addEventListener('handle-search', searchSpy);
      element.value = 'random:';
      MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13,
          null, 'enter');
      assert.isTrue(searchSpy.called);
    });
  
    test('keyboard shortcuts', () => {
      const focusSpy = sinon.spy(element.$.searchInput, 'focus');
      const selectAllSpy = sinon.spy(element.$.searchInput, 'selectAll');
      MockInteractions.pressAndReleaseKeyOn(document.body, 191, null, '/');
      assert.isTrue(focusSpy.called);
      assert.isTrue(selectAllSpy.called);
    });
  
    suite('_getSearchSuggestions', () => {
      test('Autocompletes accounts', () => {
        sinon.stub(element, 'accountSuggestions').callsFake(() =>
          Promise.resolve([{text: 'owner:fred@goog.co'}])
        );
        return element._getSearchSuggestions('owner:fr').then(s => {
          assert.equal(s[0].value, 'owner:fred@goog.co');
        });
      });
  
      test('Autocompletes groups', done => {
        sinon.stub(element, 'groupSuggestions').callsFake(() =>
          Promise.resolve([
            {text: 'ownerin:Polygerrit'},
            {text: 'ownerin:gerrit'},
          ])
        );
        element._getSearchSuggestions('ownerin:pol').then(s => {
          assert.equal(s[0].value, 'ownerin:Polygerrit');
          done();
        });
      });
  
      test('Autocompletes projects', done => {
        sinon.stub(element, 'projectSuggestions').callsFake(() =>
          Promise.resolve([
            {text: 'project:Polygerrit'},
            {text: 'project:gerrit'},
            {text: 'project:gerrittest'},
          ])
        );
        element._getSearchSuggestions('project:pol').then(s => {
          assert.equal(s[0].value, 'project:Polygerrit');
          done();
        });
      });
  
      test('Autocompletes simple searches', done => {
        element._getSearchSuggestions('is:o').then(s => {
          assert.equal(s[0].name, 'is:open');
          assert.equal(s[0].value, 'is:open');
          assert.equal(s[1].name, 'is:owner');
          assert.equal(s[1].value, 'is:owner');
          done();
        });
      });
  
      test('Does not autocomplete with no match', done => {
        element._getSearchSuggestions('asdasdasdasd').then(s => {
          assert.equal(s.length, 0);
          done();
        });
      });
  
      test('Autocompletes without is:mergable when disabled', async () => {
        const s = await element._getSearchSuggestions('is:mergeab');
        assert.isEmpty(s);
      });
    });
  
    [
      'API_REF_UPDATED_AND_CHANGE_REINDEX',
      'REF_UPDATED_AND_CHANGE_REINDEX',
    ].forEach(mergeability => {
      suite(`mergeability as ${mergeability}`, () => {
        setup(done => {
          stub('gr-rest-api-interface', {
            getConfig() {
              return Promise.resolve({
                change: {
                  mergeability_computation_behavior: mergeability,
                },
              });
            },
          });
  
          element = basicFixture.instantiate();
          flush(done);
        });
  
        test('Autocompltes with is:mergable when enabled', done => {
          element._getSearchSuggestions('is:mergeab').then(s => {
            assert.equal(s.length, 2);
            assert.equal(s[0].name, 'is:mergeable');
            assert.equal(s[0].value, 'is:mergeable');
            assert.equal(s[1].name, '-is:mergeable');
            assert.equal(s[1].value, '-is:mergeable');
            done();
          });
        });
      });
    });
  
    suite('doc url', () => {
      setup(done => {
        stub('gr-rest-api-interface', {
          getConfig() {
            return Promise.resolve({
              gerrit: {
                doc_url: 'https://doc.com/',
              },
            });
          },
        });
  
        _testOnly_clearDocsBaseUrlCache();
        element = basicFixture.instantiate();
        flush(done);
      });
  
      test('compute help doc url with correct path', () => {
        assert.equal(element.docBaseUrl, 'https://doc.com/');
        assert.equal(
            element._computeHelpDocLink(element.docBaseUrl),
            'https://doc.com/user-search.html'
        );
      });
  
      test('compute help doc url fallback to gerrit url', () => {
        assert.equal(
            element._computeHelpDocLink(),
            'https://gerrit-review.googlesource.com/documentation/' +
            'user-search.html'
        );
      });
    });
  });
  
  