<!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-messages-list</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="../../diff/gr-comment-api/gr-comment-api.html">

<link rel="import" href="gr-messages-list.html">

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

<dom-module id="comment-api-mock">
  <template>
    <gr-messages-list
        id="messagesList"
        change-comments="[[_changeComments]]"></gr-messages-list>
    <gr-comment-api id="commentAPI"></gr-comment-api>
  </template>
  <script src="../../diff/gr-comment-api/gr-comment-api-mock.js"></script>
</dom-module>

<test-fixture id="basic">
  <template>
    <comment-api-mock>
      <gr-messages-list></gr-messages-list>
    </comment-api-mock>
  </template>
</test-fixture>

<script>

  const randomMessage = function(opt_params) {
    const params = opt_params || {};
    const author1 = {
      _account_id: 1115495,
      name: 'Andrew Bonventre',
      email: 'andybons@chromium.org',
    };
    return {
      id: params.id || Math.random().toString(),
      date: params.date || '2016-01-12 20:28:33.038000',
      message: params.message || Math.random().toString(),
      _revision_number: params._revision_number || 1,
      author: params.author || author1,
    };
  };

  const randomAutomated = function(opt_params) {
    return Object.assign({tag: 'autogenerated:gerrit:replace'},
        randomMessage(opt_params));
  };

  suite('gr-messages-list tests', () => {
    let element;
    let messages;
    let sandbox;
    let commentApiWrapper;

    const getMessages = function() {
      return Polymer.dom(element.root).querySelectorAll('gr-message');
    };

    const author = {
      _account_id: 42,
      name: 'Marvin the Paranoid Android',
      email: 'marvin@sirius.org',
    };

    const comments = {
      file1: [
        {
          message: 'message text',
          updated: '2016-09-27 00:18:03.000000000',
          in_reply_to: '6505d749_f0bec0aa',
          line: 62,
          id: '6505d749_10ed44b2',
          patch_set: 2,
          author: {
            email: 'some@email.com',
            _account_id: 123,
          },
        },
        {
          message: 'message text',
          updated: '2016-09-27 00:18:03.000000000',
          in_reply_to: 'c5912363_6b820105',
          line: 42,
          id: '450a935e_0f1c05db',
          patch_set: 2,
          author,
        },
        {
          message: 'message text',
          updated: '2016-09-27 00:18:03.000000000',
          in_reply_to: '6505d749_f0bec0aa',
          line: 62,
          id: '6505d749_10ed44b2',
          patch_set: 2,
          author,
        },
      ],
      file2: [
        {
          message: 'message text',
          updated: '2016-09-27 00:18:03.000000000',
          in_reply_to: 'c5912363_4b7d450a',
          line: 132,
          id: '450a935e_4f260d25',
          patch_set: 2,
          author,
        },
      ],
    };

    setup(() => {
      stub('gr-rest-api-interface', {
        getConfig() { return Promise.resolve({}); },
        getLoggedIn() { return Promise.resolve(false); },
        getDiffComments() { return Promise.resolve(comments); },
        getDiffRobotComments() { return Promise.resolve({}); },
        getDiffDrafts() { return Promise.resolve({}); },
      });
      sandbox = sinon.sandbox.create();
      messages = _.times(3, randomMessage);
      // Element must be wrapped in an element with direct access to the
      // comment API.
      commentApiWrapper = fixture('basic');
      element = commentApiWrapper.$.messagesList;
      loadCommentSpy = sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll');
      element.messages = messages;

      // Stub methods on the changeComments object after changeComments has
      // been initalized.
      return commentApiWrapper.loadComments();
    });

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

    test('show some old messages', () => {
      assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden'));
      element.messages = _.times(26, randomMessage);
      flushAsynchronousOperations();

      assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden'));
      assert.equal(getMessages().length, 20);
      assert.equal(element.$.incrementMessagesBtn.innerText.toUpperCase()
          .trim(), 'SHOW 5 MORE');
      MockInteractions.tap(element.$.incrementMessagesBtn);
      flushAsynchronousOperations();

      assert.equal(getMessages().length, 25);
      assert.equal(element.$.incrementMessagesBtn.innerText.toUpperCase()
          .trim(), 'SHOW 1 MORE');
      MockInteractions.tap(element.$.incrementMessagesBtn);
      flushAsynchronousOperations();

      assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden'));
      assert.equal(getMessages().length, 26);
    });

    test('show all old messages', () => {
      assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden'));
      element.messages = _.times(26, randomMessage);
      flushAsynchronousOperations();

      assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden'));
      assert.equal(getMessages().length, 20);
      assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(),
          'SHOW ALL 6 MESSAGES');
      MockInteractions.tap(element.$.oldMessagesBtn);
      flushAsynchronousOperations();

      assert.equal(getMessages().length, 26);
      assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden'));
    });

    test('message count respects automated', () => {
      element.messages = _.times(10, randomAutomated)
          .concat(_.times(11, randomMessage));
      flushAsynchronousOperations();

      assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(),
          'SHOW 1 MESSAGE');
      assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden'));
      MockInteractions.tap(element.$.automatedMessageToggle);
      flushAsynchronousOperations();

      assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden'));
    });

    test('message count still respects non-automated on toggle', () => {
      element.messages = _.times(10, randomMessage)
          .concat(_.times(11, randomAutomated));
      flushAsynchronousOperations();

      assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(),
          'SHOW 1 MESSAGE');
      assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden'));
      MockInteractions.tap(element.$.automatedMessageToggle);
      flushAsynchronousOperations();

      assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(),
          'SHOW 1 MESSAGE');
      assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden'));
    });

    test('show all messages respects expand', () => {
      element.messages = _.times(10, randomAutomated)
          .concat(_.times(11, randomMessage));
      flushAsynchronousOperations();

      MockInteractions.tap(element.$$('#collapse-messages')); // Expand all.
      flushAsynchronousOperations();

      let messages = getMessages();
      assert.equal(messages.length, 20);
      for (const message of messages) {
        assert.isTrue(message._expanded);
      }

      MockInteractions.tap(element.$.oldMessagesBtn);
      flushAsynchronousOperations();

      messages = getMessages();
      assert.equal(messages.length, 21);
      for (const message of messages) {
        assert.isTrue(message._expanded);
      }
    });

    test('show all messages respects collapse', () => {
      element.messages = _.times(10, randomAutomated)
          .concat(_.times(11, randomMessage));
      flushAsynchronousOperations();

      MockInteractions.tap(element.$$('#collapse-messages')); // Expand all.
      MockInteractions.tap(element.$$('#collapse-messages')); // Collapse all.
      flushAsynchronousOperations();

      let messages = getMessages();
      assert.equal(messages.length, 20);
      for (const message of messages) {
        assert.isFalse(message._expanded);
      }

      MockInteractions.tap(element.$.oldMessagesBtn);
      flushAsynchronousOperations();

      messages = getMessages();
      assert.equal(messages.length, 21);
      for (const message of messages) {
        assert.isFalse(message._expanded);
      }
    });

    test('expand/collapse all', () => {
      let allMessageEls = getMessages();
      for (const message of allMessageEls) {
        message._expanded = false;
      }
      MockInteractions.tap(allMessageEls[1]);
      assert.isTrue(allMessageEls[1]._expanded);

      MockInteractions.tap(element.$$('#collapse-messages'));
      allMessageEls = getMessages();
      for (const message of allMessageEls) {
        assert.isTrue(message._expanded);
      }

      MockInteractions.tap(element.$$('#collapse-messages'));
      allMessageEls = getMessages();
      for (const message of allMessageEls) {
        assert.isFalse(message._expanded);
      }
    });

    test('expand/collapse from external keypress', () => {
      MockInteractions.tap(element.$$('#collapse-messages'));
      let allMessageEls = getMessages();
      for (const message of allMessageEls) {
        assert.isTrue(message._expanded);
      }

      // Expand/collapse all text also changes.
      assert.equal(element.$$('#collapse-messages').textContent.trim(),
          'Collapse all');

      MockInteractions.tap(element.$$('#collapse-messages'));
      allMessageEls = getMessages();
      for (const message of allMessageEls) {
        assert.isFalse(message._expanded);
      }
      // Expand/collapse all text also changes.
      assert.equal(element.$$('#collapse-messages').textContent.trim(),
          'Expand all');
    });

    test('hide messages does not appear when no automated messages', () => {
      assert.isOk(element.$$('#automatedMessageToggleContainer[hidden]'));
    });

    test('scroll to message', () => {
      const allMessageEls = getMessages();
      for (const message of allMessageEls) {
        message.set('message.expanded', false);
      }

      const scrollToStub = sandbox.stub(window, 'scrollTo');
      const highlightStub = sandbox.stub(element, '_highlightEl');

      element.scrollToMessage('invalid');

      for (const message of allMessageEls) {
        assert.isFalse(message._expanded,
            'expected gr-message to not be expanded');
      }

      const messageID = messages[1].id;
      element.scrollToMessage(messageID);
      assert.isTrue(
          element.$$('[data-message-id="' + messageID + '"]')._expanded);

      assert.isTrue(scrollToStub.calledOnce);
      assert.isTrue(highlightStub.calledOnce);
    });

    test('scroll to message offscreen', () => {
      const scrollToStub = sandbox.stub(window, 'scrollTo');
      const highlightStub = sandbox.stub(element, '_highlightEl');
      element.messages = _.times(25, randomMessage);
      flushAsynchronousOperations();
      assert.isFalse(scrollToStub.called);
      assert.isFalse(highlightStub.called);

      const messageID = element.messages[1].id;
      element.scrollToMessage(messageID);
      assert.isTrue(scrollToStub.calledOnce);
      assert.isTrue(highlightStub.calledOnce);
      assert.equal(element._visibleMessages.length, 24);
      assert.isTrue(
          element.$$('[data-message-id="' + messageID + '"]')._expanded);
    });

    test('messages', () => {
      const messages = [].concat(
          randomMessage(),
          {
            _index: 5,
            _revision_number: 4,
            message: 'Uploaded patch set 4.',
            date: '2016-09-28 13:36:33.000000000',
            author,
            id: '8c19ccc949c6d482b061be6a28e10782abf0e7af',
          },
          {
            _index: 6,
            _revision_number: 4,
            message: 'Patch Set 4:\n\n(6 comments)',
            date: '2016-09-28 13:36:33.000000000',
            author,
            id: 'e7bfdbc842f6b6d8064bc68e0f52b673f40c0ca5',
          }
      );
      element.messages = messages;
      const isAuthor = function(author, message) {
        return message.author._account_id === author._account_id;
      };
      const isMarvin = isAuthor.bind(null, author);
      flushAsynchronousOperations();
      const messageElements = getMessages();
      assert.equal(messageElements.length, messages.length);
      assert.deepEqual(messageElements[1].message, messages[1]);
      assert.deepEqual(messageElements[2].message, messages[2]);
      assert.deepEqual(messageElements[1].comments.file1,
          comments.file1.filter(isMarvin));
      assert.deepEqual(messageElements[1].comments.file2,
          comments.file2.filter(isMarvin));
      assert.deepEqual(messageElements[2].comments, {});
    });

    test('messages without author do not throw', () => {
      const messages = [{
        _index: 5,
        _revision_number: 4,
        message: 'Uploaded patch set 4.',
        date: '2016-09-28 13:36:33.000000000',
        id: '8c19ccc949c6d482b061be6a28e10782abf0e7af',
      }];
      element.messages = messages;
      flushAsynchronousOperations();
      const messageEls = getMessages();
      assert.equal(messageEls.length, 1);
      assert.equal(messageEls[0].message.message, messages[0].message);
    });

    test('hide increment text if increment >= total remaining', () => {
      // Test with stubbed return values, as _numRemaining and _getDelta have
      // their own tests.
      sandbox.stub(element, '_getDelta').returns(5);
      const remainingStub = sandbox.stub(element, '_numRemaining').returns(6);
      assert.isFalse(element._computeIncrementHidden(null, null, null));
      remainingStub.restore();

      sandbox.stub(element, '_numRemaining').returns(4);
      assert.isTrue(element._computeIncrementHidden(null, null, null));
    });
  });

  suite('gr-messages-list automate tests', () => {
    let element;
    let messages;
    let sandbox;
    let commentApiWrapper;

    const getMessages = function() {
      return Polymer.dom(element.root).querySelectorAll('gr-message');
    };
    const getHiddenMessages = function() {
      return Polymer.dom(element.root).querySelectorAll('gr-message[hidden]');
    };

    const randomMessageReviewer = {
      reviewer: {},
      date: '2016-01-13 20:30:33.038000',
    };

    setup(() => {
      stub('gr-rest-api-interface', {
        getConfig() { return Promise.resolve({}); },
        getLoggedIn() { return Promise.resolve(false); },
        getDiffComments() { return Promise.resolve({}); },
        getDiffRobotComments() { return Promise.resolve({}); },
        getDiffDrafts() { return Promise.resolve({}); },
      });

      sandbox = sinon.sandbox.create();
      messages = _.times(2, randomAutomated);
      messages.push(randomMessageReviewer);

      // Element must be wrapped in an element with direct access to the
      // comment API.
      commentApiWrapper = fixture('basic');
      element = commentApiWrapper.$.messagesList;
      loadCommentSpy = sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll');
      element.messages = messages;

      // Stub methods on the changeComments object after changeComments has
      // been initalized.
      return commentApiWrapper.loadComments();
    });

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

    test('hide autogenerated button is not hidden', () => {
      assert.isNotOk(element.$$('#automatedMessageToggle[hidden]'));
    });

    test('autogenerated messages are not hidden initially', () => {
      const allHiddenMessageEls = getHiddenMessages();

      // There are no hidden messages.
      assert.isFalse(!!allHiddenMessageEls.length);
    });

    test('autogenerated messages hidden after comments only toggle', () => {
      let allHiddenMessageEls = getHiddenMessages();

      element._hideAutomated = false;
      MockInteractions.tap(element.$.automatedMessageToggle);
      flushAsynchronousOperations();
      allMessageEls = getMessages();
      allHiddenMessageEls = getHiddenMessages();

      // Autogenerated messages are now hidden.
      assert.equal(allHiddenMessageEls.length, allMessageEls.length);
    });

    test('autogenerated messages not hidden after comments only toggle',
        () => {
          let allHiddenMessageEls = getHiddenMessages();

          element._hideAutomated = true;
          MockInteractions.tap(element.$.automatedMessageToggle);
          allHiddenMessageEls = getHiddenMessages();

          // Autogenerated messages are now hidden.
          assert.isFalse(!!allHiddenMessageEls.length);
        });

    test('_getDelta', () => {
      let messages = [randomMessage()];
      assert.equal(element._getDelta([], messages, false), 1);
      assert.equal(element._getDelta([], messages, true), 1);


      messages = _.times(7, randomMessage);
      assert.equal(element._getDelta([], messages, false), 5);
      assert.equal(element._getDelta([], messages, true), 5);

      messages = _.times(4, randomMessage)
          .concat(_.times(2, randomAutomated))
          .concat(_.times(3, randomMessage));

      const dummyArr = _.times(2, randomMessage);
      assert.equal(element._getDelta(dummyArr, messages, false), 5);
      assert.equal(element._getDelta(dummyArr, messages, true), 7);
    });

    test('_getHumanMessages', () => {
      assert.equal(
          element._getHumanMessages(_.times(5, randomAutomated)).length, 0);
      assert.equal(
          element._getHumanMessages(_.times(5, randomMessage)).length, 5);

      let messages = _.shuffle(_.times(5, randomMessage)
          .concat(_.times(5, randomAutomated)));
      messages = element._getHumanMessages(messages);
      assert.equal(messages.length, 5);
      assert.isFalse(element._hasAutomatedMessages(messages));
    });

    test('_computeLabelExtremes', () => {
      const computeSpy = sandbox.spy(element, '_computeLabelExtremes');

      element.labels = null;
      assert.isTrue(computeSpy.calledOnce);
      assert.deepEqual(computeSpy.lastCall.returnValue, {});

      element.labels = {};
      assert.isTrue(computeSpy.calledTwice);
      assert.deepEqual(computeSpy.lastCall.returnValue, {});

      element.labels = {'my-label': {}};
      assert.isTrue(computeSpy.calledThrice);
      assert.deepEqual(computeSpy.lastCall.returnValue, {});

      element.labels = {'my-label': {values: {}}};
      assert.equal(computeSpy.callCount, 4);
      assert.deepEqual(computeSpy.lastCall.returnValue, {});

      element.labels = {'my-label': {values: {'-12': {}}}};
      assert.equal(computeSpy.callCount, 5);
      assert.deepEqual(computeSpy.lastCall.returnValue,
          {'my-label': {min: -12, max: -12}});

      element.labels = {
        'my-label': {values: {'-12': {}}},
        'other-label': {values: {'-1': {}, ' 0': {}, '+1': {}}},
      };
      assert.equal(computeSpy.callCount, 6);
      assert.deepEqual(computeSpy.lastCall.returnValue, {
        'my-label': {min: -12, max: -12},
        'other-label': {min: -1, max: 1},
      });
    });
  });
</script>
