<!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="../../../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;

    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 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 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 = Polymer.dom(element.root).querySelector('#descriptionChip');
      let label = Polymer.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 = Polymer.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(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.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.$$('.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.$$('#expandBtn');
      const collapseBtn = element.$$('#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.loggedIn = true;
        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.$$('.descriptionContainer')));

        element.editMode = false;
        flushAsynchronousOperations();

        assert.isTrue(isVisible(element.$$('.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>
