<!DOCTYPE html>
<!--
@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-opacity-diff-mode</title>

<link rel="import" href="../node_modules/polymer/polymer.html">
<link rel="import" href="../node_modules/@polymer/test-fixture/test-fixture.html">
<link rel="import" href="../node_modules/iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="./gr-opacity-diff-mode.html">

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

<script src="../node_modules/webcomponents.js/webcomponents-lite.min.js"></script>
<script src="../node_modules/web-component-tester/browser.js"></script>
<script src="../node_modules/@polymer/sinonjs/sinon.js"></script>

<test-fixture id='opacity-diff-fixture'>
  <template>
    <gr-opacity-diff-mode></gr-opacity-diff-mode>
  </template>
</test-fixture>

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

    setup(() => {
      stub('gr-opacity-diff-mode', {
        attached() {},
      });
      element= fixture('opacity-diff-fixture');
    });

    test('slider changes opacity of image', () => {
      const arrayOfNumbers = [0.73, 0.5, 0.0];
      arrayOfNumbers.forEach(number => {
        assert.notEqual(element.customStyle['--my-opacity-value'], number);
        element.$.opacitySlider.value = number;
        element.handleOpacityChange();
        assert.equal(element.customStyle['--my-opacity-value'], number);
      });
    });

    test('create the src string for images', () => {
      element.revisionImage = {
        type: 'IMG/src',
        body: 'Zx3Cgffk=',
      };
      const expectedOutcome = 'data:IMG/src;base64, Zx3Cgffk=';
      assert.equal(element.computeSrcString(element.revisionImage),
          expectedOutcome);
    });

    suite('size scaling', () => {
      test('base image larger', () => {
        element.baseImage = {
          _width: 200,
          _height: 300,
        };
        element.revisionImage = {
          _width: 100,
          _height: 90,
        };
        assert.equal(element.customStyle['--img-width'], undefined);
        assert.equal(element.customStyle['--img-height'], undefined);
        element.$.scaleSizesToggle.checked = true;
        element.handleScaleSizesToggle();
        flushAsynchronousOperations();
        assert.equal(element.customStyle['--img-width'], '200px');
        assert.equal(element.customStyle['--img-height'], '300px');
      });

      test('revisionImage larger', () => {
        element.baseImage = {
          _width: 200,
          _height: 300,
        };
        element.revisionImage = {
          _width: 400,
          _height: 500,
        };
        assert.equal(element.customStyle['--img-width'], null);
        assert.equal(element.customStyle['--img-height'], null);
        element.$.scaleSizesToggle.checked = true;
        element.handleScaleSizesToggle();
        flushAsynchronousOperations();
        assert.equal(element.customStyle['--img-width'], '400px');
        assert.equal(element.customStyle['--img-height'], '500px');
      });

      test('bigger base width, smaller base height', () => {
        element.baseImage = {
          _width: 200,
          _height: 300,
        };
        element.revisionImage = {
          _width: 140,
          _height: 400,
        };
        assert.equal(element.customStyle['--img-width'], null);
        assert.equal(element.customStyle['--img-height'], null);
        element.$.scaleSizesToggle.checked = true;
        element.handleScaleSizesToggle();
        flushAsynchronousOperations();
        assert.equal(element.customStyle['--img-width'], '200px');
        assert.equal(element.customStyle['--img-height'], '400px');
      });
    });
    test('resize the div container for base & revision image comparison', () => {
      element.baseImage = {
        _height: 500,
      };
      element.revisionImage = {
        _height: 300,
      };
      assert.equal(element.customStyle['--div-height'], undefined);
      element.resizeDiffContainerHeight();
      flushAsynchronousOperations();
      assert.equal(element.customStyle['--div-height'], '500px');
    });
  });
</script>