<!DOCTYPE html>
<!--
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">

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

    setup(() => {
      sandbox = sinon.sandbox.create();
      let plugin;
      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);

      annotationLayer.annotate(el, 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('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>
