<!DOCTYPE html>
<!--
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.
-->

<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-search-bar</title>

<script src="../../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<script src="../../../bower_components/page/page.js"></script>

<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="gr-search-bar.html">
<script src="../../../scripts/util.js"></script>

<test-fixture id="basic">
  <template>
    <gr-search-bar></gr-search-bar>
  </template>
</test-fixture>

<script>
  suite('gr-search-bar tests', function() {
    var element;

    setup(function() {
      element = fixture('basic');
    });

    test('value is propagated to _inputVal', function() {
      element.value = 'foo';
      assert.equal(element._inputVal, 'foo');
    });

    function getActiveElement() {
      return document.activeElement.shadowRoot ?
          document.activeElement.shadowRoot.activeElement :
          document.activeElement;
    }

    test('tap on search button triggers nav', function(done) {
      sinon.stub(page, 'show', function() {
        page.show.restore();
        assert.notEqual(getActiveElement(), element.$.searchInput);
        assert.notEqual(getActiveElement(), element.$.searchButton);
        done();
      });
      MockInteractions.tap(element.$.searchButton);
    });

    test('enter in search input triggers nav', function(done) {
      sinon.stub(page, 'show', function() {
        page.show.restore();
        assert.notEqual(getActiveElement(), element.$.searchInput);
        assert.notEqual(getActiveElement(), element.$.searchButton);
        done();
      });
      MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13);
    });

    test('search query should be double-escaped', function() {
      var showStub = sinon.stub(page, 'show');
      element.$.searchInput.text = 'fate/stay';
      MockInteractions.pressAndReleaseKeyOn(element.$.searchInput.$.input, 13);
      assert.equal(showStub.lastCall.args[0], '/q/fate%252Fstay');
      showStub.restore();
    });

    suite('_getSearchSuggestions',
        function() {
      setup(function() {
        sinon.stub(element.$.restAPI, 'getSuggestedAccounts', function() {
          return Promise.resolve([
            {
              name: 'fred',
              email: 'fred@goog.co',
            },
          ]);
        });
        sinon.stub(element.$.restAPI, 'getSuggestedGroups', function() {
          return Promise.resolve({
            Polygerrit: 0,
          });
        });
        sinon.stub(element.$.restAPI, 'getSuggestedProjects', function() {
          return Promise.resolve({
            Polygerrit: 0,
          });
        });
      });

      teardown(function() {
        element.$.restAPI.getSuggestedAccounts.restore();
        element.$.restAPI.getSuggestedGroups.restore();
        element.$.restAPI.getSuggestedProjects.restore();
      });

      test('Autocompletes accounts',
          function(done) {
        return element._getSearchSuggestions('owner:fr')
            .then(function(suggestions) {
              assert.equal(suggestions[0].value, 'owner:"fred <fred@goog.co>"');
              done();
            });
      });

      test('Autocompletes groups',
          function(done) {
        return element._getSearchSuggestions('ownerin:pol')
            .then(function(suggestions) {
              assert.equal(suggestions[0].value, 'ownerin:Polygerrit');
              done();
            });
      });

      test('Autocompletes projects',
          function(done) {
        return element._getSearchSuggestions('project:pol')
            .then(function(suggestions) {
              assert.equal(suggestions[0].value, 'project:Polygerrit');
              done();
            });
      });

      test('Autocompletes simple searches',
          function(done) {
        return element._getSearchSuggestions('is:o')
            .then(function(suggestions) {
              assert.equal(suggestions[0].name, 'is:open');
              assert.equal(suggestions[0].value, 'is:open');
              assert.equal(suggestions[1].name, 'is:owner');
              assert.equal(suggestions[1].value, 'is:owner');
              done();
            });
      });

      test('Does not autocomplete with no match',
          function(done) {
        return element._getSearchSuggestions('asdasdasdasd')
            .then(function(suggestions) {
              assert.equal(suggestions.length, 0);
              done();
            });
      });
    });
  });
</script>
