<!DOCTYPE html>
<!--
Copyright (C) 2015 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</title>

<script src="../../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<script src="../../../test/fake-app.js"></script>
<script src="../../../scripts/util.js"></script>

<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="gr-diff.html">

<test-fixture id="basic">
  <template>
    <gr-diff></gr-diff>
  </template>
</test-fixture>

<script>
  suite('gr-diff tests', function() {
    var element;
    var server;
    var getDiffStub;
    var getCommentsStub;

    setup(function() {
      element = fixture('basic');
      element.changeNum = 42;
      element.path = 'sieve.go';
      element.prefs = {
        context: 10,
        tab_size: 8,
      };

      getDiffStub = sinon.stub(element.$.restAPI, 'getDiff', function() {
        return Promise.resolve({
          change_type: 'MODIFIED',
          content: [
            {
              ab: [
                '<!DOCTYPE html>',
                '<meta charset="utf-8">',
                '<title>My great page</title>',
                '<style>',
                '  *,',
                '  *:before,',
                '  *:after {',
                '    box-sizing: border-box;',
                '  }',
                '</style>',
                '<header>',
              ]
            },
            {
              a: [
                '  Welcome ',
                '  to the wooorld of tomorrow!',
              ],
              b: [
                '  Hello, world!',
              ],
            },
            {
              ab: [
                '</header>',
                '<body>',
                'Leela: This is the only place the ship can’t hear us, so ',
                'everyone pretend to shower.',
                'Fry: Same as every day. Got it.',
              ]
            },
          ]
        });
      });

      getCommentsStub = sinon.stub(element.$.restAPI, 'getDiffComments',
        function() {
          return Promise.resolve({
            baseComments: [
              {
                author: {
                  _account_id: 1000000,
                  name: 'Andrew Bonventre',
                  email: 'andybons@gmail.com',
                },
                id: '9af53d3f_5f2b8b82',
                line: 1,
                message: 'this isn’t quite right',
                updated: '2015-12-10 02:50:21.627000000',
              }
            ],
            comments: [
              {
                author: {
                  _account_id: 1010008,
                  name: 'Dave Borowitz',
                  email: 'dborowitz@google.com',
                },
                id: '001a2067_f30f3048',
                line: 12,
                message: 'What on earth are you thinking, here?',
                updated: '2015-12-12 02:51:37.973000000',
              },
              {
                author: {
                  _account_id: 1000000,
                  name: 'Andrew Bonventre',
                  email: 'andybons@gmail.com',
                },
                id: 'a0407443_30dfe8fb',
                in_reply_to: '001a2067_f30f3048',
                line: 12,
                message: '¯\\_(ツ)_/¯',
                updated: '2015-12-12 18:50:21.627000000',
              },
            ],
          });
        }
      );

      server = sinon.fakeServer.create();
      server.respondWith(
        'PUT',
        '/accounts/self/preferences.diff',
        [
          200,
          {'Content-Type': 'application/json'},
          ')]}\'\n' +
          JSON.stringify({context: 25}),
        ]
      );

    });

    teardown(function() {
      getDiffStub.restore();
      getCommentsStub.restore();
      server.restore();
    });

    test('comment rendering', function(done) {
      element.prefs.context = -1;
      element._loggedIn = true;
      element.patchRange = {
        basePatchNum: 1,
        patchNum: 2,
      };

      element.reload();
      server.respond();

      // Allow events to fire and the threads to render.
      flush(function() {
        var leftThreadEls =
            Polymer.dom(element.$.leftDiff.root).querySelectorAll(
                'gr-diff-comment-thread');
        assert.equal(leftThreadEls.length, 1);
        assert.equal(leftThreadEls[0].comments.length, 1);

        var rightThreadEls =
            Polymer.dom(element.$.rightDiff.root).querySelectorAll(
                'gr-diff-comment-thread');
        assert.equal(rightThreadEls.length, 1);
        assert.equal(rightThreadEls[0].comments.length, 2);

        var index = leftThreadEls[0].getAttribute('data-index');
        var leftFillerEls =
            Polymer.dom(element.$.leftDiff.root).querySelectorAll(
                '.commentThread.filler[data-index="' + index + '"]');
        assert.equal(leftFillerEls.length, 1);
        var rightFillerEls =
            Polymer.dom(element.$.rightDiff.root).querySelectorAll(
                '[data-index="' + index + '"]');
        assert.equal(rightFillerEls.length, 2);

        for (var i = 0; i < rightFillerEls.length; i++) {
          assert.isTrue(rightFillerEls[i].classList.contains('filler'));
        }
        var originalHeight = rightFillerEls[0].offsetHeight;
        assert.equal(rightFillerEls[1].offsetHeight, originalHeight);
        assert.equal(leftThreadEls[0].offsetHeight, originalHeight);
        assert.equal(leftFillerEls[0].offsetHeight, originalHeight);

        // Create a comment on the opposite side of the first comment.
        var rightLineEL = element.$.rightDiff.$$(
              '.lineNum[data-index="' + (index - 1) + '"]');
        assert.ok(rightLineEL);
        MockInteractions.tap(rightLineEL);
        flush(function() {
          var newThreadEls =
            Polymer.dom(element.$.rightDiff.root).querySelectorAll(
                '[data-index="' + index + '"]');
          assert.equal(newThreadEls.length, 2);
          for (var i = 0; i < newThreadEls.length; i++) {
            assert.isTrue(
                newThreadEls[i].classList.contains('commentThread') ||
                newThreadEls[i].tagName == 'GR-DIFF-COMMENT-THREAD');
          }
          var newHeight = newThreadEls[0].offsetHeight;
          assert.equal(newThreadEls[1].offsetHeight, newHeight);
          assert.equal(leftFillerEls[0].offsetHeight, newHeight);
          assert.equal(leftThreadEls[0].offsetHeight, newHeight);

          // The editing mode height of the right comment will be greater than
          // the non-editing mode height of the left comment.
          assert.isAbove(newHeight, originalHeight);

          // Discard the right thread and ensure the left comment heights are
          // back to their original values.
          newThreadEls[1].addEventListener('discard', function() {
            rightFillerEls =
                Polymer.dom(element.$.rightDiff.root).querySelectorAll(
                    '[data-index="' + index + '"]');
            assert.equal(rightFillerEls.length, 2);

            for (var i = 0; i < rightFillerEls.length; i++) {
              assert.isTrue(rightFillerEls[i].classList.contains('filler'));
            }
            var originalHeight = rightFillerEls[0].offsetHeight;
            assert.equal(rightFillerEls[1].offsetHeight, originalHeight);
            assert.equal(leftThreadEls[0].offsetHeight, originalHeight);
            assert.equal(leftFillerEls[0].offsetHeight, originalHeight);
            done();
          });
          var commentEl = newThreadEls[1].$$('gr-diff-comment');
          commentEl.fire('discard', null, {bubbles: false});
        });
      });
    });

    test('intraline normalization', function() {
      // The content and highlights are in the format returned by the Gerrit
      // REST API.
      var content = [
        '      <section class="summary">',
        '        <gr-linked-text content="' +
            '[[_computeCurrentRevisionMessage(change)]]"></gr-linked-text>',
        '      </section>',
      ];
      var highlights = [
        [31, 34], [42, 26]
      ];
      var results = element._normalizeIntralineHighlights(content, highlights);
      assert.deepEqual(results, [
        {
          contentIndex: 0,
          startIndex: 31,
        },
        {
          contentIndex: 1,
          startIndex: 0,
          endIndex: 33,
        },
        {
          contentIndex: 1,
          startIndex: 75,
        },
        {
          contentIndex: 2,
          startIndex: 0,
          endIndex: 6,
        }
      ]);

      content = [
        '        this._path = value.path;',
        '',
        '        // When navigating away from the page, there is a possibility that the',
        '        // patch number is no longer a part of the URL (say when navigating to',
        '        // the top-level change info view) and therefore undefined in `params`.',
        '        if (!this._patchRange.patchNum) {',
      ];
      highlights = [
        [14, 17],
        [11, 70],
        [12, 67],
        [12, 67],
        [14, 29],
      ];
      results = element._normalizeIntralineHighlights(content, highlights);
      assert.deepEqual(results, [
        {
          contentIndex: 0,
          startIndex: 14,
          endIndex: 31,
        },
        {
          contentIndex: 2,
          startIndex: 8,
          endIndex: 78,
        },
        {
          contentIndex: 3,
          startIndex: 11,
          endIndex: 78,
        },
        {
          contentIndex: 4,
          startIndex: 11,
          endIndex: 78,
        },
        {
          contentIndex: 5,
          startIndex: 12,
          endIndex: 41,
        }
      ]);
    });

    test('context', function() {
      element.prefs.context = 3;
      element._diffResponse = {
        content: [
          {
            ab: [
              '<!DOCTYPE html>',
              '<meta charset="utf-8">',
              '<title>My great page</title>',
              '<style>',
              '  *,',
              '  *:before,',
              '  *:after {',
              '    box-sizing: border-box;',
              '  }',
              '</style>',
              '<header>',
            ]
          },
          {
            a: [
              '  Welcome ',
              '  to the wooorld of tomorrow!',
            ],
            b: [
              '  Hello, world!',
            ],
          },
          {
            ab: [
              '</header>',
              '<body>',
              'Leela: This is the only place the ship can’t hear us, so ',
              'everyone pretend to shower.',
              'Fry: Same as every day. Got it.',
            ]
          },
        ]
      };
      element._processContent();

      // First eight lines should be hidden on both sides.
      for (var i = 0; i < 8; i++) {
        assert.isTrue(element._diff.leftSide[i].hidden);
        assert.isTrue(element._diff.rightSide[i].hidden);
      }
      // A context control should be at index 8 on both sides.
      var leftContext = element._diff.leftSide[8];
      var rightContext = element._diff.rightSide[8];
      assert.deepEqual(leftContext, rightContext);
      assert.equal(leftContext.numLines, 8);
      assert.equal(leftContext.start, 0);
      assert.equal(leftContext.end, 8);

      // Line indices 9-16 should be shown.
      for (var i = 9; i <= 16; i++) {
        // notOk (falsy) because the `hidden` attribute may not be present.
        assert.notOk(element._diff.leftSide[i].hidden);
        assert.notOk(element._diff.rightSide[i].hidden);
      }

      // Lines at indices 17 and 18 should be hidden.
      assert.isTrue(element._diff.leftSide[17].hidden);
      assert.isTrue(element._diff.rightSide[17].hidden);
      assert.isTrue(element._diff.leftSide[18].hidden);
      assert.isTrue(element._diff.rightSide[18].hidden);

      // Context control at index 19.
      leftContext = element._diff.leftSide[19];
      rightContext = element._diff.rightSide[19];
      assert.deepEqual(leftContext, rightContext);
      assert.equal(leftContext.numLines, 2);
      assert.equal(leftContext.start, 17);
      assert.equal(leftContext.end, 19);
    });

    test('save prefs', function(done) {
      element._loggedIn = false;

      element.prefs = {
        tab_size: 4,
        context: 50,
      };
      element.fire('save', {}, {node: element.$$('gr-diff-preferences')});
      assert.isTrue(element._diffPreferencesPromise == null);

      element._loggedIn = true;
      element.fire('save', {}, {node: element.$$('gr-diff-preferences')});
      server.respond();

      element._diffPreferencesPromise.then(function(req) {
        assert.equal(req.xhr.requestBody, JSON.stringify(element.prefs));
        done();
      });
    });

    test('visible line length', function() {
      assert.equal(element._visibleLineLength('A'.repeat(5)), 5);
      assert.equal(
          element._visibleLineLength('A'.repeat(5) + '\t' + 'A'.repeat(5)), 18);
    });

    test('break up common diff chunks', function() {
      element._groupedBaseComments = {
        1: {},
      };
      element._groupedComments = {
        10: {},
      };
      var ctx = {
        left: {lineNum: 0},
        right: {lineNum: 0},
      };
      var content = [
        {
          ab: [
            'Copyright (C) 2015 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.',
          ]
        }
      ];
      var result = element._breakUpCommonChunksWithComments(ctx, content);
      assert.deepEqual(result, [
        {
          __noHighlight: true,
          a: ['Copyright (C) 2015 The Android Open Source Project'],
          b: ['Copyright (C) 2015 The Android Open Source Project'],
        },
        {
          ab: [
            '',
            '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, ',
          ]
        },
        {
          __noHighlight: true,
          a: ['software distributed under the License is distributed on an '],
          b: ['software distributed under the License is distributed on an ']
        },
        {
          ab: [
            '"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.',
          ]
        }
      ]);
    });
  });

</script>
