<!DOCTYPE html>
<!--
Copyright (C) 2016 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-selection-action-box</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-selection-action-box.html">

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

<test-fixture id="basic">
  <template>
    <div>
      <gr-selection-action-box></gr-selection-action-box>
      <div class="target">some text</div>
    </div>
  </template>
</test-fixture>

<script>
  suite('gr-selection-action-box', () => {
    let container;
    let element;

    setup(() => {
      container = fixture('basic');
      element = container.querySelector('gr-selection-action-box');
      sinon.stub(element, 'fire');
    });

    teardown(() => {
      element.fire.restore();
    });

    test('ignores regular keys', () => {
      MockInteractions.pressAndReleaseKeyOn(document.body, 27, null, 'esc');
      assert.isFalse(element.fire.called);
    });

    test('reacts to hotkey', () => {
      MockInteractions.pressAndReleaseKeyOn(document.body, 67, null, 'c');
      assert.isTrue(element.fire.called);
    });

    suite('mousedown reacts only to main button', () => {
      let e;

      setup(() => {
        e = {
          button: 0,
          preventDefault: sinon.stub(),
          stopPropagation: sinon.stub(),
        };
        sinon.stub(element, '_fireCreateComment');
      });

      test('event handled if main button', () => {
        element._handleMouseDown(e);
        assert.isTrue(e.preventDefault.called);
      });

      test('event ignored if not main button', () => {
        e.button = 1;
        element._handleMouseDown(e);
        assert.isFalse(e.preventDefault.called);
      });
    });

    test('event fired contains playload', () => {
      const side = 'left';
      const range = {
        startLine: 1,
        startChar: 11,
        endLine: 2,
        endChar: 42,
      };
      element.side = 'left';
      element.range = range;
      MockInteractions.pressAndReleaseKeyOn(document.body, 67, null, 'c');
      assert(element.fire.calledWithExactly(
          'create-comment',
          {
            side,
            range,
          }));
    });

    suite('placeAbove', () => {
      let target;

      setup(() => {
        target = container.querySelector('.target');
        sinon.stub(container, 'getBoundingClientRect').returns(
            {top: 1, bottom: 2, left: 3, right: 4, width: 50, height: 6});
        sinon.stub(element, '_getTargetBoundingRect').returns(
            {top: 42, bottom: 20, left: 30, right: 40, width: 100, height: 60});
        sinon.stub(element, 'getBoundingClientRect').returns(
            {width: 10, height: 10});
      });

      teardown(() => {
        element.getBoundingClientRect.restore();
        container.getBoundingClientRect.restore();
        element._getTargetBoundingRect.restore();
      });

      test('placeAbove for Element argument', () => {
        element.placeAbove(target);
        assert.equal(element.style.top, '25px');
        assert.equal(element.style.left, '72px');
      });

      test('placeAbove for Text Node argument', () => {
        element.placeAbove(target.firstChild);
        assert.equal(element.style.top, '25px');
        assert.equal(element.style.left, '72px');
      });

      test('uses document.createRange', () => {
        sinon.spy(document, 'createRange');
        element._getTargetBoundingRect.restore();
        sinon.spy(element, '_getTargetBoundingRect');
        element.placeAbove(target.firstChild);
        assert.isTrue(document.createRange.called);
        document.createRange.restore();
      });
    });
  });
</script>
