<!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">
<meta charset="utf-8">
<title>gr-change-metadata</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>

<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 type="module">
import '../../../test/common-test-setup.js';
import '../../plugins/gr-plugin-host/gr-plugin-host.js';
import './gr-change-metadata.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
import {resetPlugins} from '../../../test/test-utils.js';
import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';

const pluginApi = _testOnly_initGerritPluginApi();

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

  const sectionSelectors = [
    '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(
        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}); },
    });
  });

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

  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 => {
      resetPlugins();
      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');
      pluginLoader.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;

    setup(() => {
      pluginApi.install(p => plugin = p, '0.1',
          new URL('test/plugin.html?' + Math.random(),
              window.location.href).toString());
      sandbox.stub(pluginLoader, 'arePluginsLoaded').returns(true);
      pluginLoader.loadPlugins([]);
      element = createElement();
    });

    test('labels changed callback', done => {
      let callCount = 0;
      const labelChangeSpy = sandbox.spy(arg => {
        callCount++;
        if (callCount === 1) {
          assert.deepEqual(arg, labels);
          assert.equal(arg.CI.all.length, 2);
          element.set(['change', 'labels'], {
            CI: {
              all: [
                {value: 1, name: 'user 2', _account_id: 1},
              ],
              values: {
                ' 0': 'Don\'t submit as-is',
                '+1': 'No score',
                '+2': 'Looks good to me',
              },
            },
          });
        } else if (callCount === 2) {
          assert.equal(arg.CI.all.length, 1);
          done();
        }
      });

      plugin.changeMetadata().onLabelsChanged(labelChangeSpy);
    });
  });
});
</script>
