<!--
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>resemble-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-resemble-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="basicFixture">
  <template>
    <gr-resemble-diff-mode>
    </gr-resemble-diff-mode>
  </template>
</test-fixture>

<script>
  suite('gr-resemble-diff-mode tests', () => {
    let element;
    let sandbox;

    setup(() => {
      sandbox = sinon.sandbox.create();
      element = fixture('basicFixture');
    });

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

    test('test initialization', () => {
      assert.notEqual(element, null);
      assert.equal(element.baseImage, null);
      assert.equal(element.revisionImage, null);
    });

    test('_setImageDiffSrc', () => {
      const img = element.$.imageDiff;
      const src = 'data:image/png;base64,SGVsbG8=';
      assert.notOk(img.getAttribute('src'));
      element._setImageDiffSrc(src);
      assert.equal(img.getAttribute('src'), src);
    });

    test('_setDifferenceValue', () => {
      const expected = 0.15;
      element._setDifferenceValue(expected);
      assert.equal(element._difference, expected);
    });

    test('_maybeIgnoreColors', () => {
      const dummyProcess = {
        ignoreColors: sandbox.stub(),
        ignoreNothing: sandbox.stub(),
      };
      element._maybeIgnoreColors(dummyProcess, false);
      assert.isFalse(dummyProcess.ignoreColors.called);
      assert.isTrue(dummyProcess.ignoreNothing.called);
      element._maybeIgnoreColors(dummyProcess, true);
      assert.isTrue(dummyProcess.ignoreColors.called);
    });

    test('_setOutputSetting', () => {
      sandbox.stub(window.resemble, 'outputSettings');
      element._transparent = true;
      element._colorValue = '#00ffff';
      const expectedResult = {
        transparency: 0.1,
        errorColor: {
          red: 0,
          green: 255,
          blue: 255,
        },
      };
      element._createDiffProcess();
      flushAsynchronousOperations();

      assert.isTrue(window.resemble.outputSettings.called);
      sinon.assert.calledWith(window.resemble.outputSettings, expectedResult);
    });

    test('_handleIgnoreColorsToggle', () => {
      sandbox.stub(element, 'reload');
      element._ignoreColors = false;
      assert.isFalse(element.$.ignoreColorsToggle.checked);
      MockInteractions.tap(element.$.ignoreColorsToggle);
      element.flushDebouncer('ignore-colors-toggle');
      flushAsynchronousOperations();

      assert.isTrue(element._ignoreColors);
      assert.isTrue(element.reload.called);
    });

    test('_handleTransparentToggle', () => {
      sandbox.stub(element, 'reload');
      element._transparent = false;
      assert.isFalse(element.$.transparentToggle.checked);
      MockInteractions.tap(element.$.transparentToggle);
      element.flushDebouncer('transparent-toggle');
      flushAsynchronousOperations();

      assert.isTrue(element._transparent);
      assert.isTrue(element.reload.called);
    });

    test('_handleColorChange', () => {
      sandbox.stub(element, 'reload');
      element._colorValue = '';
      element.flushDebouncer('color-change');
      flushAsynchronousOperations();

      assert.isTrue(element.reload.called);
    });

    test('_hexToRGB', () => {
      const expected = {r: 0, g: 255, b: 255};
      const input = '#00ffff';
      const output = element._hexToRGB(input);
      assert.equal(output.r, expected.r);
      assert.equal(output.g, expected.g);
      assert.equal(output.b, expected.b);
    });

    test('_handleFullScreen', () => {
      sandbox.stub(element, '_handleFullScreen');
      MockInteractions.tap(element.$.fullscreen);
      flushAsynchronousOperations();

      assert.isTrue(element._handleFullScreen.called);
    });

    test('calls reload', () => {
      sandbox.stub(element, 'reload');
      element.baseImage = {};
      assert.equal(element.reload.callCount, 0);
      element.revisionImage = {};
      assert.equal(element.reload.callCount, 1);
      MockInteractions.tap(element.$.ignoreColorsToggle);
      element.flushDebouncer('ignore-colors-toggle');
      assert.equal(element.reload.callCount, 2);
      MockInteractions.tap(element.$.transparentToggle);
      element.flushDebouncer('transparent-toggle');
      assert.equal(element.reload.callCount, 3);
    });
  });
</script>