<!DOCTYPE html>
<!--
@license
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="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>

<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>
<script type="module" src="../../../test/test-pre-setup.js"></script>
<script type="module" src="../../../test/common-test-setup.js"></script>
<script src="/node_modules/page/page.js"></script>

<script type="module" src="./gr-file-list-header.js"></script>

<script type="module">
import '../../../test/test-pre-setup.js';
import '../../../test/common-test-setup.js';
import './gr-file-list-header.js';
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 type="module">
import '../../../test/test-pre-setup.js';
import '../../../test/common-test-setup.js';
import './gr-file-list-header.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
suite('gr-file-list-header tests', () => {
  let element;
  let sandbox;

  setup(() => {
    sandbox = sinon.sandbox.create();
    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 diffPrefsDisabled', () => {
    element.diffPrefsDisabled = true;
    flushAsynchronousOperations();
    assert.isTrue(element.$.diffPrefsContainer.hidden);

    element.diffPrefsDisabled = false;
    flushAsynchronousOperations();
    assert.isTrue(element.$.diffPrefsContainer.hidden);

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

    element.diffPrefsDisabled = false;
    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 patchset description');
    assert.equal(element._computeDescriptionPlaceholder(false),
        'Add patchset description');
  });

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

    element.changeNum = '42';
    element.basePatchNum = 'PARENT';
    element.patchNum = 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();

    // The element has a description, so the account chip should be visible
    // and the description label should not exist.
    const chip = dom(element.root).querySelector('#descriptionChip');
    let label = dom(element.root).querySelector('#descriptionLabel');

    assert.equal(chip.text, 'test');
    assert.isNotOk(label);

    // Simulate tapping the remove button, but call function directly so that
    // can determine what happens after the promise is resolved.
    return element._handleDescriptionRemoved()
        .then(() => {
          // The API stub should be called with an empty string for the new
          // description.
          assert.equal(putDescStub.lastCall.args[2], '');
          assert.equal(element.change.revisions.rev1.description, '');

          flushAsynchronousOperations();
          // The editable label should now be visible and the chip hidden.
          label = dom(element.root).querySelector('#descriptionLabel');
          assert.isOk(label);
          assert.equal(getComputedStyle(chip).display, 'none');
          assert.notEqual(getComputedStyle(label).display, 'none');
          assert.isFalse(label.readOnly);
          // Edit the label to have a new value of test2, and save.
          label.editing = true;
          label._inputText = 'test2';
          label._save();
          flushAsynchronousOperations();
          // The API stub should be called with an `test2` for the new
          // description.
          assert.equal(putDescStub.callCount, 2);
          assert.equal(putDescStub.lastCall.args[2], 'test2');
        })
        .then(() => {
          flushAsynchronousOperations();
          // The chip should be visible again, and the label hidden.
          assert.equal(element.change.revisions.rev1.description, 'test2');
          assert.equal(getComputedStyle(label).display, 'none');
          assert.notEqual(getComputedStyle(chip).display, 'none');
        });
  });

  test('expandAllDiffs called when expand button clicked', () => {
    element.shownFileCount = 1;
    flushAsynchronousOperations();
    sandbox.stub(element, '_expandAllDiffs');
    MockInteractions.tap(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(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.basePatchNum = 'PARENT';
    element.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('fileViewActions are properly hidden', () => {
    const actions = element.shadowRoot
        .querySelector('.fileViewActions');
    assert.equal(getComputedStyle(actions).display, 'none');
    element.filesExpanded = GrFileListConstants.FilesExpandedState.SOME;
    flushAsynchronousOperations();
    assert.notEqual(getComputedStyle(actions).display, 'none');
    element.filesExpanded = GrFileListConstants.FilesExpandedState.ALL;
    flushAsynchronousOperations();
    assert.notEqual(getComputedStyle(actions).display, 'none');
    element.filesExpanded = GrFileListConstants.FilesExpandedState.NONE;
    flushAsynchronousOperations();
    assert.equal(getComputedStyle(actions).display, 'none');
  });

  test('expand/collapse buttons are toggled correctly', () => {
    element.shownFileCount = 10;
    flushAsynchronousOperations();
    const expandBtn = element.shadowRoot.querySelector('#expandBtn');
    const collapseBtn = element.shadowRoot.querySelector('#collapseBtn');
    assert.notEqual(getComputedStyle(expandBtn).display, 'none');
    assert.equal(getComputedStyle(collapseBtn).display, 'none');
    element.filesExpanded = GrFileListConstants.FilesExpandedState.SOME;
    flushAsynchronousOperations();
    assert.notEqual(getComputedStyle(expandBtn).display, 'none');
    assert.equal(getComputedStyle(collapseBtn).display, 'none');
    element.filesExpanded = GrFileListConstants.FilesExpandedState.ALL;
    flushAsynchronousOperations();
    assert.equal(getComputedStyle(expandBtn).display, 'none');
    assert.notEqual(getComputedStyle(collapseBtn).display, 'none');
    element.filesExpanded = GrFileListConstants.FilesExpandedState.NONE;
    flushAsynchronousOperations();
    assert.notEqual(getComputedStyle(expandBtn).display, 'none');
    assert.equal(getComputedStyle(collapseBtn).display, 'none');
  });

  test('navigateToChange called when range select changes', () => {
    const navigateToChangeStub = sandbox.stub(Gerrit.Nav, 'navigateToChange');
    element.change = {
      change_id: 'Iad9dc96274af6946f3632be53b106ef80f7ba6ca',
      revisions: {
        rev2: {_number: 2},
        rev1: {_number: 1},
        rev13: {_number: 13},
        rev3: {_number: 3},
      },
      status: 'NEW',
      labels: {},
    };
    element.basePatchNum = 1;
    element.patchNum = 2;

    element._handlePatchChange({detail: {basePatchNum: 1, patchNum: 3}});
    assert.equal(navigateToChangeStub.callCount, 1);
    assert.isTrue(navigateToChangeStub.lastCall
        .calledWithExactly(element.change, 3, 1));
  });

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

  suite('editMode behavior', () => {
    setup(() => {
      element.diffPrefsDisabled = false;
      element.diffPrefs = {};
    });

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

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

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

      element.editMode = false;
      flushAsynchronousOperations();

      assert.isTrue(isVisible(element.shadowRoot
          .querySelector('.descriptionContainer')));
      assert.isTrue(isVisible(element.$.diffPrefsContainer));
    });

    test('edit-controls visibility', () => {
      element.editMode = true;
      flushAsynchronousOperations();
      assert.isTrue(isVisible(element.$.editControls.parentElement));

      element.editMode = false;
      flushAsynchronousOperations();
      assert.isFalse(isVisible(element.$.editControls.parentElement));
    });

    test('_computeUploadHelpContainerClass', () => {
      // Only show the upload helper button when an unmerged change is viewed
      // by its owner.
      const accountA = {_account_id: 1};
      const accountB = {_account_id: 2};
      assert.notInclude(element._computeUploadHelpContainerClass(
          {owner: accountA}, accountA), 'hide');
      assert.include(element._computeUploadHelpContainerClass(
          {owner: accountA}, accountB), 'hide');
    });
  });
});
</script>
