<!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().then(function() {
        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});
          });
        });
      });
      server.respond();
    });

    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>
