<!DOCTYPE html>
<!--
Copyright (C) 2017 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-score-row</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="gr-label-score-row.html">

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

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

<script>
  suite('gr-label-row-score tests', () => {
    let element;
    let sandbox;

    setup(done => {
      sandbox = sinon.sandbox.create();
      element = fixture('basic');
      element.labels = {
        'Code-Review': {
          values: {
            '0': 'No score',
            '+1': 'good',
            '+2': 'excellent',
            '-1': 'bad',
            '-2': 'terrible',
          },
          default_value: 0,
          value: 1,
          all: [{
            _account_id: 123,
            value: 1,
          }],
        },
        'Verified': {
          values: {
            '0': 'No score',
            '+1': 'good',
            '+2': 'excellent',
            '-1': 'bad',
            '-2': 'terrible',
          },
          default_value: 0,
          value: 1,
          all: [{
            _account_id: 123,
            value: 1,
          }],
        },
      };

      element.permittedLabels = {
        'Code-Review': [
          '-2',
          '-1',
          ' 0',
          '+1',
          '+2',
        ],
        'Verified': [
          '-1',
          ' 0',
          '+1',
        ],
      };

      element.labelValues = {'0': 2, '1': 3, '2': 4, '-2': 0, '-1': 1};

      element.label = {
        name: 'Verified',
        value: '+1',
      };

      flush(done);
    });

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

    test('label picker', () => {
      const labelsChangedHandler = sandbox.stub();
      element.addEventListener('labels-changed', labelsChangedHandler);
      assert.ok(element.$$('iron-selector'));
      MockInteractions.tap(element.$$(
          'gr-button[value="-1"]'));
      flushAsynchronousOperations();
      assert.strictEqual(element.selectedValue, '-1');
      assert.strictEqual(element.selectedItem
          .textContent.trim(), '-1');
      assert.strictEqual(
          element.$.selectedValueLabel.textContent.trim(), 'bad');
      assert.isTrue(labelsChangedHandler.called);
    });

    test('correct item is selected', () => {
      // 1 should be the value of the selected item
      assert.strictEqual(element.$$('iron-selector').selected, '+1');
      assert.strictEqual(
          element.$$('iron-selector').selectedItem
              .textContent.trim(), '+1');
      assert.strictEqual(
          element.$.selectedValueLabel.textContent.trim(), 'good');
    });

    test('do not display tooltips on touch devices', () => {
      const verifiedBtn = element.$$(
          'iron-selector > gr-button[value="-1"]');

      // On touch devices, tooltips should not be shown.
      verifiedBtn._isTouchDevice = true;
      verifiedBtn._handleShowTooltip();
      assert.isNotOk(verifiedBtn._tooltip);
      verifiedBtn._handleHideTooltip();
      assert.isNotOk(verifiedBtn._tooltip);

      // On other devices, tooltips should be shown.
      verifiedBtn._isTouchDevice = false;
      verifiedBtn._handleShowTooltip();
      assert.isOk(verifiedBtn._tooltip);
      verifiedBtn._handleHideTooltip();
      assert.isNotOk(verifiedBtn._tooltip);
    });

    test('_computeLabelValue', () => {
      assert.strictEqual(element._computeLabelValue(element.labels,
          element.permittedLabels,
          element.label), '+1');
    });

    test('_computeBlankItems', () => {
      element.labelValues = {
        '-2': 0,
        '-1': 1,
        '0': 2,
        '1': 3,
        '2': 4,
      };

      assert.strictEqual(element._computeBlankItems(element.permittedLabels,
          'Code-Review').length, 0);

      assert.strictEqual(element._computeBlankItems(element.permittedLabels,
          'Verified').length, 1);
    });

    test('changes in label score are reflected in the DOM', () => {
      element.labels = {
        'Code-Review': {
          values: {
            '0': 'No score',
            '+1': 'good',
            '+2': 'excellent',
            '-1': 'bad',
            '-2': 'terrible',
          },
          default_value: 0,
        },
        'Verified': {
          values: {
            ' 0': 'No score',
            '+1': 'good',
            '+2': 'excellent',
            '-1': 'bad',
            '-2': 'terrible',
          },
          default_value: 0,
        },
      };
      const selector = element.$$('iron-selector');
      element.set('label', {name: 'Verified', value: ' 0'});
      flushAsynchronousOperations();
      assert.strictEqual(selector.selected, ' 0');
      assert.strictEqual(
          element.$.selectedValueLabel.textContent.trim(), 'No score');
    });

    test('without permitted labels', () => {
      element.permittedLabels = {
        Verified: [
          '-1',
          ' 0',
          '+1',
        ],
      };
      flushAsynchronousOperations();
      assert.isOk(element.$$('iron-selector'));
      assert.isFalse(element.$$('iron-selector').hidden);

      element.permittedLabels = {};
      flushAsynchronousOperations();
      assert.isOk(element.$$('iron-selector'));
      assert.isTrue(element.$$('iron-selector').hidden);
    });

    test('asymetrical labels', () => {
      element.permittedLabels = {
        'Code-Review': [
          '-2',
          '-1',
          ' 0',
          '+1',
          '+2',
        ],
        'Verified': [
          ' 0',
          '+1',
        ],
      };
      flushAsynchronousOperations();
      assert.strictEqual(element.$$('iron-selector')
          .items.length, 2);
      assert.strictEqual(Polymer.dom(element.root).
          querySelectorAll('.placeholder').length, 3);

      element.permittedLabels = {
        'Code-Review': [
          ' 0',
          '+1',
        ],
        'Verified': [
          '-2',
          '-1',
          ' 0',
          '+1',
          '+2',
        ],
      };
      flushAsynchronousOperations();
      assert.strictEqual(element.$$('iron-selector')
          .items.length, 5);
      assert.strictEqual(Polymer.dom(element.root).
          querySelectorAll('.placeholder').length, 0);
    });

    test('default_value', () => {
      element.permittedLabels = {
        Verified: [
          '-1',
          ' 0',
          '+1',
        ],
      };
      element.labels = {
        Verified: {
          values: {
            '0': 'No score',
            '+1': 'good',
            '+2': 'excellent',
            '-1': 'bad',
            '-2': 'terrible',
          },
          default_value: -1,
        },
      };
      element.label = {
        name: 'Verified',
        value: null,
      };
      flushAsynchronousOperations();
      assert.strictEqual(element.selectedValue, '-1');
    });

    test('default_value is null if not permitted', () => {
      element.permittedLabels = {
        Verified: [
          '-1',
          ' 0',
          '+1',
        ],
      };
      element.labels = {
        'Code-Review': {
          values: {
            '0': 'No score',
            '+1': 'good',
            '+2': 'excellent',
            '-1': 'bad',
            '-2': 'terrible',
          },
          default_value: -1,
        },
      };
      element.label = {
        name: 'Code-Review',
        value: null,
      };
      flushAsynchronousOperations();
      assert.isNull(element.selectedValue);
    });
  });
</script>
