<!DOCTYPE html>
<!--
@license
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-diff-selection</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-diff-selection.html">

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

<test-fixture id="basic">
  <template>
    <gr-diff-selection>
      <table id="diffTable" class="side-by-side">
        <tr class="diff-row">
          <td class="blame" data-line-number="1"></td>
          <td class="lineNum left" data-value="1">1</td>
          <td class="content">
            <div class="contentText" data-side="left">ba ba</div>
            <div data-side="left">
              <div class="gr-diff-comment-thread">
                <div class="gr-formatted-text message">
                  <span id="output" class="gr-linked-text">This is a comment</span>
                </div>
              </div>
            </div>
          </td>
          <td class="lineNum right" data-value="1">1</td>
          <td class="content">
            <div class="contentText" data-side="right">some other text</div>
          </td>
        </tr>
        <tr class="diff-row">
          <td class="blame" data-line-number="2"></td>
          <td class="lineNum left" data-value="2">2</td>
          <td class="content">
            <div class="contentText" data-side="left">zin</div>
          </td>
          <td class="lineNum right" data-value="2">2</td>
          <td class="content">
            <div class="contentText" data-side="right">more more more</div>
            <div data-side="right">
              <div class="gr-diff-comment-thread">
                <div class="gr-formatted-text message">
                  <span id="output" class="gr-linked-text">This is a comment on the right</span>
                </div>
              </div>
            </div>
          </td>
        </tr>
        <tr class="diff-row">
          <td class="blame" data-line-number="3"></td>
          <td class="lineNum left" data-value="3">3</td>
          <td class="content">
            <div class="contentText" data-side="left">ga ga</div>
            <div data-side="left">
              <div class="gr-diff-comment-thread">
                <div class="gr-formatted-text message">
                  <span id="output" class="gr-linked-text">This is <a>a</a> different comment 💩 unicode is fun</span>
                </div>
              </div>
            </div>
          </td>
          <td class="lineNum right" data-value="3">3</td>
        </tr>
        <tr class="diff-row">
          <td class="blame" data-line-number="4"></td>
          <td class="lineNum left" data-value="4">4</td>
          <td class="content">
            <div class="contentText" data-side="left">ga ga</div>
            <div data-side="left">
              <div class="gr-diff-comment-thread">
                <textarea data-side="right">test for textarea copying</textarea>
              </div>
            </div>
          </td>
          <td class="lineNum right" data-value="4">4</td>
        </tr>
        <tr class="not-diff-row">
          <td class="other">
            <div class="contentText" data-side="right">some other text</div>
          </td>
        </tr>
      </table>
    </gr-diff-selection>
  </template>
</test-fixture>

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

    const emulateCopyOn = function(target) {
      const fakeEvent = {
        target,
        preventDefault: sandbox.stub(),
        clipboardData: {
          setData: sandbox.stub(),
        },
      };
      element._getCopyEventTarget.returns(target);
      element._handleCopy(fakeEvent);
      return fakeEvent;
    };

    setup(() => {
      element = fixture('basic');
      sandbox = sinon.sandbox.create();
      sandbox.stub(element, '_getCopyEventTarget');
      element._cachedDiffBuilder = {
        getLineElByChild: sandbox.stub().returns({}),
        getSideByLineEl: sandbox.stub(),
        diffElement: element.querySelector('#diffTable'),
      };
      element.diff = {
        content: [
          {
            a: ['ba ba'],
            b: ['some other text'],
          },
          {
            a: ['zin'],
            b: ['more more more'],
          },
          {
            a: ['ga ga'],
            b: ['some other text'],
          },
        ],
      };
    });

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

    test('applies selected-left on left side click', () => {
      element.classList.add('selected-right');
      element._cachedDiffBuilder.getSideByLineEl.returns('left');
      MockInteractions.down(element);
      assert.isTrue(
          element.classList.contains('selected-left'), 'adds selected-left');
      assert.isFalse(
          element.classList.contains('selected-right'),
          'removes selected-right');
    });

    test('applies selected-right on right side click', () => {
      element.classList.add('selected-left');
      element._cachedDiffBuilder.getSideByLineEl.returns('right');
      MockInteractions.down(element);
      assert.isTrue(
          element.classList.contains('selected-right'), 'adds selected-right');
      assert.isFalse(
          element.classList.contains('selected-left'), 'removes selected-left');
    });

    test('applies selected-blame on blame click', () => {
      element.classList.add('selected-left');
      element.diffBuilder.getLineElByChild.returns(null);
      sandbox.stub(element, '_elementDescendedFromClass',
          (el, className) => className === 'blame');
      MockInteractions.down(element);
      assert.isTrue(
          element.classList.contains('selected-blame'), 'adds selected-right');
      assert.isFalse(
          element.classList.contains('selected-left'), 'removes selected-left');
    });

    test('ignores copy for non-content Element', () => {
      sandbox.stub(element, '_getSelectedText');
      emulateCopyOn(element.querySelector('.not-diff-row'));
      assert.isFalse(element._getSelectedText.called);
    });

    test('asks for text for left side Elements', () => {
      element._cachedDiffBuilder.getSideByLineEl.returns('left');
      sandbox.stub(element, '_getSelectedText');
      emulateCopyOn(element.querySelector('div.contentText'));
      assert.deepEqual(['left', false], element._getSelectedText.lastCall.args);
    });

    test('reacts to copy for content Elements', () => {
      sandbox.stub(element, '_getSelectedText');
      emulateCopyOn(element.querySelector('div.contentText'));
      assert.isTrue(element._getSelectedText.called);
    });

    test('copy event is prevented for content Elements', () => {
      sandbox.stub(element, '_getSelectedText');
      element._cachedDiffBuilder.getSideByLineEl.returns('left');
      element._getSelectedText.returns('test');
      const event = emulateCopyOn(element.querySelector('div.contentText'));
      assert.isTrue(event.preventDefault.called);
    });

    test('inserts text into clipboard on copy', () => {
      sandbox.stub(element, '_getSelectedText').returns('the text');
      const event = emulateCopyOn(element.querySelector('div.contentText'));
      assert.deepEqual(
          ['Text', 'the text'], event.clipboardData.setData.lastCall.args);
    });

    test('_setClasses adds given SelectionClass values, removes others', () => {
      element.classList.add('selected-right');
      element._setClasses(['selected-comment', 'selected-left']);
      assert.isTrue(element.classList.contains('selected-comment'));
      assert.isTrue(element.classList.contains('selected-left'));
      assert.isFalse(element.classList.contains('selected-right'));
      assert.isFalse(element.classList.contains('selected-blame'));

      element._setClasses(['selected-blame']);
      assert.isFalse(element.classList.contains('selected-comment'));
      assert.isFalse(element.classList.contains('selected-left'));
      assert.isFalse(element.classList.contains('selected-right'));
      assert.isTrue(element.classList.contains('selected-blame'));
    });

    test('_setClasses removes before it ads', () => {
      element.classList.add('selected-right');
      const addStub = sandbox.stub(element.classList, 'add');
      const removeStub = sandbox.stub(element.classList, 'remove', () => {
        assert.isFalse(addStub.called);
      });
      element._setClasses(['selected-comment', 'selected-left']);
      assert.isTrue(addStub.called);
      assert.isTrue(removeStub.called);
    });

    test('copies content correctly', () => {
      // Fetch the line number.
      element._cachedDiffBuilder.getLineElByChild = function(child) {
        while (!child.classList.contains('content') && child.parentElement) {
          child = child.parentElement;
        }
        return child.previousElementSibling;
      };

      element.classList.add('selected-left');
      element.classList.remove('selected-right');

      const selection = window.getSelection();
      selection.removeAllRanges();
      const range = document.createRange();
      range.setStart(element.querySelector('div.contentText').firstChild, 3);
      range.setEnd(
          element.querySelectorAll('div.contentText')[4].firstChild, 2);
      selection.addRange(range);
      assert.equal(element._getSelectedText('left'), 'ba\nzin\nga');
    });

    test('copies comments', () => {
      element.classList.add('selected-left');
      element.classList.add('selected-comment');
      element.classList.remove('selected-right');
      const selection = window.getSelection();
      selection.removeAllRanges();
      const range = document.createRange();
      range.setStart(
          element.querySelector('.gr-formatted-text *').firstChild, 3);
      range.setEnd(
          element.querySelectorAll('.gr-formatted-text *')[2].childNodes[2], 7);
      selection.addRange(range);
      assert.equal('s is a comment\nThis is a differ',
          element._getSelectedText('left', true));
    });

    test('respects astral chars in comments', () => {
      element.classList.add('selected-left');
      element.classList.add('selected-comment');
      element.classList.remove('selected-right');
      const selection = window.getSelection();
      selection.removeAllRanges();
      const range = document.createRange();
      const nodes = element.querySelectorAll('.gr-formatted-text *');
      range.setStart(nodes[2].childNodes[2], 13);
      range.setEnd(nodes[2].childNodes[2], 23);
      selection.addRange(range);
      assert.equal('mment 💩 u',
          element._getSelectedText('left', true));
    });

    test('defers to default behavior for textarea', () => {
      element.classList.add('selected-left');
      element.classList.remove('selected-right');
      const selectedTextSpy = sandbox.spy(element, '_getSelectedText');
      emulateCopyOn(element.querySelector('textarea'));
      assert.isFalse(selectedTextSpy.called);
    });

    test('regression test for 4794', () => {
      element._cachedDiffBuilder.getLineElByChild = function(child) {
        while (!child.classList.contains('content') && child.parentElement) {
          child = child.parentElement;
        }
        return child.previousElementSibling;
      };

      element.classList.add('selected-right');
      element.classList.remove('selected-left');

      const selection = window.getSelection();
      selection.removeAllRanges();
      const range = document.createRange();
      range.setStart(
          element.querySelectorAll('div.contentText')[1].firstChild, 4);
      range.setEnd(
          element.querySelectorAll('div.contentText')[1].firstChild, 10);
      selection.addRange(range);
      assert.equal(element._getSelectedText('right'), ' other');
    });

    test('copies to end of side (issue 7895)', () => {
      element._cachedDiffBuilder.getLineElByChild = function(child) {
        // Return null for the end container.
        if (child.textContent === 'ga ga') { return null; }
        while (!child.classList.contains('content') && child.parentElement) {
          child = child.parentElement;
        }
        return child.previousElementSibling;
      };
      element.classList.add('selected-left');
      element.classList.remove('selected-right');
      const selection = window.getSelection();
      selection.removeAllRanges();
      const range = document.createRange();
      range.setStart(element.querySelector('div.contentText').firstChild, 3);
      range.setEnd(
          element.querySelectorAll('div.contentText')[4].firstChild, 2);
      selection.addRange(range);
      assert.equal(element._getSelectedText('left'), 'ba\nzin\nga');
    });

    suite('_getTextContentForRange', () => {
      let selection;
      let range;
      let nodes;

      setup(() => {
        element.classList.add('selected-left');
        element.classList.add('selected-comment');
        element.classList.remove('selected-right');
        selection = window.getSelection();
        selection.removeAllRanges();
        range = document.createRange();
        nodes = element.querySelectorAll('.gr-formatted-text *');
      });

      test('multi level element contained in range', () => {
        range.setStart(nodes[2].childNodes[0], 1);
        range.setEnd(nodes[2].childNodes[2], 7);
        selection.addRange(range);
        assert.equal(element._getTextContentForRange(element, selection, range),
            'his is a differ');
      });


      test('multi level element as startContainer of range', () => {
        range.setStart(nodes[2].childNodes[1], 0);
        range.setEnd(nodes[2].childNodes[2], 7);
        selection.addRange(range);
        assert.equal(element._getTextContentForRange(element, selection, range),
            'a differ');
      });

      test('startContainer === endContainer', () => {
        range.setStart(nodes[0].firstChild, 2);
        range.setEnd(nodes[0].firstChild, 12);
        selection.addRange(range);
        assert.equal(element._getTextContentForRange(element, selection, range),
            'is is a co');
      });
    });

    test('cache is reset when diff changes', () => {
      element._linesCache = {left: 'test', right: 'test'};
      element.diff = {};
      flushAsynchronousOperations();
      assert.deepEqual(element._linesCache, {left: null, right: null});
    });
  });
</script>
