<!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-plugin-host</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="gr-plugin-host.html">

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

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

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

    setup(() => {
      element = fixture('basic');
      sandbox = sinon.sandbox.create();
      sandbox.stub(document.body, 'appendChild');
      sandbox.stub(element, 'importHref');
    });

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

    test('counts plugins', () => {
      sandbox.stub(Gerrit, '_setPluginsCount');
      element.config = {
        plugin: {
          html_resource_paths: ['foo/bar', 'baz'],
          js_resource_paths: ['42'],
        },
      };
      assert.isTrue(Gerrit._setPluginsCount.calledWith(3));
    });

    test('imports relative html plugins from config', () => {
      element.config = {
        plugin: {html_resource_paths: ['foo/bar', 'baz']},
      };
      assert.equal(element.importHref.firstCall.args[0], '/foo/bar');
      assert.equal(element.importHref.firstCall.args[2],
          Gerrit._pluginInstalled);
      assert.isTrue(element.importHref.firstCall.args[3]);

      assert.equal(element.importHref.secondCall.args[0], '/baz');
      assert.equal(element.importHref.secondCall.args[2],
          Gerrit._pluginInstalled);
      assert.isTrue(element.importHref.secondCall.args[3]);
    });

    test('imports relative html plugins from config with a base url', () => {
      sandbox.stub(element, 'getBaseUrl').returns('/the-base');
      element.config = {
        plugin: {html_resource_paths: ['foo/bar', 'baz']}};
      assert.equal(element.importHref.firstCall.args[0], '/the-base/foo/bar');
      assert.equal(element.importHref.firstCall.args[2],
          Gerrit._pluginInstalled);
      assert.isTrue(element.importHref.firstCall.args[3]);

      assert.equal(element.importHref.secondCall.args[0], '/the-base/baz');
      assert.equal(element.importHref.secondCall.args[2],
          Gerrit._pluginInstalled);
      assert.isTrue(element.importHref.secondCall.args[3]);
    });

    test('inportHref is not called with null callback functions', () => {
      const plugins = ['path/to/plugin'];
      element._importHtmlPlugins(plugins);
      assert.isTrue(element.importHref.calledOnce);
      assert.isFunction(element.importHref.lastCall.args[1]);
      assert.isFunction(element.importHref.lastCall.args[2]);
    });

    test('imports absolute html plugins from config', () => {
      element.config = {
        plugin: {
          html_resource_paths: [
            'http://example.com/foo/bar',
            'https://example.com/baz',
          ],
        },
      };
      assert.equal(element.importHref.firstCall.args[0],
          'http://example.com/foo/bar');
      assert.equal(element.importHref.firstCall.args[2],
          Gerrit._pluginInstalled);
      assert.isTrue(element.importHref.firstCall.args[3]);

      assert.equal(element.importHref.secondCall.args[0],
          'https://example.com/baz');
      assert.equal(element.importHref.secondCall.args[2],
          Gerrit._pluginInstalled);
      assert.isTrue(element.importHref.secondCall.args[3]);
    });

    test('adds js plugins from config to the body', () => {
      element.config = {plugin: {js_resource_paths: ['foo/bar', 'baz']}};
      assert.isTrue(document.body.appendChild.calledTwice);
    });

    test('imports relative js plugins from config', () => {
      sandbox.stub(element, '_createScriptTag');
      element.config = {plugin: {js_resource_paths: ['foo/bar', 'baz']}};
      assert.isTrue(element._createScriptTag.calledWith('/foo/bar'));
      assert.isTrue(element._createScriptTag.calledWith('/baz'));
    });

    test('imports relative html plugins from config with a base url', () => {
      sandbox.stub(element, '_createScriptTag');
      sandbox.stub(element, 'getBaseUrl').returns('/the-base');
      element.config = {plugin: {js_resource_paths: ['foo/bar', 'baz']}};
      assert.isTrue(element._createScriptTag.calledWith('/the-base/foo/bar'));
      assert.isTrue(element._createScriptTag.calledWith('/the-base/baz'));
    });

    test('imports absolute html plugins from config', () => {
      sandbox.stub(element, '_createScriptTag');
      element.config = {
        plugin: {
          js_resource_paths: [
            'http://example.com/foo/bar',
            'https://example.com/baz',
          ],
        },
      };
      assert.isTrue(element._createScriptTag.calledWith(
          'http://example.com/foo/bar'));
      assert.isTrue(element._createScriptTag.calledWith(
          'https://example.com/baz'));
    });

    test('default theme is loaded with html plugins', () => {
      element.config = {
        default_theme: '/oof',
        plugin: {
          html_resource_paths: ['some'],
        },
      };
      assert.equal(element.importHref.firstCall.args[0], '/oof');
      assert.equal(element.importHref.firstCall.args[2],
          Gerrit._pluginInstalled);
      assert.isTrue(element.importHref.firstCall.args[3]);

      assert.equal(element.importHref.secondCall.args[0], '/some');
      assert.equal(element.importHref.secondCall.args[2],
          Gerrit._pluginInstalled);
      assert.isTrue(element.importHref.secondCall.args[3]);
    });
  });
</script>
