<!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.
-->

<title>tooltip-behavior</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>
    <tooltip-behavior-element></tooltip-behavior-element>
  </template>
</test-fixture>

<script type="module">
import '../../test/common-test-setup.js';
import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
import {TooltipBehavior} from './gr-tooltip-behavior.js';
suite('gr-tooltip-behavior tests', () => {
  let element;
  let sandbox;

  function makeTooltip(tooltipRect, parentRect) {
    return {
      getBoundingClientRect() { return tooltipRect; },
      updateStyles: sinon.stub(),
      style: {left: 0, top: 0},
      parentElement: {
        getBoundingClientRect() { return parentRect; },
      },
    };
  }

  suiteSetup(() => {
    // Define a Polymer element that uses this behavior.
    Polymer({
      is: 'tooltip-behavior-element',
      behaviors: [TooltipBehavior],
    });
  });

  setup(() => {
    sandbox = sinon.sandbox.create();
    element = fixture('basic');
  });

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

  test('normal position', () => {
    sandbox.stub(element, 'getBoundingClientRect', () => {
      return {top: 100, left: 100, width: 200};
    });
    const tooltip = makeTooltip(
        {height: 30, width: 50},
        {top: 0, left: 0, width: 1000});

    element._positionTooltip(tooltip);
    assert.isFalse(tooltip.updateStyles.called);
    assert.equal(tooltip.style.left, '175px');
    assert.equal(tooltip.style.top, '100px');
  });

  test('left side position', () => {
    sandbox.stub(element, 'getBoundingClientRect', () => {
      return {top: 100, left: 10, width: 50};
    });
    const tooltip = makeTooltip(
        {height: 30, width: 120},
        {top: 0, left: 0, width: 1000});

    element._positionTooltip(tooltip);
    assert.isTrue(tooltip.updateStyles.called);
    const offset = tooltip.updateStyles
        .lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
    assert.isBelow(parseFloat(offset.replace(/px$/, '')), 0);
    assert.equal(tooltip.style.left, '0px');
    assert.equal(tooltip.style.top, '100px');
  });

  test('right side position', () => {
    sandbox.stub(element, 'getBoundingClientRect', () => {
      return {top: 100, left: 950, width: 50};
    });
    const tooltip = makeTooltip(
        {height: 30, width: 120},
        {top: 0, left: 0, width: 1000});

    element._positionTooltip(tooltip);
    assert.isTrue(tooltip.updateStyles.called);
    const offset = tooltip.updateStyles
        .lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
    assert.isAbove(parseFloat(offset.replace(/px$/, '')), 0);
    assert.equal(tooltip.style.left, '915px');
    assert.equal(tooltip.style.top, '100px');
  });

  test('position to bottom', () => {
    sandbox.stub(element, 'getBoundingClientRect', () => {
      return {top: 100, left: 950, width: 50, height: 50};
    });
    const tooltip = makeTooltip(
        {height: 30, width: 120},
        {top: 0, left: 0, width: 1000});

    element.positionBelow = true;
    element._positionTooltip(tooltip);
    assert.isTrue(tooltip.updateStyles.called);
    const offset = tooltip.updateStyles
        .lastCall.args[0]['--gr-tooltip-arrow-center-offset'];
    assert.isAbove(parseFloat(offset.replace(/px$/, '')), 0);
    assert.equal(tooltip.style.left, '915px');
    assert.equal(tooltip.style.top, '157.2px');
  });

  test('hides tooltip when detached', () => {
    sandbox.stub(element, '_handleHideTooltip');
    element.remove();
    flushAsynchronousOperations();
    assert.isTrue(element._handleHideTooltip.called);
  });

  test('sets up listeners when has-tooltip is changed', () => {
    const addListenerStub = sandbox.stub(element, 'addEventListener');
    element.hasTooltip = true;
    assert.isTrue(addListenerStub.called);
  });

  test('clean up listeners when has-tooltip changed to false', () => {
    const removeListenerStub = sandbox.stub(element, 'removeEventListener');
    element.hasTooltip = true;
    element.hasTooltip = false;
    assert.isTrue(removeListenerStub.called);
  });
});
</script>
