<!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-api-interface</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>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-js-api-interface.html">

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

<test-fixture id="basic">
  <template>
    <gr-js-api-interface></gr-js-api-interface>
  </template>
</test-fixture>

<script>
  const {PLUGIN_LOADING_TIMEOUT_MS} = window._apiUtils;
  suite('gr-js-api-interface tests', () => {
    let element;
    let plugin;
    let errorStub;
    let sandbox;
    let getResponseObjectStub;
    let sendStub;

    const throwErrFn = function() {
      throw Error('Unfortunately, this handler has stopped');
    };

    setup(() => {
      this.clock = sinon.useFakeTimers();
      sandbox = sinon.sandbox.create();
      getResponseObjectStub = sandbox.stub().returns(Promise.resolve());
      sendStub = sandbox.stub().returns(Promise.resolve({status: 200}));
      stub('gr-rest-api-interface', {
        getAccount() {
          return Promise.resolve({name: 'Judy Hopps'});
        },
        getResponseObject: getResponseObjectStub,
        send(...args) {
          return sendStub(...args);
        },
      });
      element = fixture('basic');
      errorStub = sandbox.stub(console, 'error');
      Gerrit.install(p => { plugin = p; }, '0.1',
          'http://test.com/plugins/testplugin/static/test.js');
      Gerrit._loadPlugins([]);
    });

    teardown(() => {
      this.clock.restore();
      sandbox.restore();
      element._removeEventCallbacks();
      plugin = null;
    });

    test('url', () => {
      assert.equal(plugin.url(), 'http://test.com/plugins/testplugin/');
      assert.equal(plugin.url('/static/test.js'),
          'http://test.com/plugins/testplugin/static/test.js');
    });

    test('url for preloaded plugin without ASSETS_PATH', () => {
      let plugin;
      Gerrit.install(p => { plugin = p; }, '0.1',
          'preloaded:testpluginB');
      assert.equal(plugin.url(),
          `${window.location.origin}/plugins/testpluginB/`);
      assert.equal(plugin.url('/static/test.js'),
          `${window.location.origin}/plugins/testpluginB/static/test.js`);
    });

    test('url for preloaded plugin without ASSETS_PATH', () => {
      const oldAssetsPath = window.ASSETS_PATH;
      window.ASSETS_PATH = 'http://test.com';
      let plugin;
      Gerrit.install(p => { plugin = p; }, '0.1',
          'preloaded:testpluginC');
      assert.equal(plugin.url(), `${window.ASSETS_PATH}/plugins/testpluginC/`);
      assert.equal(plugin.url('/static/test.js'),
          `${window.ASSETS_PATH}/plugins/testpluginC/static/test.js`);
      window.ASSETS_PATH = oldAssetsPath;
    });

    test('_send on failure rejects with response text', () => {
      sendStub.returns(Promise.resolve(
          {status: 400, text() { return Promise.resolve('text'); }}));
      return plugin._send().catch(r => {
        assert.equal(r, 'text');
      });
    });

    test('_send on failure without text rejects with code', () => {
      sendStub.returns(Promise.resolve(
          {status: 400, text() { return Promise.resolve(null); }}));
      return plugin._send().catch(r => {
        assert.equal(r, '400');
      });
    });

    test('get', () => {
      const response = {foo: 'foo'};
      getResponseObjectStub.returns(Promise.resolve(response));
      return plugin.get('/url', r => {
        assert.isTrue(sendStub.calledWith(
            'GET', 'http://test.com/plugins/testplugin/url'));
        assert.strictEqual(r, response);
      });
    });

    test('get using Promise', () => {
      const response = {foo: 'foo'};
      getResponseObjectStub.returns(Promise.resolve(response));
      return plugin.get('/url', r => 'rubbish').then(r => {
        assert.isTrue(sendStub.calledWith(
            'GET', 'http://test.com/plugins/testplugin/url'));
        assert.strictEqual(r, response);
      });
    });

    test('post', () => {
      const payload = {foo: 'foo'};
      const response = {bar: 'bar'};
      getResponseObjectStub.returns(Promise.resolve(response));
      return plugin.post('/url', payload, r => {
        assert.isTrue(sendStub.calledWith(
            'POST', 'http://test.com/plugins/testplugin/url', payload));
        assert.strictEqual(r, response);
      });
    });

    test('put', () => {
      const payload = {foo: 'foo'};
      const response = {bar: 'bar'};
      getResponseObjectStub.returns(Promise.resolve(response));
      return plugin.put('/url', payload, r => {
        assert.isTrue(sendStub.calledWith(
            'PUT', 'http://test.com/plugins/testplugin/url', payload));
        assert.strictEqual(r, response);
      });
    });

    test('delete works', () => {
      const response = {status: 204};
      sendStub.returns(Promise.resolve(response));
      return plugin.delete('/url', r => {
        assert.isTrue(sendStub.calledWithExactly(
            'DELETE', 'http://test.com/plugins/testplugin/url'));
        assert.strictEqual(r, response);
      });
    });

    test('delete fails', () => {
      sendStub.returns(Promise.resolve(
          {status: 400, text() { return Promise.resolve('text'); }}));
      return plugin.delete('/url', r => {
        throw new Error('Should not resolve');
      }).catch(err => {
        assert.isTrue(sendStub.calledWith(
            'DELETE', 'http://test.com/plugins/testplugin/url'));
        assert.equal('text', err);
      });
    });

    test('history event', done => {
      plugin.on(element.EventType.HISTORY, throwErrFn);
      plugin.on(element.EventType.HISTORY, path => {
        assert.equal(path, '/path/to/awesomesauce');
        assert.isTrue(errorStub.calledOnce);
        done();
      });
      element.handleEvent(element.EventType.HISTORY,
          {path: '/path/to/awesomesauce'});
    });

    test('showchange event', done => {
      const testChange = {
        _number: 42,
        revisions: {def: {_number: 2}, abc: {_number: 1}},
      };
      const expectedChange = Object.assign({mergeable: false}, testChange);
      plugin.on(element.EventType.SHOW_CHANGE, throwErrFn);
      plugin.on(element.EventType.SHOW_CHANGE, (change, revision, info) => {
        assert.deepEqual(change, expectedChange);
        assert.deepEqual(revision, testChange.revisions.abc);
        assert.deepEqual(info, {mergeable: false});
        assert.isTrue(errorStub.calledOnce);
        done();
      });
      element.handleEvent(element.EventType.SHOW_CHANGE,
          {change: testChange, patchNum: 1, info: {mergeable: false}});
    });

    test('handleEvent awaits plugins load', done => {
      const testChange = {
        _number: 42,
        revisions: {def: {_number: 2}, abc: {_number: 1}},
      };
      const spy = sandbox.spy();
      Gerrit._loadPlugins(['plugins/test.html']);
      plugin.on(element.EventType.SHOW_CHANGE, spy);
      element.handleEvent(element.EventType.SHOW_CHANGE,
          {change: testChange, patchNum: 1});
      assert.isFalse(spy.called);

      // Timeout on loading plugins
      this.clock.tick(PLUGIN_LOADING_TIMEOUT_MS * 2);

      flush(() => {
        assert.isTrue(spy.called);
        done();
      });
    });

    test('comment event', done => {
      const testCommentNode = {foo: 'bar'};
      plugin.on(element.EventType.COMMENT, throwErrFn);
      plugin.on(element.EventType.COMMENT, commentNode => {
        assert.deepEqual(commentNode, testCommentNode);
        assert.isTrue(errorStub.calledOnce);
        done();
      });
      element.handleEvent(element.EventType.COMMENT, {node: testCommentNode});
    });

    test('revert event', () => {
      function appendToRevertMsg(c, revertMsg, originalMsg) {
        return revertMsg + '\n' + originalMsg.replace(/^/gm, '> ') + '\ninfo';
      }

      assert.equal(element.modifyRevertMsg(null, 'test', 'origTest'), 'test');
      assert.equal(errorStub.callCount, 0);

      plugin.on(element.EventType.REVERT, throwErrFn);
      plugin.on(element.EventType.REVERT, appendToRevertMsg);
      assert.equal(element.modifyRevertMsg(null, 'test', 'origTest'),
          'test\n> origTest\ninfo');
      assert.isTrue(errorStub.calledOnce);

      plugin.on(element.EventType.REVERT, appendToRevertMsg);
      assert.equal(element.modifyRevertMsg(null, 'test', 'origTest'),
          'test\n> origTest\ninfo\n> origTest\ninfo');
      assert.isTrue(errorStub.calledTwice);
    });

    test('postrevert event', () => {
      function getLabels(c) {
        return {'Code-Review': 1};
      }

      assert.deepEqual(element.getLabelValuesPostRevert(null), {});
      assert.equal(errorStub.callCount, 0);

      plugin.on(element.EventType.POST_REVERT, throwErrFn);
      plugin.on(element.EventType.POST_REVERT, getLabels);
      assert.deepEqual(
          element.getLabelValuesPostRevert(null), {'Code-Review': 1});
      assert.isTrue(errorStub.calledOnce);
    });

    test('commitmsgedit event', done => {
      const testMsg = 'Test CL commit message';
      plugin.on(element.EventType.COMMIT_MSG_EDIT, throwErrFn);
      plugin.on(element.EventType.COMMIT_MSG_EDIT, (change, msg) => {
        assert.deepEqual(msg, testMsg);
        assert.isTrue(errorStub.calledOnce);
        done();
      });
      element.handleCommitMessage(null, testMsg);
    });

    test('labelchange event', done => {
      const testChange = {_number: 42};
      plugin.on(element.EventType.LABEL_CHANGE, throwErrFn);
      plugin.on(element.EventType.LABEL_CHANGE, change => {
        assert.deepEqual(change, testChange);
        assert.isTrue(errorStub.calledOnce);
        done();
      });
      element.handleEvent(element.EventType.LABEL_CHANGE, {change: testChange});
    });

    test('submitchange', () => {
      plugin.on(element.EventType.SUBMIT_CHANGE, throwErrFn);
      plugin.on(element.EventType.SUBMIT_CHANGE, () => { return true; });
      assert.isTrue(element.canSubmitChange());
      assert.isTrue(errorStub.calledOnce);
      plugin.on(element.EventType.SUBMIT_CHANGE, () => { return false; });
      plugin.on(element.EventType.SUBMIT_CHANGE, () => { return true; });
      assert.isFalse(element.canSubmitChange());
      assert.isTrue(errorStub.calledTwice);
    });

    test('highlightjs-loaded event', done => {
      const testHljs = {_number: 42};
      plugin.on(element.EventType.HIGHLIGHTJS_LOADED, throwErrFn);
      plugin.on(element.EventType.HIGHLIGHTJS_LOADED, hljs => {
        assert.deepEqual(hljs, testHljs);
        assert.isTrue(errorStub.calledOnce);
        done();
      });
      element.handleEvent(element.EventType.HIGHLIGHTJS_LOADED, {hljs: testHljs});
    });

    test('getAccount', done => {
      plugin.restApi().getLoggedIn().then(loggedIn => {
        assert.isTrue(loggedIn);
        done();
      });
    });

    test('attributeHelper', () => {
      assert.isOk(plugin.attributeHelper());
    });

    test('deprecated.install', () => {
      plugin.deprecated.install();
      assert.strictEqual(plugin.popup, plugin.deprecated.popup);
      assert.strictEqual(plugin.onAction, plugin.deprecated.onAction);
      assert.notStrictEqual(plugin.install, plugin.deprecated.install);
    });

    test('getAdminMenuLinks', () => {
      const links = [{text: 'a', url: 'b'}, {text: 'c', url: 'd'}];
      const getCallbacksStub = sandbox.stub(element, '_getEventCallbacks')
          .returns([
            {getMenuLinks: () => [links[0]]},
            {getMenuLinks: () => [links[1]]},
          ]);
      const result = element.getAdminMenuLinks();
      assert.deepEqual(result, links);
      assert.isTrue(getCallbacksStub.calledOnce);
      assert.equal(getCallbacksStub.lastCall.args[0],
          element.EventType.ADMIN_MENU_LINKS);
    });

    suite('test plugin with base url', () => {
      let baseUrlPlugin;

      setup(() => {
        sandbox.stub(Gerrit.BaseUrlBehavior, 'getBaseUrl').returns('/r');

        Gerrit.install(p => { baseUrlPlugin = p; }, '0.1',
            'http://test.com/r/plugins/baseurlplugin/static/test.js');
      });

      test('url', () => {
        assert.notEqual(baseUrlPlugin.url(),
            'http://test.com/plugins/baseurlplugin/');
        assert.equal(baseUrlPlugin.url(),
            'http://test.com/r/plugins/baseurlplugin/');
        assert.equal(baseUrlPlugin.url('/static/test.js'),
            'http://test.com/r/plugins/baseurlplugin/static/test.js');
      });
    });

    suite('popup', () => {
      test('popup(element) is deprecated', () => {
        plugin.popup(document.createElement('div'));
        assert.isTrue(console.error.calledOnce);
      });

      test('popup(moduleName) creates popup with component', () => {
        const openStub = sandbox.stub();
        sandbox.stub(window, 'GrPopupInterface').returns({
          open: openStub,
        });
        plugin.popup('some-name');
        assert.isTrue(openStub.calledOnce);
        assert.isTrue(GrPopupInterface.calledWith(plugin, 'some-name'));
      });

      test('deprecated.popup(element) creates popup with element', () => {
        const el = document.createElement('div');
        el.textContent = 'some text here';
        const openStub = sandbox.stub(GrPopupInterface.prototype, 'open');
        openStub.returns(Promise.resolve({
          _getElement() {
            return document.createElement('div');
          }}));
        plugin.deprecated.popup(el);
        assert.isTrue(openStub.calledOnce);
      });
    });

    suite('onAction', () => {
      let change;
      let revision;
      let actionDetails;

      setup(() => {
        change = {};
        revision = {};
        actionDetails = {__key: 'some'};
        sandbox.stub(plugin, 'on').callsArgWith(1, change, revision);
        sandbox.stub(plugin, 'changeActions').returns({
          addTapListener: sandbox.stub().callsArg(1),
          getActionDetails: () => actionDetails,
        });
      });

      test('returns GrPluginActionContext', () => {
        const stub = sandbox.stub();
        plugin.deprecated.onAction('change', 'foo', ctx => {
          assert.isTrue(ctx instanceof GrPluginActionContext);
          assert.strictEqual(ctx.change, change);
          assert.strictEqual(ctx.revision, revision);
          assert.strictEqual(ctx.action, actionDetails);
          assert.strictEqual(ctx.plugin, plugin);
          stub();
        });
        assert.isTrue(stub.called);
      });

      test('other actions', () => {
        const stub = sandbox.stub();
        plugin.deprecated.onAction('project', 'foo', stub);
        plugin.deprecated.onAction('edit', 'foo', stub);
        plugin.deprecated.onAction('branch', 'foo', stub);
        assert.isFalse(stub.called);
      });
    });

    suite('screen', () => {
      test('screenUrl()', () => {
        sandbox.stub(Gerrit.BaseUrlBehavior, 'getBaseUrl').returns('/base');
        assert.equal(plugin.screenUrl(), 'http://test.com/base/x/testplugin');
        assert.equal(
            plugin.screenUrl('foo'), 'http://test.com/base/x/testplugin/foo');
      });

      test('deprecated works', () => {
        const stub = sandbox.stub();
        const hookStub = {onAttached: sandbox.stub()};
        sandbox.stub(plugin, 'hook').returns(hookStub);
        plugin.deprecated.screen('foo', stub);
        assert.isTrue(plugin.hook.calledWith('testplugin-screen-foo'));
        const fakeEl = {style: {display: ''}};
        hookStub.onAttached.callArgWith(0, fakeEl);
        assert.isTrue(stub.called);
        assert.equal(fakeEl.style.display, 'none');
      });

      test('works', () => {
        sandbox.stub(plugin, 'registerCustomComponent');
        plugin.screen('foo', 'some-module');
        assert.isTrue(plugin.registerCustomComponent.calledWith(
            'testplugin-screen-foo', 'some-module'));
      });
    });

    suite('panel', () => {
      let fakeEl;
      let emulateAttached;

      setup(()=> {
        fakeEl = {change: {}, revision: {}};
        const hookStub = {onAttached: sandbox.stub()};
        sandbox.stub(plugin, 'hook').returns(hookStub);
        emulateAttached = () => hookStub.onAttached.callArgWith(0, fakeEl);
      });

      test('plugin.panel is deprecated', () => {
        plugin.panel('rubbish');
        assert.isTrue(console.error.called);
      });

      [
        ['CHANGE_SCREEN_BELOW_COMMIT_INFO_BLOCK', 'change-view-integration'],
        ['CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK', 'change-metadata-item'],
      ].forEach(([panelName, endpointName]) => {
        test(`deprecated.panel works for ${panelName}`, () => {
          const callback = sandbox.stub();
          plugin.deprecated.panel(panelName, callback);
          assert.isTrue(plugin.hook.calledWith(endpointName));
          emulateAttached();
          assert.isTrue(callback.called);
          const args = callback.args[0][0];
          assert.strictEqual(args.body, fakeEl);
          assert.strictEqual(args.p.CHANGE_INFO, fakeEl.change);
          assert.strictEqual(args.p.REVISION_INFO, fakeEl.revision);
        });
      });
    });

    suite('settingsScreen', () => {
      test('plugin.settingsScreen is deprecated', () => {
        plugin.settingsScreen('rubbish');
        assert.isTrue(console.error.called);
      });

      test('plugin.settings() returns GrSettingsApi', () => {
        assert.isOk(plugin.settings());
        assert.isTrue(plugin.settings() instanceof GrSettingsApi);
      });

      test('plugin.deprecated.settingsScreen() works', () => {
        const hookStub = {onAttached: sandbox.stub()};
        sandbox.stub(plugin, 'hook').returns(hookStub);
        const fakeSettings = {};
        fakeSettings.title = sandbox.stub().returns(fakeSettings);
        fakeSettings.token = sandbox.stub().returns(fakeSettings);
        fakeSettings.module = sandbox.stub().returns(fakeSettings);
        fakeSettings.build = sandbox.stub().returns(hookStub);
        sandbox.stub(plugin, 'settings').returns(fakeSettings);
        const callback = sandbox.stub();

        plugin.deprecated.settingsScreen('path', 'menu', callback);
        assert.isTrue(fakeSettings.title.calledWith('menu'));
        assert.isTrue(fakeSettings.token.calledWith('path'));
        assert.isTrue(fakeSettings.module.calledWith('div'));
        assert.equal(fakeSettings.build.callCount, 1);

        const fakeBody = {};
        const fakeEl = {
          style: {
            display: '',
          },
          querySelector: sandbox.stub().returns(fakeBody),
        };
        // Emulate settings screen attached
        hookStub.onAttached.callArgWith(0, fakeEl);
        assert.isTrue(callback.called);
        const args = callback.args[0][0];
        assert.strictEqual(args.body, fakeBody);
        assert.equal(fakeEl.style.display, 'none');
      });
    });
  });
</script>
