<!--
@license
Copyright (C) 2018 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-label-info</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-label-info.html">

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

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

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

    setup(() => {
      element = fixture('basic');
      sandbox = sinon.sandbox.create();
      // Needed to trigger computed bindings.
      element.account = {};
      element.change = {labels: {}};
    });

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

    suite('remove reviewer votes', () => {
      setup(() => {
        sandbox.stub(element, '_computeValueTooltip').returns('');
        element.account = {
          _account_id: 1,
          name: 'bojack',
        };
        const test = {
          all: [{_account_id: 1, name: 'bojack', value: 1}],
          default_value: 0,
          values: [],
        };
        element.change = {
          _number: 42,
          change_id: 'the id',
          actions: [],
          topic: 'the topic',
          status: 'NEW',
          submit_type: 'CHERRY_PICK',
          labels: {test},
          removable_reviewers: [],
        };
        element.labelInfo = test;
        element.label = 'test';

        flushAsynchronousOperations();
      });

      test('_computeCanDeleteVote', () => {
        element.mutable = false;
        const button = element.$$('gr-button');
        assert.isTrue(isHidden(button));
        element.change.removable_reviewers = [element.account];
        element.mutable = true;
        assert.isFalse(isHidden(button));
      });

      test('deletes votes', () => {
        const deleteResponse = Promise.resolve({ok: true});
        const deleteStub = sandbox.stub(
            element.$.restAPI, 'deleteVote').returns(deleteResponse);

        element.change.removable_reviewers = [element.account];
        element.change.labels.test.recommended = {_account_id: 1};
        element.mutable = true;
        const button = element.$$('gr-button');
        MockInteractions.tap(button);
        assert.isTrue(button.disabled);
        return deleteResponse.then(() => {
          assert.isFalse(button.disabled);
          assert.isTrue(deleteStub.calledWithExactly(42, 1, 'test'));
        });
      });
    });

    suite('label color and order', () => {
      test('valueless label rejected', () => {
        element.labelInfo = {rejected: {name: 'someone'}};
        flushAsynchronousOperations();
        const labels = Polymer.dom(element.root).querySelectorAll('gr-label');
        assert.isTrue(labels[0].classList.contains('negative'));
      });

      test('valueless label approved', () => {
        element.labelInfo = {approved: {name: 'someone'}};
        flushAsynchronousOperations();
        const labels = Polymer.dom(element.root).querySelectorAll('gr-label');
        assert.isTrue(labels[0].classList.contains('positive'));
      });

      test('-2 to +2', () => {
        element.labelInfo = {
          all: [
            {value: 2, name: 'user 2'},
            {value: 1, name: 'user 1'},
            {value: -1, name: 'user 3'},
            {value: -2, name: 'user 4'},
          ],
          values: {
            '-2': 'Awful',
            '-1': 'Don\'t submit as-is',
            ' 0': 'No score',
            '+1': 'Looks good to me',
            '+2': 'Ready to submit',
          },
        };
        flushAsynchronousOperations();
        const labels = Polymer.dom(element.root).querySelectorAll('gr-label');
        assert.isTrue(labels[0].classList.contains('max'));
        assert.isTrue(labels[1].classList.contains('positive'));
        assert.isTrue(labels[2].classList.contains('negative'));
        assert.isTrue(labels[3].classList.contains('min'));
      });

      test('-1 to +1', () => {
        element.labelInfo = {
          all: [
            {value: 1, name: 'user 1'},
            {value: -1, name: 'user 2'},
          ],
          values: {
            '-1': 'Don\'t submit as-is',
            ' 0': 'No score',
            '+1': 'Looks good to me',
          },
        };
        flushAsynchronousOperations();
        const labels = Polymer.dom(element.root).querySelectorAll('gr-label');
        assert.isTrue(labels[0].classList.contains('max'));
        assert.isTrue(labels[1].classList.contains('min'));
      });

      test('0 to +2', () => {
        element.labelInfo = {
          all: [
            {value: 1, name: 'user 2'},
            {value: 2, name: 'user '},
          ],
          values: {
            ' 0': 'Don\'t submit as-is',
            '+1': 'No score',
            '+2': 'Looks good to me',
          },
        };
        flushAsynchronousOperations();
        const labels = Polymer.dom(element.root).querySelectorAll('gr-label');
        assert.isTrue(labels[0].classList.contains('max'));
        assert.isTrue(labels[1].classList.contains('positive'));
      });

      test('self votes at top', () => {
        element.account = {
          _account_id: 1,
          name: 'bojack',
        };
        element.labelInfo = {
          all: [
            {value: 1, name: 'user 1', _account_id: 2},
            {value: -1, name: 'bojack', _account_id: 1},
          ],
          values: {
            '-1': 'Don\'t submit as-is',
            ' 0': 'No score',
            '+1': 'Looks good to me',
          },
        };
        flushAsynchronousOperations();
        const chips =
            Polymer.dom(element.root).querySelectorAll('gr-account-chip');
        assert.equal(chips[0].account._account_id, element.account._account_id);
      });
    });

    test('_computeValueTooltip', () => {
      // Existing label.
      let labelInfo = {values: {0: 'Baz'}};
      let score = '0';
      assert.equal(element._computeValueTooltip(labelInfo, score), 'Baz');

      // Non-exsistent score.
      score = '2';
      assert.equal(element._computeValueTooltip(labelInfo, score), '');

      // No values on label.
      labelInfo = {values: {}};
      score = '0';
      assert.equal(element._computeValueTooltip(labelInfo, score), '');
    });

    test('placeholder', () => {
      element.labelInfo = {};
      assert.isFalse(isHidden(element.$$('.placeholder')));
      element.labelInfo = {all: []};
      assert.isFalse(isHidden(element.$$('.placeholder')));
      element.labelInfo = {all: [{value: 1}]};
      assert.isTrue(isHidden(element.$$('.placeholder')));
      element.labelInfo = {rejected: []};
      assert.isTrue(isHidden(element.$$('.placeholder')));
      element.labelInfo = {values: [], rejected: [], all: [{value: 1}]};
      assert.isTrue(isHidden(element.$$('.placeholder')));
      element.labelInfo = {approved: []};
      assert.isTrue(isHidden(element.$$('.placeholder')));
      element.labelInfo = {values: [], approved: [], all: [{value: 1}]};
      assert.isTrue(isHidden(element.$$('.placeholder')));
    });
  });
</script>
