<!DOCTYPE html>
<!--
Copyright (C) 2017 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-header</title>

<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../bower_components/page/page.js"></script>

<link rel="import" href="gr-file-list-header.html">

<script>void(0);</script>

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

<test-fixture id="blank">
  <template>
    <div></div>
  </template>
</test-fixture>

<script>
  suite('gr-file-list-header tests', () => {
    let element;
    let sandbox;
    let navigateToChangeStub;

    setup(() => {
      sandbox = sinon.sandbox.create();
      navigateToChangeStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
      stub('gr-rest-api-interface', {
        getConfig() { return Promise.resolve({test: 'config'}); },
        getAccount() { return Promise.resolve(null); },
        _fetchSharedCacheURL() { return Promise.resolve({}); },
      });
      element = fixture('basic');
    });

    teardown(done => {
      flush(() => {
        sandbox.restore();
        done();
      });
    });

    test('Diff preferences hidden when no prefs or logged out', () => {
      element.loggedIn = false;
      flushAsynchronousOperations();
      assert.isTrue(element.$.diffPrefsContainer.hidden);

      element.loggedIn = true;
      flushAsynchronousOperations();
      assert.isTrue(element.$.diffPrefsContainer.hidden);

      element.loggedIn = false;
      element.diffPrefs = {font_size: '12'};
      flushAsynchronousOperations();
      assert.isTrue(element.$.diffPrefsContainer.hidden);

      element.loggedIn = true;
      flushAsynchronousOperations();
      assert.isFalse(element.$.diffPrefsContainer.hidden);
    });

    test('_computeDescriptionReadOnly', () => {
      assert.equal(element._computeDescriptionReadOnly(false,
          {owner: {_account_id: 1}}, {_account_id: 1}), true);
      assert.equal(element._computeDescriptionReadOnly(true,
          {owner: {_account_id: 0}}, {_account_id: 1}), true);
      assert.equal(element._computeDescriptionReadOnly(true,
          {owner: {_account_id: 1}}, {_account_id: 1}), false);
    });

    test('_computeDescriptionPlaceholder', () => {
      assert.equal(element._computeDescriptionPlaceholder(true),
          'No patch set description');
      assert.equal(element._computeDescriptionPlaceholder(false),
          'Add a patch set description');
    });

    test('_computePatchSetDisabled', () => {
      element.revisions = [
        {_number: 1},
        {_number: 2},
        {_number: element.EDIT_NAME, basePatchNum: 2},
        {_number: 3},
      ];
      let basePatchNum = 'PARENT';
      let patchNum = 1;
      assert.equal(element._computePatchSetDisabled(patchNum, basePatchNum),
          false);
      basePatchNum = 1;
      assert.equal(element._computePatchSetDisabled(patchNum, basePatchNum),
          true);
      patchNum = 2;
      assert.equal(element._computePatchSetDisabled(patchNum, basePatchNum),
          false);
      basePatchNum = element.EDIT_NAME;
      assert.equal(element._computePatchSetDisabled(patchNum, basePatchNum),
          true);
      patchNum = '3';
      assert.equal(element._computePatchSetDisabled(patchNum, basePatchNum),
          false);
    });

    test('_computePatchSetCommentsString', () => {
      // Test string with unresolved comments.

      comments = {
        foo: [{
          id: '27dcee4d_f7b77cfa',
          message: 'test',
          patch_set: 1,
          unresolved: true,
        }],
        bar: [{
          id: '27dcee4d_f7b77cfa',
          message: 'test',
          patch_set: 1,
        },
        {
          id: '27dcee4d_f7b77cfa',
          message: 'test',
          patch_set: 1,
        }],
        abc: [],
      };

      assert.equal(element._computePatchSetCommentsString(comments, 1),
          '(3 comments, 1 unresolved)');

      // Test string with no unresolved comments.
      delete comments['foo'];
      assert.equal(element._computePatchSetCommentsString(comments, 1),
          '(2 comments)');

      // Test string with no comments.
      delete comments['bar'];
      assert.equal(element._computePatchSetCommentsString(comments, 1), '');
    });

    test('_handleDescriptionChanged', () => {
      const putDescStub = sandbox.stub(element.$.restAPI, 'setDescription')
          .returns(Promise.resolve({ok: true}));
      sandbox.stub(element, '_computeDescriptionReadOnly');

      element.changeNum = '42';
      element.patchRange = {
        basePatchNum: 'PARENT',
        patchNum: 1,
      };
      element._selectedPatchNum = '1';
      element.change = {
        change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
        revisions: {
          rev1: {_number: 1, description: 'test', commit: {commit: 'rev1'}},
        },
        current_revision: 'rev1',
        status: 'NEW',
        labels: {},
        actions: {},
        owner: {_account_id: 1},
      };
      element.account = {_account_id: 1};
      element.loggedIn = true;

      flushAsynchronousOperations();
      const label = element.$.descriptionLabel;
      assert.equal(label.value, 'test');
      label.editing = true;
      label._inputText = 'test2';
      label._save();
      flushAsynchronousOperations();
      assert.isTrue(putDescStub.called);
      assert.equal(putDescStub.args[0][2], 'test2');
    });

    test('patch num change', done => {
      element.patchRange = {
        basePatchNum: 'PARENT',
        patchNum: 2,
      };

      element.allPatchSets = [
        {num: 1},
        {num: 2},
        {num: 3},
        {num: 13},
      ];

      flushAsynchronousOperations();

      const selectEl = element.$$('.patchInfo-header gr-select');
      assert.ok(selectEl);
      const optionEls = Polymer.dom(element.root).querySelectorAll(
          '.patchInfo-header option');
      assert.equal(optionEls.length, 4);
      const select = element.$$('.patchInfo-header #patchSetSelect').bindValue;
      assert.notEqual(select, 1);
      assert.equal(select, 2);
      assert.notEqual(select, 3);
      assert.equal(optionEls[3].value, 13);

      let numEvents = 0;
      selectEl.addEventListener('change', e => {
        assert.equal(element.diffViewMode, 'SIDE_BY_SIDE');
        numEvents++;
        if (numEvents == 1) {
          assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
              element.change, '1', 'PARENT'));
          selectEl.nativeSelect.value = '3';
          element.fire('change', {}, {node: selectEl.nativeSelect});
        } else if (numEvents == 2) {
          assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
              element.change, '3', 'PARENT'));
          done();
        }
      });
      selectEl.nativeSelect.value = '1';
      element.fire('change', {}, {node: selectEl.nativeSelect});
    });

    test('patch num change with missing current_revision', done => {
      element.patchRange = {
        basePatchNum: 'PARENT',
        patchNum: 2,
      };

      element.allPatchSets = [
        {num: 1},
        {num: 2},
        {num: 3},
        {num: 13},
      ];
      flushAsynchronousOperations();
      const selectEl = element.$$('.patchInfo-header gr-select');
      assert.ok(selectEl);
      const optionEls = Polymer.dom(element.root).querySelectorAll(
          '.patchInfo-header option');
      assert.equal(optionEls.length, 4);
      assert.notEqual(
          element.$$('.patchInfo-header #patchSetSelect').bindValue, 1);
      assert.equal(
          element.$$('.patchInfo-header #patchSetSelect').bindValue, 2);
      assert.notEqual(
          element.$$('.patchInfo-header #patchSetSelect').bindValue, 3);
      assert.equal(optionEls[3].value, 13);

      let numEvents = 0;
      selectEl.addEventListener('change', e => {
        numEvents++;
        if (numEvents == 1) {
          assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
              element.change, '1', 'PARENT'));
          selectEl.nativeSelect.value = '3';
          element.fire('change', {}, {node: selectEl.nativeSelect});
        } else if (numEvents == 2) {
          assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
              element.change, '3', 'PARENT'));
          done();
        }
      });
      selectEl.nativeSelect.value = '1';
      element.fire('change', {}, {node: selectEl.nativeSelect});
    });

    test('diff against dropdown', done => {
      element.revisions = [
        {commit: {}},
        {commit: {}},
        {commit: {}},
        {commit: {}},
      ];
      element.allPatchSets = [
        {num: 1},
        {num: 2},
        {num: 3},
        {num: 'edit'},
      ];
      element.patchRange = {
        basePatchNum: 'PARENT',
        patchNum: '3',
      };

      flush(() => {
        const selectEl = element.$.patchChange;
        assert.equal(selectEl.nativeSelect.value, 'PARENT');
        assert.isTrue(element.$$('#patchChange option[value="3"]')
            .hasAttribute('disabled'));
        selectEl.addEventListener('change', () => {
          assert.equal(selectEl.nativeSelect.value, 'edit');
          assert(navigateToChangeStub.lastCall.calledWithExactly(
              element.change, '3', 'edit'),
              'Should navigate to /c/42/edit..3');
          done();
        });
        selectEl.nativeSelect.value = 'edit';
        element.fire('change', {}, {node: selectEl.nativeSelect});
      });
    });

    test('expandAllDiffs called when expand button clicked', () => {
      element.shownFileCount = 1;
      flushAsynchronousOperations();
      sandbox.stub(element, '_expandAllDiffs');
      MockInteractions.tap(Polymer.dom(element.root).querySelector(
          '#expandBtn'));
      assert.isTrue(element._expandAllDiffs.called);
    });

    test('collapseAllDiffs called when expand button clicked', () => {
      element.shownFileCount = 1;
      flushAsynchronousOperations();
      sandbox.stub(element, '_collapseAllDiffs');
      MockInteractions.tap(Polymer.dom(element.root).querySelector(
          '#collapseBtn'));
      assert.isTrue(element._collapseAllDiffs.called);
    });

    test('show/hide diffs disabled for large amounts of files', done => {
      const computeSpy = sandbox.spy(element, '_fileListActionsVisible');
      element._files = [];
      element.changeNum = '42';
      element.patchRange = {
        basePatchNum: 'PARENT',
        patchNum: '2',
      };
      element.shownFileCount = 1;
      flush(() => {
        assert.isTrue(computeSpy.lastCall.returnValue);
        _.times(element._maxFilesForBulkActions + 1, () => {
          element.shownFileCount = element.shownFileCount + 1;
        });
        assert.isFalse(computeSpy.lastCall.returnValue);
        done();
      });
    });

    test('diff mode selector is set correctly', () => {
      const select = element.$.modeSelect;
      element.diffViewMode = 'SIDE_BY_SIDE';
      flushAsynchronousOperations();
      assert.equal(select.nativeSelect.value, 'SIDE_BY_SIDE');

      element.diffViewMode = 'UNIFIED_DIFF';
      flushAsynchronousOperations();
      assert.equal(select.nativeSelect.value, 'UNIFIED_DIFF');
    });

    test('include base patch when not parent', () => {
      element.changeNum = '42';
      element.patchRange = {
        basePatchNum: '2',
        patchNum: '3',
      };
      element.change = {
        change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
        revisions: {
          rev2: {_number: 2},
          rev1: {_number: 1},
          rev13: {_number: 13},
          rev3: {_number: 3},
        },
        status: 'NEW',
        labels: {},
      };

      element._changePatchNum(13, 2);
      assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
          element.change, 13, 2));

      element.patchRange.basePatchNum = 'PARENT';

      element._changePatchNum(3, 'PARENT');
      assert.isTrue(navigateToChangeStub.lastCall.calledWithExactly(
          element.change, 3, 'PARENT'));
    });

    test('class is applied to file list on old patch set', () => {
      const allPatchSets = [{num: 1}, {num: 2}, {num: 4}];
      assert.equal(element._computePatchInfoClass('1', allPatchSets),
          'patchInfoOldPatchSet');
      assert.equal(element._computePatchInfoClass('2', allPatchSets),
          'patchInfoOldPatchSet');
      assert.equal(element._computePatchInfoClass('4', allPatchSets), '');
    });

    suite('editLoaded behavior', () => {
      setup(() => {
        element.loggedIn = true;
        element.diffPrefs = {};
      });

      const isVisible = el => {
        assert.ok(el);
        return getComputedStyle(el).getPropertyValue('display') !== 'none';
      };

      test('patch specific elements', () => {
        element.editLoaded = true;
        sandbox.stub(element, 'computeLatestPatchNum').returns('2');
        flushAsynchronousOperations();

        assert.isFalse(isVisible(element.$.diffPrefsContainer));
        assert.isFalse(isVisible(element.$$('.descriptionContainer')));

        element.editLoaded = false;
        flushAsynchronousOperations();

        assert.isTrue(isVisible(element.$$('.descriptionContainer')));
        assert.isTrue(isVisible(element.$.diffPrefsContainer));
      });
    });
  });
</script>
