<!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-message</title>
<script src="/test/common-test-setup.js"></script>
<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>

<script src="/bower_components/webcomponentsjs/webcomponents-lite.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-message.html">

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

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

<script>
  suite('gr-message tests', () => {
    let element;

    setup(done => {
      stub('gr-rest-api-interface', {
        getLoggedIn() { return Promise.resolve(false); },
        getConfig() { return Promise.resolve({}); },
      });
      element = fixture('basic');
      flush(done);
    });

    test('reply event', done => {
      element.message = {
        id: '47c43261_55aa2c41',
        author: {
          _account_id: 1115495,
          name: 'Andrew Bonventre',
          email: 'andybons@chromium.org',
        },
        date: '2016-01-12 20:24:49.448000000',
        message: 'Uploaded patch set 1.',
        _revision_number: 1,
        expanded: false,
      };

      element.addEventListener('reply', e => {
        assert.deepEqual(e.detail.message, element.message);
        done();
      });
      flushAsynchronousOperations();
      MockInteractions.tap(element.$$('.replyContainer gr-button'));
    });

    test('autogenerated prefix hiding', () => {
      element.message = {
        tag: 'autogenerated:gerrit:test',
        updated: '2016-01-12 20:24:49.448000000',
        expanded: false,
      };

      assert.isTrue(element.isAutomated);
      assert.isFalse(element.hidden);

      element.hideAutomated = true;

      assert.isTrue(element.hidden);
    });

    test('reviewer message treated as autogenerated', () => {
      element.message = {
        tag: 'autogenerated:gerrit:test',
        updated: '2016-01-12 20:24:49.448000000',
        reviewer: {},
        expanded: false,
      };

      assert.isTrue(element.isAutomated);
      assert.isFalse(element.hidden);

      element.hideAutomated = true;

      assert.isTrue(element.hidden);
    });

    test('batch reviewer message treated as autogenerated', () => {
      element.message = {
        type: 'REVIEWER_UPDATE',
        updated: '2016-01-12 20:24:49.448000000',
        reviewer: {},
        expanded: false,
      };

      assert.isTrue(element.isAutomated);
      assert.isFalse(element.hidden);

      element.hideAutomated = true;

      assert.isTrue(element.hidden);
    });

    test('tag that is not autogenerated prefix does not hide', () => {
      element.message = {
        tag: 'something',
        updated: '2016-01-12 20:24:49.448000000',
        expanded: false,
      };

      assert.isFalse(element.isAutomated);
      assert.isFalse(element.hidden);

      element.hideAutomated = true;

      assert.isFalse(element.hidden);
    });

    test('reply button hidden unless logged in', () => {
      const message = {
        message: 'Uploaded patch set 1.',
        expanded: false,
      };
      assert.isFalse(element._computeShowReplyButton(message, false));
      assert.isTrue(element._computeShowReplyButton(message, true));
    });

    test('_computeShowOnBehalfOf', () => {
      const message = {
        message: '...',
        expanded: false,
      };
      assert.isNotOk(element._computeShowOnBehalfOf(message));
      message.author = {_account_id: 1115495};
      assert.isNotOk(element._computeShowOnBehalfOf(message));
      message.real_author = {_account_id: 1115495};
      assert.isNotOk(element._computeShowOnBehalfOf(message));
      message.real_author._account_id = 123456;
      assert.isOk(element._computeShowOnBehalfOf(message));
      message.updated_by = message.author;
      delete message.author;
      assert.isOk(element._computeShowOnBehalfOf(message));
      delete message.updated_by;
      assert.isNotOk(element._computeShowOnBehalfOf(message));
    });

    ['Trybot-Ready', 'Tryjob-Request', 'Commit-Queue'].forEach(label => {
      test(`${label} ignored for color voting`, () => {
        element.message = {
          author: {},
          expanded: false,
          message: `Patch Set 1: ${label}+1`,
        };
        assert.isNotOk(
            Polymer.dom(element.root).querySelector('.negativeVote'));
        assert.isNotOk(
            Polymer.dom(element.root).querySelector('.positiveVote'));
      });
    });

    test('clicking on date link fires event', () => {
      element.message = {
        type: 'REVIEWER_UPDATE',
        updated: '2016-01-12 20:24:49.448000000',
        reviewer: {},
        id: '47c43261_55aa2c41',
        expanded: false,
      };
      flushAsynchronousOperations();
      const stub = sinon.stub();
      element.addEventListener('message-anchor-tap', stub);
      const dateEl = element.$$('.date');
      assert.ok(dateEl);
      MockInteractions.tap(dateEl);

      assert.isTrue(stub.called);
      assert.deepEqual(stub.lastCall.args[0].detail, {id: element.message.id});
    });

    test('votes', () => {
      element.message = {
        author: {},
        expanded: false,
        message: 'Patch Set 1: Verified+1 Code-Review-2 Trybot-Ready+1',
      };
      element.labelExtremes = {
        'Verified': {max: 1, min: -1},
        'Code-Review': {max: 2, min: -2},
        'Trybot-Ready': {max: 3, min: 0},
      };
      flushAsynchronousOperations();
      const scoreChips = Polymer.dom(element.root).querySelectorAll('.score');
      assert.equal(scoreChips.length, 3);

      assert.isTrue(scoreChips[0].classList.contains('positive'));
      assert.isTrue(scoreChips[0].classList.contains('max'));

      assert.isTrue(scoreChips[1].classList.contains('negative'));
      assert.isTrue(scoreChips[1].classList.contains('min'));

      assert.isTrue(scoreChips[2].classList.contains('positive'));
      assert.isFalse(scoreChips[2].classList.contains('min'));
    });

    test('false negative vote', () => {
      element.message = {
        author: {},
        expanded: false,
        message: 'Patch Set 1: Cherry Picked from branch stable-2.14.',
      };
      element.labelExtremes = {};
      const scoreChips = Polymer.dom(element.root).querySelectorAll('.score');
      assert.equal(scoreChips.length, 0);
    });
  });
</script>
