<!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-dom-hooks</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="basic">
  <template>
    <div></div>
  </template>
</test-fixture>

<script type="module">
import '../../../test/common-test-setup.js';
import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
import {GrDomHook, GrDomHooksManager} from './gr-dom-hooks.js';
import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';

const pluginApi = _testOnly_initGerritPluginApi();

suite('gr-dom-hooks tests', () => {
  const PUBLIC_METHODS =[
    'onAttached',
    'onDetached',
    'getLastAttached',
    'getAllAttached',
    'getModuleName',
  ];

  let instance;
  let sandbox;
  let hook;
  let hookInternal;

  setup(() => {
    sandbox = sinon.sandbox.create();
    let plugin;
    pluginApi.install(p => { plugin = p; }, '0.1',
        'http://test.com/plugins/testplugin/static/test.js');
    instance = new GrDomHooksManager(plugin);
  });

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

  suite('placeholder', () => {
    setup(()=>{
      sandbox.stub(GrDomHook.prototype, '_createPlaceholder');
      hookInternal = instance.getDomHook('foo-bar');
      hook = hookInternal.getPublicAPI();
    });

    test('public hook API has only public methods', () => {
      assert.deepEqual(Object.keys(hook), PUBLIC_METHODS);
    });

    test('registers placeholder class', () => {
      assert.isTrue(hookInternal._createPlaceholder.calledWithExactly(
          'testplugin-autogenerated-foo-bar'));
    });

    test('getModuleName()', () => {
      const hookName = Object.keys(instance._hooks).pop();
      assert.equal(hookName, 'testplugin-autogenerated-foo-bar');
      assert.equal(hook.getModuleName(), 'testplugin-autogenerated-foo-bar');
    });
  });

  suite('custom element', () => {
    setup(() => {
      hookInternal = instance.getDomHook('foo-bar', 'my-el');
      hook = hookInternal.getPublicAPI();
    });

    test('public hook API has only public methods', () => {
      assert.deepEqual(Object.keys(hook), PUBLIC_METHODS);
    });

    test('getModuleName()', () => {
      const hookName = Object.keys(instance._hooks).pop();
      assert.equal(hookName, 'foo-bar my-el');
      assert.equal(hook.getModuleName(), 'my-el');
    });

    test('onAttached', () => {
      const onAttachedSpy = sandbox.spy();
      hook.onAttached(onAttachedSpy);
      const [el1, el2] = [
        document.createElement(hook.getModuleName()),
        document.createElement(hook.getModuleName()),
      ];
      hookInternal.handleInstanceAttached(el1);
      hookInternal.handleInstanceAttached(el2);
      assert.isTrue(onAttachedSpy.firstCall.calledWithExactly(el1));
      assert.isTrue(onAttachedSpy.secondCall.calledWithExactly(el2));
    });

    test('onDetached', () => {
      const onDetachedSpy = sandbox.spy();
      hook.onDetached(onDetachedSpy);
      const [el1, el2] = [
        document.createElement(hook.getModuleName()),
        document.createElement(hook.getModuleName()),
      ];
      hookInternal.handleInstanceDetached(el1);
      assert.isTrue(onDetachedSpy.firstCall.calledWithExactly(el1));
      hookInternal.handleInstanceDetached(el2);
      assert.isTrue(onDetachedSpy.secondCall.calledWithExactly(el2));
    });

    test('getAllAttached', () => {
      const [el1, el2] = [
        document.createElement(hook.getModuleName()),
        document.createElement(hook.getModuleName()),
      ];
      el1.textContent = 'one';
      el2.textContent = 'two';
      hookInternal.handleInstanceAttached(el1);
      hookInternal.handleInstanceAttached(el2);
      assert.deepEqual([el1, el2], hook.getAllAttached());
      hookInternal.handleInstanceDetached(el1);
      assert.deepEqual([el2], hook.getAllAttached());
    });

    test('getLastAttached', () => {
      const beforeAttachedPromise = hook.getLastAttached().then(
          el => assert.strictEqual(el1, el));
      const [el1, el2] = [
        document.createElement(hook.getModuleName()),
        document.createElement(hook.getModuleName()),
      ];
      el1.textContent = 'one';
      el2.textContent = 'two';
      hookInternal.handleInstanceAttached(el1);
      hookInternal.handleInstanceAttached(el2);
      const afterAttachedPromise = hook.getLastAttached().then(
          el => assert.strictEqual(el2, el));
      return Promise.all([
        beforeAttachedPromise,
        afterAttachedPromise,
      ]);
    });
  });
});
</script>
