<!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-file-list</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>
<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-file-list.html">

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

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

    setup(function() {
      element = fixture('basic');
      server = sinon.fakeServer.create();
      server.respondWith(
        'GET',
        '/changes/42/revisions/1/files',
        [
          200,
          {'Content-Type': 'application/json'},
          ')]}\'\n' +
          JSON.stringify({
            '/COMMIT_MSG': {
              status: 'A',
              lines_inserted: 9,
              size_delta: 317,
              size: 317
            },
            'myfile.txt': {
              lines_inserted: 35,
              size_delta: 1146,
              size: 1167
            }
          }),
        ]
      );
      server.respondWith(
        'GET',
        '/changes/42/revisions/2/files',
        [
          200,
          {'Content-Type': 'application/json'},
          ')]}\'\n' +
          JSON.stringify({
            '/COMMIT_MSG': {
              status: 'A',
              lines_inserted: 9,
              size_delta: 317,
              size: 317
            },
            'myfile.txt': {
              lines_inserted: 35,
              size_delta: 1146,
              size: 1167
            },
            'file_added_in_rev2.txt': {
              lines_inserted: 98,
              size_delta: 234,
              size: 136
            }
          }),
        ]
      );
    });

    teardown(function() {
      server.restore();
    });

    test('requests', function(done) {
      element.changeNum = '42';
      element.patchNum = '1';
      element.reload();
      server.respond();

      element.async(function() {
        var filenames = element.files.map(function(f) {
          return f.__path;
        });
        assert.deepEqual(filenames, ['/COMMIT_MSG', 'myfile.txt']);

        element.patchNum = '2';
        element.reload();
        server.respond();
        element.async(function() {
          filenames = element.files.map(function(f) {
            return f.__path;
          });
          assert.deepEqual(filenames,
              ['/COMMIT_MSG', 'file_added_in_rev2.txt', 'myfile.txt']);
          done();
        }, 1);
      }, 1);
    });

    test('keyboard shortcuts', function(done) {
      element.changeNum = '42';
      element.patchNum = '2';
      element.selectedIndex = 0;
      element.reload();
      server.respond();

      element.async(function() {
        var elementItems = Polymer.dom(element.root).querySelectorAll(
            '.fileRow');
        assert.equal(elementItems.length, 3);
        assert.isTrue(elementItems[0].hasAttribute('selected'));
        assert.isFalse(elementItems[1].hasAttribute('selected'));
        assert.isFalse(elementItems[2].hasAttribute('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.calledWith('/c/42/2/myfile.txt'),
            'Should navigate to /c/42/2/myfile.txt');

        MockInteractions.pressAndReleaseKeyOn(element, 75);  // 'k'
        assert.equal(element.selectedIndex, 1);
        MockInteractions.pressAndReleaseKeyOn(element, 79);  // 'o'
        assert(showStub.lastCall.calledWith('/c/42/2/file_added_in_rev2.txt'),
            'Should navigate to /c/42/2/file_added_in_rev2.txt');

        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('comment filtering', function() {
      var comments = {
        '/COMMIT_MSG': [
          {patch_set: 1, message: 'Done'},
          {patch_set: 1, message: 'oh hay'},
          {patch_set: 2, message: 'hello'},
        ],
        'myfile.txt': [
          {patch_set: 1, message: 'good news!'},
          {patch_set: 2, message: 'wat!?'},
          {patch_set: 2, message: 'hi'},
        ],
      };
      assert.equal(
          element._computeCommentsString(comments, '1', '/COMMIT_MSG'),
          '2 comments');
      assert.equal(
          element._computeCommentsString(comments, '1', 'myfile.txt'),
          '1 comment');
      assert.equal(
          element._computeCommentsString(comments, '1',
              'file_added_in_rev2.txt'),
          '');
      assert.equal(
          element._computeCommentsString(comments, '2', '/COMMIT_MSG'),
          '1 comment');
      assert.equal(
          element._computeCommentsString(comments, '2', 'myfile.txt'),
          '2 comments');
      assert.equal(
          element._computeCommentsString(comments, '2',
              'file_added_in_rev2.txt'),
          '');
    });
  });
</script>
