<!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/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="../../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>
      <input is="iron-input" type="checkbox" id="annotation-checkbox" disabled>
    </span>
  </template>
</test-fixture>

<script>
  suite('gr-annotation-actions-js-api tests', () => {
    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};
      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;
      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', () => {
      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);
      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>
