<!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-annotation-actions-js-api-js-api</title>

<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>
<script src="../../../test/test-pre-setup.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../../change/gr-change-actions/gr-change-actions.html">

<test-fixture id="basic">
  <template>
    <span hidden id="annotation-span">
      <label for="annotation-checkbox" id="annotation-label"></label>
      <iron-input type="checkbox" disabled>
        <input is="iron-input" type="checkbox" id="annotation-checkbox" disabled>
      </iron-input>
    </span>
  </template>
</test-fixture>

<script>
  suite('gr-annotation-actions-js-api tests', async () => {
    await readyToTest();
    let annotationActions;
    let sandbox;
    let plugin;

    setup(() => {
      sandbox = sinon.sandbox.create();
      Gerrit.install(p => { plugin = p; }, '0.1',
          'http://test.com/plugins/testplugin/static/test.js');
      annotationActions = plugin.annotationApi();
    });

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

    test('add/get layer', () => {
      const str = 'lorem ipsum blah blah';
      const line = {text: str};
      const el = document.createElement('div');
      el.textContent = str;
      const changeNum = 1234;
      const patchNum = 2;
      let testLayerFuncCalled = false;

      const testLayerFunc = context => {
        testLayerFuncCalled = true;
        assert.equal(context.line, line);
        assert.equal(context.changeNum, changeNum);
        assert.equal(context.patchNum, 2);
      };
      annotationActions.addLayer(testLayerFunc);

      const annotationLayer = annotationActions.getLayer(
          '/dummy/path', changeNum, patchNum);

      const lineNumberEl = document.createElement('td');
      annotationLayer.annotate(el, lineNumberEl, line);
      assert.isTrue(testLayerFuncCalled);
    });

    test('add notifier', () => {
      const path1 = '/dummy/path1';
      const path2 = '/dummy/path2';
      const annotationLayer1 = annotationActions.getLayer(path1, 1, 2);
      const annotationLayer2 = annotationActions.getLayer(path2, 1, 2);
      const layer1Spy = sandbox.spy(annotationLayer1, 'notifyListeners');
      const layer2Spy = sandbox.spy(annotationLayer2, 'notifyListeners');

      let notify;
      let notifyFuncCalled;
      const notifyFunc = n => {
        notifyFuncCalled = true;
        notify = n;
      };
      annotationActions.addNotifier(notifyFunc);
      assert.isTrue(notifyFuncCalled);

      // Assert that no layers are invoked with a different path.
      notify('/dummy/path3', 0, 10, 'right');
      assert.isFalse(layer1Spy.called);
      assert.isFalse(layer2Spy.called);

      // Assert that only the 1st layer is invoked with path1.
      notify(path1, 0, 10, 'right');
      assert.isTrue(layer1Spy.called);
      assert.isFalse(layer2Spy.called);

      // Reset spies.
      layer1Spy.reset();
      layer2Spy.reset();

      // Assert that only the 2nd layer is invoked with path2.
      notify(path2, 0, 20, 'left');
      assert.isFalse(layer1Spy.called);
      assert.isTrue(layer2Spy.called);
    });

    test('toggle checkbox', () => {
      const fakeEl = {content: fixture('basic')};
      const hookStub = {onAttached: sandbox.stub()};
      sandbox.stub(plugin, 'hook').returns(hookStub);

      let checkbox;
      let onAttachedFuncCalled = false;
      const onAttachedFunc = c => {
        checkbox = c;
        onAttachedFuncCalled = true;
      };
      annotationActions.enableToggleCheckbox('test label', onAttachedFunc);
      const emulateAttached = () => hookStub.onAttached.callArgWith(0, fakeEl);
      emulateAttached();

      // Assert that onAttachedFunc is called and HTML elements have the
      // expected state.
      assert.isTrue(onAttachedFuncCalled);
      assert.equal(checkbox.id, 'annotation-checkbox');
      assert.isTrue(checkbox.disabled);
      assert.equal(document.getElementById('annotation-label').textContent,
          'test label');
      assert.isFalse(document.getElementById('annotation-span').hidden);

      // Assert that error is shown if we try to enable checkbox again.
      onAttachedFuncCalled = false;
      annotationActions.enableToggleCheckbox('test label2', onAttachedFunc);
      const errorStub = sandbox.stub(
          console, 'error', (msg, err) => undefined);
      emulateAttached();
      assert.isTrue(
          errorStub.calledWith(
              'annotation-span is already enabled. Cannot re-enable.'));
      // Assert that onAttachedFunc is not called and the label has not changed.
      assert.isFalse(onAttachedFuncCalled);
      assert.equal(document.getElementById('annotation-label').textContent,
          'test label');
    });

    test('layer notify listeners', () => {
      const annotationLayer = annotationActions.getLayer(
          '/dummy/path', 1, 2);
      let listenerCalledTimes = 0;
      const startRange = 10;
      const endRange = 20;
      const side = 'right';
      const listener = (st, end, s) => {
        listenerCalledTimes++;
        assert.equal(st, startRange);
        assert.equal(end, endRange);
        assert.equal(s, side);
      };

      // Notify with 0 listeners added.
      annotationLayer.notifyListeners(startRange, endRange, side);
      assert.equal(listenerCalledTimes, 0);

      // Add 1 listener.
      annotationLayer.addListener(listener);
      annotationLayer.notifyListeners(startRange, endRange, side);
      assert.equal(listenerCalledTimes, 1);

      // Add 1 more listener. Total 2 listeners.
      annotationLayer.addListener(listener);
      annotationLayer.notifyListeners(startRange, endRange, side);
      assert.equal(listenerCalledTimes, 3);
    });
  });
</script>
