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

<script src="../../../bower_components/page/page.js"></script>
<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"/>
<link rel="import" href="gr-project-detail-list.html">

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

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

<script>
  let counter;
  const branchGenerator = () => {
    return {
      ref: `refs/heads/test${++counter}`,
      revision: '9c9d08a438e55e52f33b608415e6dddd9b18550d',
      web_links: [
        {
          name: 'diffusion',
          url: `https://git.example.org/branch/test;refs/heads/test${counter}`,
        },
      ],
    };
  };
  const tagGenerator = () => {
    return {
      ref: `refs/tags/test${++counter}`,
      revision: '9c9d08a438e55e52f33b608415e6dddd9b18550d',
      web_links: [
        {
          name: 'diffusion',
          url: `https://git.example.org/tag/test;refs/tags/test${counter}`,
        },
      ],
    };
  };

  suite('Branches', () => {
    let element;
    let branches;
    let sandbox;

    setup(() => {
      sandbox = sinon.sandbox.create();
      element = fixture('basic');
      element.detailType = 'branches';
      counter = 0;
      sandbox.stub(page, 'show');
    });

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

    suite('list of project branches', () => {
      setup(done => {
        branches = [{
          ref: 'HEAD',
          revision: 'master',
        }].concat(_.times(25, branchGenerator));

        stub('gr-rest-api-interface', {
          getProjectBranches(num, project, offset) {
            return Promise.resolve(branches);
          },
        });

        const params = {
          project: 'test',
          detailType: 'branches',
        };

        element._paramsChanged(params).then(() => { flush(done); });
      });

      test('test for branch in the list', done => {
        flush(() => {
          assert.equal(element._items[2].ref, 'refs/heads/test2');
          done();
        });
      });

      test('test for web links in the branches list', done => {
        flush(() => {
          assert.equal(element._items[2].web_links[0].url,
              'https://git.example.org/branch/test;refs/heads/test2');
          done();
        });
      });

      test('test for refs/heads/ being striped from ref', done => {
        flush(() => {
          assert.equal(element._stripRefs(element._items[2].ref,
              element.detailType), 'test2');
          done();
        });
      });

      test('_shownItems', () => {
        assert.equal(element._shownItems.length, 25);
      });

      test('Edit HEAD button not admin', done => {
        sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true));
        sandbox.stub(element.$.restAPI, 'getProjectAccess').returns(
            Promise.resolve({
              test: {is_owner: false},
            }));
        element._determineIfOwner('test').then(() => {
          assert.equal(element._isOwner, false);
          assert.equal(getComputedStyle(Polymer.dom(element.root)
              .querySelector('.revisionNoEditing')).display, 'inline');
          assert.equal(getComputedStyle(Polymer.dom(element.root)
              .querySelector('.revisionEdit')).display, 'none');
          done();
        });
      });

      test('Edit HEAD button admin', done => {
        const saveBtn = Polymer.dom(element.root).querySelector('.saveBtn');
        const cancelBtn = Polymer.dom(element.root).querySelector('.cancelBtn');
        const editBtn = Polymer.dom(element.root).querySelector('.editBtn');
        const revisionNoEditing = Polymer.dom(element.root)
              .querySelector('.revisionNoEditing');
        const revisionWithEditing = Polymer.dom(element.root)
              .querySelector('.revisionWithEditing');

        sandbox.stub(element, '_getLoggedIn').returns(Promise.resolve(true));
        sandbox.stub(element.$.restAPI, 'getProjectAccess').returns(
            Promise.resolve({
              test: {is_owner: true},
            }));
        sandbox.stub(element, '_handleSaveRevision');
        element._determineIfOwner('test').then(() => {
          assert.equal(element._isOwner, true);
          // The revision container for non-editing enabled row is not visible.
          assert.equal(getComputedStyle(revisionNoEditing).display, 'none');

          // The revision container for editing enabled row is visible.
          assert.notEqual(getComputedStyle(Polymer.dom(element.root)
              .querySelector('.revisionEdit')).display, 'none');

          // The revision and edit button are visible.
          assert.notEqual(getComputedStyle(revisionWithEditing).display,
              'none');
          assert.notEqual(getComputedStyle(editBtn).display, 'none');

          // The input, cancel, and save buttons are not visible.
          const hiddenElements = Polymer.dom(element.root)
              .querySelectorAll('.canEdit .editItem');

          for (const item of hiddenElements) {
            assert.equal(getComputedStyle(item).display, 'none');
          }

          MockInteractions.tap(editBtn);
          flushAsynchronousOperations();
          // The revision and edit button are not visible.
          assert.equal(getComputedStyle(revisionWithEditing).display, 'none');
          assert.equal(getComputedStyle(editBtn).display, 'none');

          // The input, cancel, and save buttons are not visible.
          for (item of hiddenElements) {
            assert.notEqual(getComputedStyle(item).display, 'none');
          }

          // The revised ref was set correctly
          assert.equal(element._revisedRef, 'master');

          assert.isFalse(saveBtn.disabled);

          // Delete the ref.
          element._revisedRef = '';
          assert.isTrue(saveBtn.disabled);

          // Change the ref to something else
          element._revisedRef = 'newRef';
          element._project = 'test';
          assert.isFalse(saveBtn.disabled);

          // Save button calls handleSave. since this is stubbed, the edit
          // section remains open.
          MockInteractions.tap(saveBtn);
          assert.isTrue(element._handleSaveRevision.called);

          // When cancel is tapped, the edit secion closes.
          MockInteractions.tap(cancelBtn);
          flushAsynchronousOperations();

          // The revision and edit button are visible.
          assert.notEqual(getComputedStyle(revisionWithEditing).display,
              'none');
          assert.notEqual(getComputedStyle(editBtn).display, 'none');

          // The input, cancel, and save buttons are not visible.
          for (const item of hiddenElements) {
            assert.equal(getComputedStyle(item).display, 'none');
          }
          done();
        });
      });

      test('_handleSaveRevision with invalid rev', done => {
        const event = {model: {set: sandbox.stub()}};
        element._isEditing = true;
        sandbox.stub(element.$.restAPI, 'setProjectHead').returns(
            Promise.resolve({
              status: 400,
            })
        );

        element._setProjectHead('test', 'newRef', event).then(() => {
          assert.isTrue(element._isEditing);
          assert.isFalse(event.model.set.called);
          done();
        });
      });

      test('_handleSaveRevision with valid rev', done => {
        const event = {model: {set: sandbox.stub()}};
        element._isEditing = true;
        sandbox.stub(element.$.restAPI, 'setProjectHead').returns(
            Promise.resolve({
              status: 200,
            })
        );

        element._setProjectHead('test', 'newRef', event).then(() => {
          assert.isFalse(element._isEditing);
          assert.isTrue(event.model.set.called);
          done();
        });
      });

      test('test _computeItemName', () => {
        assert.deepEqual(element._computeItemName('branches'), 'Branch');
        assert.deepEqual(element._computeItemName('tags'), 'Tag');
      });
    });

    suite('list with less then 25 branches', () => {
      setup(done => {
        branches = _.times(25, branchGenerator);

        stub('gr-rest-api-interface', {
          getProjectBranches(num, project, offset) {
            return Promise.resolve(branches);
          },
        });

        const params = {
          project: 'test',
          detailType: 'branches',
        };

        element._paramsChanged(params).then(() => { flush(done); });
      });

      test('_shownProjectsBranches', () => {
        assert.equal(element._shownItems.length, 25);
      });
    });

    suite('filter', () => {
      test('_paramsChanged', done => {
        sandbox.stub(element.$.restAPI, 'getProjectBranches', () => {
          return Promise.resolve(branches);
        });
        const params = {
          detailType: 'branches',
          project: 'test',
          filter: 'test',
          offset: 25,
        };
        element._paramsChanged(params).then(() => {
          assert.isTrue(element.$.restAPI.getProjectBranches.lastCall
              .calledWithExactly('test', 'test', 25, 25));
          done();
        });
      });
    });
  });

  suite('Tags', () => {
    let element;
    let tags;
    let sandbox;

    setup(() => {
      sandbox = sinon.sandbox.create();
      element = fixture('basic');
      element.detailType = 'tags';
      counter = 0;
      sandbox.stub(page, 'show');
    });

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

    suite('list of project tags', () => {
      setup(done => {
        tags = _.times(26, tagGenerator);

        stub('gr-rest-api-interface', {
          getProjectTags(num, project, offset) {
            return Promise.resolve(tags);
          },
        });

        const params = {
          project: 'test',
          detailType: 'tags',
        };

        element._paramsChanged(params).then(() => { flush(done); });
      });

      test('test for tag in the list', done => {
        flush(() => {
          assert.equal(element._items[1].ref, 'refs/tags/test2');
          done();
        });
      });

      test('test for web links in the tags list', done => {
        flush(() => {
          assert.equal(element._items[1].web_links[0].url,
              'https://git.example.org/tag/test;refs/tags/test2');
          done();
        });
      });

      test('test for refs/tags/ being striped from ref', done => {
        flush(() => {
          assert.equal(element._stripRefs(element._items[1].ref,
              element.detailType), 'test2');
          done();
        });
      });

      test('_shownItems', () => {
        assert.equal(element._shownItems.length, 25);
      });
    });

    suite('list with less then 25 tags', () => {
      setup(done => {
        tags = _.times(25, tagGenerator);

        stub('gr-rest-api-interface', {
          getProjectTags(num, project, offset) {
            return Promise.resolve(tags);
          },
        });

        const params = {
          project: 'test',
          detailType: 'tags',
        };

        element._paramsChanged(params).then(() => { flush(done); });
      });

      test('_shownItems', () => {
        assert.equal(element._shownItems.length, 25);
      });
    });

    suite('filter', () => {
      test('_paramsChanged', done => {
        sandbox.stub(element.$.restAPI, 'getProjectTags', () => {
          return Promise.resolve(tags);
        });
        const params = {
          project: 'test',
          detailType: 'tags',
          filter: 'test',
          offset: 25,
        };
        element._paramsChanged(params).then(() => {
          assert.isTrue(element.$.restAPI.getProjectTags.lastCall
              .calledWithExactly('test', 'test', 25, 25));
          done();
        });
      });
    });

    suite('create new', () => {
      test('_handleCreateClicked called when create-click fired', () => {
        sandbox.stub(element, '_handleCreateClicked');
        element.$$('gr-list-view').fire('create-clicked');
        assert.isTrue(element._handleCreateClicked.called);
      });

      test('_handleCreateClicked opens modal', () => {
        const openStub = sandbox.stub(element.$.createOverlay, 'open');
        element._handleCreateClicked();
        assert.isTrue(openStub.called);
      });

      test('_handleCreateItem called when confirm fired', () => {
        sandbox.stub(element, '_handleCreateItem');
        element.$.createDialog.fire('confirm');
        assert.isTrue(element._handleCreateItem.called);
      });

      test('_handleCloseCreate called when cancel fired', () => {
        sandbox.stub(element, '_handleCloseCreate');
        element.$.createDialog.fire('cancel');
        assert.isTrue(element._handleCloseCreate.called);
      });
    });

    test('test _computeHideDeleteClass', () => {
      assert.deepEqual(element._computeHideDeleteClass(true, false), 'show');
      assert.deepEqual(element._computeHideDeleteClass(false, true), 'show');
      assert.deepEqual(element._computeHideDeleteClass(false, false), '');
    });
  });
</script>
