<!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-cursor</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>
<script type="module" src="../../../test/test-pre-setup.js"></script>
<script type="module" src="../../../test/common-test-setup.js"></script>
<script type="module" src="../../../scripts/util.js"></script>

<script type="module" src="../gr-diff/gr-diff.js"></script>
<script type="module" src="./gr-diff-cursor.js"></script>
<script type="module" src="../../shared/gr-rest-api-interface/gr-rest-api-interface.js"></script>
<script type="module" src="../../shared/gr-rest-api-interface/mock-diff-response_test.js"></script>

<script type="module">
import '../../../test/test-pre-setup.js';
import '../../../test/common-test-setup.js';
import '../../../scripts/util.js';
import '../gr-diff/gr-diff.js';
import './gr-diff-cursor.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../../shared/gr-rest-api-interface/mock-diff-response_test.js';
void(0);
</script>

<test-fixture id="basic">
  <template>
    <mock-diff-response></mock-diff-response>
    <gr-diff></gr-diff>
    <gr-diff-cursor></gr-diff-cursor>
    <gr-rest-api-interface></gr-rest-api-interface>
  </template>
</test-fixture>

<test-fixture id="empty">
  <template>
    <div></div>
  </template>
</test-fixture>

<script type="module">
import '../../../test/test-pre-setup.js';
import '../../../test/common-test-setup.js';
import '../../../scripts/util.js';
import '../gr-diff/gr-diff.js';
import './gr-diff-cursor.js';
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
import '../../shared/gr-rest-api-interface/mock-diff-response_test.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
suite('gr-diff-cursor tests', () => {
  let sandbox;
  let cursorElement;
  let diffElement;
  let mockDiffResponse;

  setup(done => {
    sandbox = sinon.sandbox.create();

    const fixtureElems = fixture('basic');
    mockDiffResponse = fixtureElems[0];
    diffElement = fixtureElems[1];
    cursorElement = fixtureElems[2];
    const restAPI = fixtureElems[3];

    // Register the diff with the cursor.
    cursorElement.push('diffs', diffElement);

    diffElement.loggedIn = false;
    diffElement.patchRange = {basePatchNum: 1, patchNum: 2};
    diffElement.comments = {
      left: [],
      right: [],
      meta: {patchRange: undefined},
    };
    const setupDone = () => {
      cursorElement._updateStops();
      cursorElement.moveToFirstChunk();
      diffElement.removeEventListener('render', setupDone);
      done();
    };
    diffElement.addEventListener('render', setupDone);

    restAPI.getDiffPreferences().then(prefs => {
      diffElement.prefs = prefs;
      diffElement.diff = mockDiffResponse.diffResponse;
    });
  });

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

  test('diff cursor functionality (side-by-side)', () => {
    // The cursor has been initialized to the first delta.
    assert.isOk(cursorElement.diffRow);

    const firstDeltaRow = diffElement.shadowRoot
        .querySelector('.section.delta .diff-row');
    assert.equal(cursorElement.diffRow, firstDeltaRow);

    cursorElement.moveDown();

    assert.notEqual(cursorElement.diffRow, firstDeltaRow);
    assert.equal(cursorElement.diffRow, firstDeltaRow.nextSibling);

    cursorElement.moveUp();

    assert.notEqual(cursorElement.diffRow, firstDeltaRow.nextSibling);
    assert.equal(cursorElement.diffRow, firstDeltaRow);
  });

  test('moveToLastChunk', () => {
    const chunks = Array.from(dom(diffElement.root).querySelectorAll(
        '.section.delta'));
    assert.isAbove(chunks.length, 1);
    assert.equal(chunks.indexOf(cursorElement.diffRow.parentElement), 0);

    cursorElement.moveToLastChunk();

    assert.equal(chunks.indexOf(cursorElement.diffRow.parentElement),
        chunks.length - 1);
  });

  test('cursor scroll behavior', () => {
    cursorElement._handleDiffRenderStart();
    assert.equal(cursorElement._scrollBehavior, 'keep-visible');
    assert.isTrue(cursorElement._focusOnMove);

    cursorElement._handleWindowScroll();
    assert.equal(cursorElement._scrollBehavior, 'never');
    assert.isFalse(cursorElement._focusOnMove);

    cursorElement.handleDiffUpdate();
    assert.equal(cursorElement._scrollBehavior, 'keep-visible');
    assert.isTrue(cursorElement._focusOnMove);
  });

  suite('unified diff', () => {
    setup(done => {
      // We must allow the diff to re-render after setting the viewMode.
      const renderHandler = function() {
        diffElement.removeEventListener('render', renderHandler);
        cursorElement.reInitCursor();
        done();
      };
      diffElement.addEventListener('render', renderHandler);
      diffElement.viewMode = 'UNIFIED_DIFF';
    });

    test('diff cursor functionality (unified)', () => {
      // The cursor has been initialized to the first delta.
      assert.isOk(cursorElement.diffRow);

      let firstDeltaRow = diffElement.shadowRoot
          .querySelector('.section.delta .diff-row');
      assert.equal(cursorElement.diffRow, firstDeltaRow);

      firstDeltaRow = diffElement.shadowRoot
          .querySelector('.section.delta .diff-row');
      assert.equal(cursorElement.diffRow, firstDeltaRow);

      cursorElement.moveDown();

      assert.notEqual(cursorElement.diffRow, firstDeltaRow);
      assert.equal(cursorElement.diffRow, firstDeltaRow.nextSibling);

      cursorElement.moveUp();

      assert.notEqual(cursorElement.diffRow, firstDeltaRow.nextSibling);
      assert.equal(cursorElement.diffRow, firstDeltaRow);
    });
  });

  test('cursor side functionality', () => {
    // The side only applies to side-by-side mode, which should be the default
    // mode.
    assert.equal(diffElement.viewMode, 'SIDE_BY_SIDE');

    const firstDeltaSection = diffElement.shadowRoot
        .querySelector('.section.delta');
    const firstDeltaRow = firstDeltaSection.querySelector('.diff-row');

    // Because the first delta in this diff is on the right, it should be set
    // to the right side.
    assert.equal(cursorElement.side, 'right');
    assert.equal(cursorElement.diffRow, firstDeltaRow);
    const firstIndex = cursorElement.$.cursorManager.index;

    // Move the side to the left. Because this delta only has a right side, we
    // should be moved up to the previous line where there is content on the
    // right. The previous row is part of the previous section.
    cursorElement.moveLeft();

    assert.equal(cursorElement.side, 'left');
    assert.notEqual(cursorElement.diffRow, firstDeltaRow);
    assert.equal(cursorElement.$.cursorManager.index, firstIndex - 1);
    assert.equal(cursorElement.diffRow.parentElement,
        firstDeltaSection.previousSibling);

    // If we move down, we should skip everything in the first delta because
    // we are on the left side and the first delta has no content on the left.
    cursorElement.moveDown();

    assert.equal(cursorElement.side, 'left');
    assert.notEqual(cursorElement.diffRow, firstDeltaRow);
    assert.isTrue(cursorElement.$.cursorManager.index > firstIndex);
    assert.equal(cursorElement.diffRow.parentElement,
        firstDeltaSection.nextSibling);
  });

  test('chunk skip functionality', () => {
    const chunks = dom(diffElement.root).querySelectorAll(
        '.section.delta');
    const indexOfChunk = function(chunk) {
      return Array.prototype.indexOf.call(chunks, chunk);
    };

    // We should be initialized to the first chunk. Since this chunk only has
    // content on the right side, our side should be right.
    let currentIndex = indexOfChunk(cursorElement.diffRow.parentElement);
    assert.equal(currentIndex, 0);
    assert.equal(cursorElement.side, 'right');

    // Move to the next chunk.
    cursorElement.moveToNextChunk();

    // Since this chunk only has content on the left side. we should have been
    // automatically mvoed over.
    const previousIndex = currentIndex;
    currentIndex = indexOfChunk(cursorElement.diffRow.parentElement);
    assert.equal(currentIndex, previousIndex + 1);
    assert.equal(cursorElement.side, 'left');
  });

  test('initialLineNumber not provided', done => {
    let scrollBehaviorDuringMove;
    const moveToNumStub = sandbox.stub(cursorElement, 'moveToLineNumber');
    const moveToChunkStub = sandbox.stub(cursorElement, 'moveToFirstChunk',
        () => { scrollBehaviorDuringMove = cursorElement._scrollBehavior; });

    function renderHandler() {
      diffElement.removeEventListener('render', renderHandler);
      assert.isFalse(moveToNumStub.called);
      assert.isTrue(moveToChunkStub.called);
      assert.equal(scrollBehaviorDuringMove, 'never');
      assert.equal(cursorElement._scrollBehavior, 'keep-visible');
      done();
    }
    diffElement.addEventListener('render', renderHandler);
    diffElement._diffChanged(mockDiffResponse.diffResponse);
  });

  test('initialLineNumber provided', done => {
    let scrollBehaviorDuringMove;
    const moveToNumStub = sandbox.stub(cursorElement, 'moveToLineNumber',
        () => { scrollBehaviorDuringMove = cursorElement._scrollBehavior; });
    const moveToChunkStub = sandbox.stub(cursorElement, 'moveToFirstChunk');
    function renderHandler() {
      diffElement.removeEventListener('render', renderHandler);
      assert.isFalse(moveToChunkStub.called);
      assert.isTrue(moveToNumStub.called);
      assert.equal(moveToNumStub.lastCall.args[0], 10);
      assert.equal(moveToNumStub.lastCall.args[1], 'right');
      assert.equal(scrollBehaviorDuringMove, 'keep-visible');
      assert.equal(cursorElement._scrollBehavior, 'keep-visible');
      done();
    }
    diffElement.addEventListener('render', renderHandler);
    cursorElement.initialLineNumber = 10;
    cursorElement.side = 'right';

    diffElement._diffChanged(mockDiffResponse.diffResponse);
  });

  test('getTargetDiffElement', () => {
    cursorElement.initialLineNumber = 1;
    assert.isTrue(!!cursorElement.diffRow);
    assert.equal(
        cursorElement.getTargetDiffElement(),
        diffElement
    );
  });

  suite('createCommentInPlace', () => {
    setup(() => {
      diffElement.loggedIn = true;
    });

    test('adds new draft for selected line on the left', done => {
      cursorElement.moveToLineNumber(2, 'left');
      diffElement.addEventListener('create-comment', e => {
        const {lineNum, range, side, patchNum} = e.detail;
        assert.equal(lineNum, 2);
        assert.equal(range, undefined);
        assert.equal(patchNum, 1);
        assert.equal(side, 'left');
        done();
      });
      cursorElement.createCommentInPlace();
    });

    test('adds draft for selected line on the right', done => {
      cursorElement.moveToLineNumber(4, 'right');
      diffElement.addEventListener('create-comment', e => {
        const {lineNum, range, side, patchNum} = e.detail;
        assert.equal(lineNum, 4);
        assert.equal(range, undefined);
        assert.equal(patchNum, 2);
        assert.equal(side, 'right');
        done();
      });
      cursorElement.createCommentInPlace();
    });

    test('createCommentInPlace creates comment for range if selected', done => {
      const someRange = {
        start_line: 2,
        start_character: 3,
        end_line: 6,
        end_character: 1,
      };
      diffElement.$.highlights.selectedRange = {
        side: 'right',
        range: someRange,
      };
      diffElement.addEventListener('create-comment', e => {
        const {lineNum, range, side, patchNum} = e.detail;
        assert.equal(lineNum, 6);
        assert.equal(range, someRange);
        assert.equal(patchNum, 2);
        assert.equal(side, 'right');
        done();
      });
      cursorElement.createCommentInPlace();
    });

    test('createCommentInPlace ignores call if nothing is selected', () => {
      const createRangeCommentStub = sandbox.stub(diffElement,
          'createRangeComment');
      const addDraftAtLineStub = sandbox.stub(diffElement, 'addDraftAtLine');
      cursorElement.diffRow = undefined;
      cursorElement.createCommentInPlace();
      assert.isFalse(createRangeCommentStub.called);
      assert.isFalse(addDraftAtLineStub.called);
    });
  });

  test('getAddress', () => {
    // It should initialize to the first chunk: line 5 of the revision.
    assert.deepEqual(cursorElement.getAddress(),
        {leftSide: false, number: 5});

    // Revision line 4 is up.
    cursorElement.moveUp();
    assert.deepEqual(cursorElement.getAddress(),
        {leftSide: false, number: 4});

    // Base line 4 is left.
    cursorElement.moveLeft();
    assert.deepEqual(cursorElement.getAddress(), {leftSide: true, number: 4});

    // Moving to the next chunk takes it back to the start.
    cursorElement.moveToNextChunk();
    assert.deepEqual(cursorElement.getAddress(),
        {leftSide: false, number: 5});

    // The following chunk is a removal starting on line 10 of the base.
    cursorElement.moveToNextChunk();
    assert.deepEqual(cursorElement.getAddress(),
        {leftSide: true, number: 10});

    // Should be null if there is no selection.
    cursorElement.$.cursorManager.unsetCursor();
    assert.isNotOk(cursorElement.getAddress());
  });

  test('_findRowByNumberAndFile', () => {
    // Get the first ab row after the first chunk.
    const row = dom(diffElement.root).querySelectorAll('tr')[8];

    // It should be line 8 on the right, but line 5 on the left.
    assert.equal(cursorElement._findRowByNumberAndFile(8, 'right'), row);
    assert.equal(cursorElement._findRowByNumberAndFile(5, 'left'), row);
  });

  test('expand context updates stops', done => {
    sandbox.spy(cursorElement, 'handleDiffUpdate');
    MockInteractions.tap(diffElement.shadowRoot
        .querySelector('.showContext'));
    flush(() => {
      assert.isTrue(cursorElement.handleDiffUpdate.called);
      done();
    });
  });

  suite('gr-diff-cursor event tests', () => {
    let sandbox;
    let someEmptyDiv;

    setup(() => {
      sandbox = sinon.sandbox.create();
      someEmptyDiv = fixture('empty');
    });

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

    test('ready is fired after component is rendered', done => {
      const cursorElement = document.createElement('gr-diff-cursor');
      cursorElement.addEventListener('ready', () => {
        done();
      });
      someEmptyDiv.appendChild(cursorElement);
    });
  });
});
</script>
