<!DOCTYPE html>
<!--
@license
Copyright (C) 2019 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-admin-api</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>

<dom-module id="gr-style-test-element">
  <template>
    <div id="wrapper"></div>
  </template>
  <script type="module">
import '../../../test/common-test-setup.js';
import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
import './gr-styles-api.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
Polymer({is: 'gr-style-test-element'});
</script>
</dom-module>

<script type="module">
import '../../../test/common-test-setup.js';
import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
import './gr-styles-api.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
suite('gr-styles-api tests', () => {
  let sandbox;
  let stylesApi;

  setup(() => {
    sandbox = sinon.sandbox.create();
    let plugin;
    Gerrit.install(p => { plugin = p; }, '0.1',
        'http://test.com/plugins/testplugin/static/test.js');
    Gerrit._loadPlugins([]);
    stylesApi = plugin.styles();
  });

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

  test('exists', () => {
    assert.isOk(stylesApi);
  });

  test('css', () => {
    const styleObject = stylesApi.css('background: red');
    assert.isDefined(styleObject);
  });

  suite('GrStyleObject tests', () => {
    let sandbox;
    let stylesApi;
    let displayInlineStyle;
    let displayNoneStyle;

    setup(() => {
      sandbox = sinon.sandbox.create();
      let plugin;
      Gerrit.install(p => { plugin = p; }, '0.1',
          'http://test.com/plugins/testplugin/static/test.js');
      Gerrit._loadPlugins([]);
      stylesApi = plugin.styles();
      displayInlineStyle = stylesApi.css('display: inline');
      displayNoneStyle = stylesApi.css('display: none');
    });

    teardown(() => {
      displayInlineStyle = null;
      displayNoneStyle = null;
      stylesApi = null;
      sandbox.restore();
    });

    function createNestedElements(parentElement) {
      /* parentElement
      *  |--- element1
      *  |--- element2
      *       |--- element3
      **/
      const element1 = document.createElement('div');
      const element2 = document.createElement('div');
      const element3 = document.createElement('div');
      dom(parentElement).appendChild(element1);
      dom(parentElement).appendChild(element2);
      dom(element2).appendChild(element3);

      return [element1, element2, element3];
    }

    test('getClassName  - body level elements', () => {
      const bodyLevelElements = createNestedElements(document.body);

      testGetClassName(bodyLevelElements);
    });

    test('getClassName  - elements inside polymer element', () => {
      const polymerElement = document.createElement('gr-style-test-element');
      dom(document.body).appendChild(polymerElement);
      const contentElements = createNestedElements(polymerElement.$.wrapper);

      testGetClassName(contentElements);
    });

    function testGetClassName(elements) {
      assertAllElementsHaveDefaultStyle(elements);

      const className1 = displayInlineStyle.getClassName(elements[0]);
      const className2 = displayNoneStyle.getClassName(elements[1]);
      const className3 = displayInlineStyle.getClassName(elements[2]);

      assert.notEqual(className2, className1);
      assert.equal(className3, className1);

      assertAllElementsHaveDefaultStyle(elements);

      elements[0].classList.add(className1);
      elements[1].classList.add(className2);
      elements[2].classList.add(className1);

      assertDisplayPropertyValues(elements, ['inline', 'none', 'inline']);
    }

    test('apply - body level elements', () => {
      const bodyLevelElements = createNestedElements(document.body);

      testApply(bodyLevelElements);
    });

    test('apply - elements inside polymer element', () => {
      const polymerElement = document.createElement('gr-style-test-element');
      dom(document.body).appendChild(polymerElement);
      const contentElements = createNestedElements(polymerElement.$.wrapper);

      testApply(contentElements);
    });

    function testApply(elements) {
      assertAllElementsHaveDefaultStyle(elements);
      displayInlineStyle.apply(elements[0]);
      displayNoneStyle.apply(elements[1]);
      displayInlineStyle.apply(elements[2]);
      assertDisplayPropertyValues(elements, ['inline', 'none', 'inline']);
    }

    function assertAllElementsHaveDefaultStyle(elements) {
      for (const element of elements) {
        assert.equal(getComputedStyle(element).getPropertyValue('display'),
            'block');
      }
    }

    function assertDisplayPropertyValues(elements, expectedDisplayValues) {
      for (const key in elements) {
        if (elements.hasOwnProperty(key)) {
          assert.equal(
              getComputedStyle(elements[key]).getPropertyValue('display'),
              expectedDisplayValues[key]);
        }
      }
    }
  });
});
</script>
