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

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

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

<script>
  suite('gr-project-access tests', () => {
    let element;
    let sandbox;

    setup(() => {
      sandbox = sinon.sandbox.create();
      element = fixture('basic');
    });

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

    test('_projectChanged called when project name changes', () => {
      sandbox.stub(element, '_projectChanged');
      element.project = 'New Project';
      assert.isTrue(element._projectChanged.called);
    });

    test('_projectChanged', done => {
      const capabilitiesRes = {
        accessDatabase: {
          id: 'accessDatabase',
          name: 'Access Database',
        },
        createAccount: {
          id: 'createAccount',
          name: 'Create Account',
        },
      };
      const accessRes = {
        local: {
          'refs/*': {
            permissions: {
              owner: {
                rules: {
                  234: {},
                },
              },
            },
          },
        },
      };
      const accessRes2 = {
        local: {
          GLOBAL_CAPABILITIES: {
            permissions: {
              accessDatabase: {
                rules: {
                  group1: {
                    action: 'ALLOW',
                  },
                },
              },
            },
          },
        },
      };
      const projectRes = {
        labels: {
          'Code-Review': {},
        },
      };
      const accessStub = sandbox.stub(element.$.restAPI,
          'getProjectAccessRights');


      accessStub.withArgs('New Project').returns(Promise.resolve(accessRes));
      accessStub.withArgs('Another New Project')
          .returns(Promise.resolve(accessRes2));
      const capabilitiesStub = sandbox.stub(element.$.restAPI,
          'getCapabilities');
      capabilitiesStub.returns(Promise.resolve(capabilitiesRes));
      const projectStub = sandbox.stub(element.$.restAPI, 'getProject').returns(
          Promise.resolve(projectRes));
      const adminStub = sandbox.stub(element.$.restAPI, 'getIsAdmin').returns(
          Promise.resolve(true));

      element._projectChanged('New Project').then(() => {
        assert.isTrue(accessStub.called);
        assert.isTrue(capabilitiesStub.called);
        assert.isTrue(projectStub.called);
        assert.isTrue(adminStub.called);
        assert.isNotOk(element._inheritsFrom);
        assert.deepEqual(element._local, accessRes.local);
        assert.deepEqual(element._sections,
            element.toSortedArray(accessRes.local));
        assert.deepEqual(element._labels, projectRes.labels);
        return element._projectChanged('Another New Project');
      })
          .then(() => {
            assert.deepEqual(element._sections,
                element.toSortedArray(accessRes2.local));
            done();
          });
    });

    test('_projectChanged when project changes to undefined returns', done => {
      const capabilitiesRes = {
        accessDatabase: {
          id: 'accessDatabase',
          name: 'Access Database',
        },
      };
      const accessRes = {
        local: {
          GLOBAL_CAPABILITIES: {
            permissions: {
              accessDatabase: {
                rules: {
                  123: {},
                },
              },
            },
          },
        },
      };
      const projectRes = {
        labels: {
          'Code-Review': {},
        },
      };
      const accessStub = sandbox.stub(element.$.restAPI,
          'getProjectAccessRights').returns(Promise.resolve(accessRes));
      const capabilitiesStub = sandbox.stub(element.$.restAPI,
          'getCapabilities').returns(Promise.resolve(capabilitiesRes));
      const projectStub = sandbox.stub(element.$.restAPI, 'getProject').returns(
          Promise.resolve(projectRes));

      element._projectChanged().then(() => {
        assert.isFalse(accessStub.called);
        assert.isFalse(capabilitiesStub.called);
        assert.isFalse(projectStub.called);
        done();
      });
    });

    test('_computeParentHref', () => {
      const projectName = 'test-project';
      assert.equal(element._computeParentHref(projectName),
          '/admin/projects/test-project,access');
    });

    test('_computeAdminClass', () => {
      let isAdmin = true;
      assert.equal(element._computeAdminClass(isAdmin), 'admin');
      isAdmin = false;
      assert.equal(element._computeAdminClass(isAdmin), '');
    });

    test('inherit section', () => {
      sandbox.stub(element, '_computeParentHref');
      assert.isNotOk(Polymer.dom(element.root).querySelector('#inheritsFrom'));
      assert.isFalse(element._computeParentHref.called);
      element._inheritsFrom = {
        name: 'another-project',
      };
      flushAsynchronousOperations();
      assert.isOk(Polymer.dom(element.root).querySelector('#inheritsFrom'));
      assert.isTrue(element._computeParentHref.called);
    });
  });
</script>
