<!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-change-metadata</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"/>
<link rel="import" href="../../plugins/gr-plugin-host/gr-plugin-host.html">
<link rel="import" href="gr-change-metadata.html">

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

<test-fixture id="element">
  <template>
    <gr-change-metadata mutable="true"></gr-change-metadata>
  </template>
</test-fixture>

<test-fixture id="plugin-host">
  <template>
    <gr-plugin-host></gr-plugin-host>
  </template>
</test-fixture>

<script>
  suite('gr-change-metadata integration tests', () => {
    let sandbox;
    let element;

    const sectionSelectors = [
      'section.assignee',
      'section.labelStatus',
      'section.strategy',
      'section.topic',
    ];

    const labels = {
      CI: {
        all: [
          {value: 1, name: 'user 2', _account_id: 1},
          {value: 2, name: 'user '},
        ],
        values: {
          ' 0': 'Don\'t submit as-is',
          '+1': 'No score',
          '+2': 'Looks good to me',
        },
      },
    };

    const getStyle = function(selector, name) {
      return window.getComputedStyle(
          Polymer.dom(element.root).querySelector(selector))[name];
    };

    function createElement() {
      const element = fixture('element');
      element.change = {labels, status: 'NEW'};
      element.revision = {};
      return element;
    }

    setup(() => {
      sandbox = sinon.sandbox.create();
      stub('gr-rest-api-interface', {
        getConfig() { return Promise.resolve({}); },
        getLoggedIn() { return Promise.resolve(false); },
        deleteVote() { return Promise.resolve({ok: true}); },
      });
      stub('gr-change-metadata', {
        _computeShowLabelStatus() { return true; },
        _computeShowReviewersByState() { return true; },
      });
    });

    teardown(() => {
      Gerrit._pluginsPending = -1;
      Gerrit._allPluginsPromise = undefined;
      sandbox.restore();
    });

    suite('by default', () => {
      setup(done => {
        element = createElement();
        flush(done);
      });

      for (const sectionSelector of sectionSelectors) {
        test(sectionSelector + ' does not have display: none', () => {
          assert.notEqual(getStyle(sectionSelector, 'display'), 'none');
        });
      }
    });

    suite('with plugin style', () => {
      setup(done => {
        const pluginHost = fixture('plugin-host');
        pluginHost.config = {
          plugin: {
            js_resource_paths: [],
            html_resource_paths: [
              new URL('test/plugin.html?' + Math.random(),
                      window.location.href).toString(),
            ],
          },
        };
        element = createElement();
        const importSpy = sandbox.spy(element.$.externalStyle, '_import');
        Gerrit.awaitPluginsLoaded().then(() => {
          Promise.all(importSpy.returnValues).then(() => {
            flush(done);
          });
        });
      });

      for (const sectionSelector of sectionSelectors) {
        test(sectionSelector + ' may have display: none', () => {
          assert.equal(getStyle(sectionSelector, 'display'), 'none');
        });
      }
    });

    suite('label updates', () => {
      let plugin;
      let labelChangeStub;

      setup(done => {
        Gerrit.install(p => plugin = p, '0.1',
            new URL('test/plugin.html?' + Math.random(),
                    window.location.href).toString());
        sandbox.stub(Gerrit, '_arePluginsLoaded').returns(true);
        Gerrit._resolveAllPluginsLoaded();
        element = createElement();
        sandbox.stub(element, '_computeCanDeleteVote').returns(true);

        labelChangeStub = sandbox.stub();
        plugin.changeMetadata().onLabelsChanged(labelChangeStub);
        flush(done);
      });

      test('labels changed callback', done => {
        assert.equal(labelChangeStub.callCount, 1);
        assert.isTrue(labelChangeStub.calledWithExactly(labels));
        assert.equal(labelChangeStub.args[0][0]['CI'].all.length, 2);
        MockInteractions.tap(Polymer.dom(element.root).querySelector(
            'gr-account-chip').$.remove);
        // Wait for fake rest API response.
        flush(() => {
          assert.equal(labelChangeStub.callCount, 2);
          assert.equal(labelChangeStub.args[1][0]['CI'].all.length, 1);
          done();
        });
      });
    });
  });
</script>
