<!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-change-list</title>

<script src="../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../bower_components/web-component-tester/browser.js"></script>
<script src="../bower_components/page/page.js"></script>
<script src="../scripts/fake-app.js"></script>
<script src="../scripts/util.js"></script>

<link rel="import" href="../bower_components/iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="../elements/gr-change-list.html">

<test-fixture id="basic">
  <template>
    <gr-change-list></gr-change-list>
  </template>
</test-fixture>

<test-fixture id="grouped">
  <template>
    <gr-change-list></gr-change-list>
  </template>
</test-fixture>

<script>
  suite('gr-change-list basic tests', function() {
    var element;

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

    test('computed fields', function() {
      assert.equal(element._computeLabelNames(
          [[{_number: 0, labels: {}}]]).length, 0);
      assert.equal(element._computeLabelNames([[
            {_number: 0, labels: {Verified: {approved: {}}}},
            {_number: 1, labels: {
              Verified: {approved: {}}, 'Code-Review': {approved: {}}}},
            {_number: 2, labels: {
              Verified: {approved: {}}, 'Library-Compliance': {approved: {}}}},
          ]]).length, 3);

      assert.equal(element._computeLabelShortcut('Code-Review'), 'CR');
      assert.equal(element._computeLabelShortcut('Verified'), 'V');
      assert.equal(element._computeLabelShortcut('Library-Compliance'), 'LC');
      assert.equal(element._computeLabelShortcut(
          'Some-Special-Label-7'), 'SSL7');
    });

    test('keyboard shortcuts', function(done) {
      element.selectedIndex = 0;
      element.changes = [
        {_number: 0},
        {_number: 1},
        {_number: 2},
      ];
      flushAsynchronousOperations();
      var elementItems = Polymer.dom(element.root).querySelectorAll(
          'gr-change-list-item');
      assert.equal(elementItems.length, 3);

      element.async(function() {
        assert.isTrue(elementItems[0].selected);
        MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'
        assert.equal(element.selectedIndex, 1);
        MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'

        var showStub = sinon.stub(page, 'show');
        assert.equal(element.selectedIndex, 2);
        MockInteractions.pressAndReleaseKeyOn(element, 13);  // 'enter'
        assert(showStub.lastCall.calledWithExactly('/c/2/'),
            'Should navigate to /c/2/');

        MockInteractions.pressAndReleaseKeyOn(element, 75);  // 'k'
        assert.equal(element.selectedIndex, 1);
        MockInteractions.pressAndReleaseKeyOn(element, 13);  // 'enter'
        assert(showStub.lastCall.calledWithExactly('/c/1/'),
            'Should navigate to /c/1/');

        MockInteractions.pressAndReleaseKeyOn(element, 75);  // 'k'
        MockInteractions.pressAndReleaseKeyOn(element, 75);  // 'k'
        MockInteractions.pressAndReleaseKeyOn(element, 75);  // 'k'
        assert.equal(element.selectedIndex, 0);

        showStub.restore();
        done();
      }, 1);
    });

    test('unreviewed changes', function() {
      element.changes = [
        {
          _number: 0,
          reviewed: true,
        },
        {
          _number: 1,
        },
        {
          _number: 2,
          status: 'MERGED',
        },
      ];
      flushAsynchronousOperations();
      var elementItems = Polymer.dom(element.root).querySelectorAll(
          'gr-change-list-item');
      assert.equal(elementItems.length, 3);
      for (var i = 0; i < elementItems.length; i++) {
        assert.isFalse(elementItems[i].hasAttribute('unreviewed'));
      }

      element.showReviewedState = true;
      var elementItems = Polymer.dom(element.root).querySelectorAll(
          'gr-change-list-item');
      assert.equal(elementItems.length, 3);
      assert.isFalse(elementItems[0].hasAttribute('unreviewed'));
      assert.isTrue(elementItems[1].hasAttribute('unreviewed'));
      assert.isFalse(elementItems[2].hasAttribute('unreviewed'));
    });

  });

  suite('gr-change-list groups', function() {
    var element;

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

    test('keyboard shortcuts', function() {
      element.selectedIndex = 0;
      element.groups = [
        [
          {_number: 0},
          {_number: 1},
          {_number: 2},
        ],
        [
          {_number: 3},
          {_number: 4},
          {_number: 5},
        ],
        [
          {_number: 6},
          {_number: 7},
          {_number: 8},
        ]
      ];
      element.groupTitles = ['Group 1', 'Group 2', 'Group 3'];
      flushAsynchronousOperations();
      var elementItems = Polymer.dom(element.root).querySelectorAll(
          'gr-change-list-item');
      assert.equal(elementItems.length, 9);

      MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'
      assert.equal(element.selectedIndex, 1);
      MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'

      var showStub = sinon.stub(page, 'show');
      assert.equal(element.selectedIndex, 2);
      MockInteractions.pressAndReleaseKeyOn(element, 13);  // 'enter'
      assert(showStub.lastCall.calledWithExactly('/c/2/'),
          'Should navigate to /c/2/');

      MockInteractions.pressAndReleaseKeyOn(element, 75);  // 'k'
      assert.equal(element.selectedIndex, 1);
      MockInteractions.pressAndReleaseKeyOn(element, 13);  // 'enter'
      assert(showStub.lastCall.calledWithExactly('/c/1/'),
          'Should navigate to /c/1/');

      MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'
      MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'
      MockInteractions.pressAndReleaseKeyOn(element, 74);  // 'j'
      assert.equal(element.selectedIndex, 4);
      MockInteractions.pressAndReleaseKeyOn(element, 13);  // 'enter'
      assert(showStub.lastCall.calledWithExactly('/c/4/'),
          'Should navigate to /c/4/');
      showStub.restore();
    });

  });
</script>
