| <!DOCTYPE html> | |
| <!-- | |
| @license | |
| Copyright (C) 2017 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-plugin-host</title> | |
| <script src="/test/common-test-setup.js"></script> | |
| <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 {PRELOADED_PROTOCOL, PLUGIN_LOADING_TIMEOUT_MS} = window._apiUtils; | |
| suite('gr-plugin-loader tests', () => { | |
| let plugin; | |
| let sandbox; | |
| let url; | |
| let sendStub; | |
| setup(() => { | |
| this.clock = sinon.useFakeTimers(); | |
| sandbox = sinon.sandbox.create(); | |
| sendStub = sandbox.stub().returns(Promise.resolve({status: 200})); | |
| stub('gr-rest-api-interface', { | |
| getAccount() { | |
| return Promise.resolve({name: 'Judy Hopps'}); | |
| }, | |
| send(...args) { | |
| return sendStub(...args); | |
| }, | |
| }); | |
| sandbox.stub(document.body, 'appendChild'); | |
| fixture('basic'); | |
| url = window.location.origin; | |
| }); | |
| teardown(() => { | |
| sandbox.restore(); | |
| this.clock.restore(); | |
| Gerrit._testOnly_resetPlugins(); | |
| }); | |
| test('reuse plugin for install calls', () => { | |
| Gerrit.install(p => { plugin = p; }, '0.1', | |
| 'http://test.com/plugins/testplugin/static/test.js'); | |
| let otherPlugin; | |
| Gerrit.install(p => { otherPlugin = p; }, '0.1', | |
| 'http://test.com/plugins/testplugin/static/test.js'); | |
| assert.strictEqual(plugin, otherPlugin); | |
| }); | |
| test('flushes preinstalls if provided', () => { | |
| assert.doesNotThrow(() => { | |
| Gerrit._testOnly_flushPreinstalls(); | |
| }); | |
| window.Gerrit.flushPreinstalls = sandbox.stub(); | |
| Gerrit._testOnly_flushPreinstalls(); | |
| assert.isTrue(window.Gerrit.flushPreinstalls.calledOnce); | |
| delete window.Gerrit.flushPreinstalls; | |
| }); | |
| test('versioning', () => { | |
| const callback = sandbox.spy(); | |
| Gerrit.install(callback, '0.0pre-alpha'); | |
| assert(callback.notCalled); | |
| }); | |
| test('report pluginsLoaded', done => { | |
| stub('gr-reporting', { | |
| pluginsLoaded() { | |
| done(); | |
| }, | |
| }); | |
| Gerrit._loadPlugins([]); | |
| }); | |
| test('arePluginsLoaded', done => { | |
| assert.isFalse(Gerrit._arePluginsLoaded()); | |
| const plugins = [ | |
| 'http://test.com/plugins/foo/static/test.js', | |
| 'http://test.com/plugins/bar/static/test.js', | |
| ]; | |
| Gerrit._loadPlugins(plugins); | |
| assert.isFalse(Gerrit._arePluginsLoaded()); | |
| // Timeout on loading plugins | |
| this.clock.tick(PLUGIN_LOADING_TIMEOUT_MS * 2); | |
| flush(() => { | |
| assert.isTrue(Gerrit._arePluginsLoaded()); | |
| done(); | |
| }); | |
| }); | |
| test('plugins installed successfully', done => { | |
| sandbox.stub(Gerrit._pluginLoader, '_loadJsPlugin', url => { | |
| Gerrit.install(() => void 0, undefined, url); | |
| }); | |
| const pluginsLoadedStub = sandbox.stub(); | |
| stub('gr-reporting', { | |
| pluginsLoaded: (...args) => pluginsLoadedStub(...args), | |
| }); | |
| const plugins = [ | |
| 'http://test.com/plugins/foo/static/test.js', | |
| 'http://test.com/plugins/bar/static/test.js', | |
| ]; | |
| Gerrit._loadPlugins(plugins); | |
| flush(() => { | |
| assert.isTrue(pluginsLoadedStub.calledWithExactly(['foo', 'bar'])); | |
| assert.isTrue(Gerrit._arePluginsLoaded()); | |
| done(); | |
| }); | |
| }); | |
| test('isPluginEnabled and isPluginLoaded', done => { | |
| sandbox.stub(Gerrit._pluginLoader, '_loadJsPlugin', url => { | |
| Gerrit.install(() => void 0, undefined, url); | |
| }); | |
| const pluginsLoadedStub = sandbox.stub(); | |
| stub('gr-reporting', { | |
| pluginsLoaded: (...args) => pluginsLoadedStub(...args), | |
| }); | |
| const plugins = [ | |
| 'http://test.com/plugins/foo/static/test.js', | |
| 'http://test.com/plugins/bar/static/test.js', | |
| 'bar/static/test.js', | |
| ]; | |
| Gerrit._loadPlugins(plugins); | |
| assert.isTrue( | |
| plugins.every(plugin => Gerrit._pluginLoader.isPluginEnabled(plugin)) | |
| ); | |
| flush(() => { | |
| assert.isTrue(Gerrit._arePluginsLoaded()); | |
| assert.isTrue( | |
| plugins.every(plugin => Gerrit._pluginLoader.isPluginLoaded(plugin)) | |
| ); | |
| done(); | |
| }); | |
| }); | |
| test('plugins installed mixed result, 1 fail 1 succeed', done => { | |
| const plugins = [ | |
| 'http://test.com/plugins/foo/static/test.js', | |
| 'http://test.com/plugins/bar/static/test.js', | |
| ]; | |
| const alertStub = sandbox.stub(); | |
| document.addEventListener('show-alert', alertStub); | |
| sandbox.stub(Gerrit._pluginLoader, '_loadJsPlugin', url => { | |
| Gerrit.install(() => { | |
| if (url === plugins[0]) { | |
| throw new Error('failed'); | |
| } | |
| }, undefined, url); | |
| }); | |
| const pluginsLoadedStub = sandbox.stub(); | |
| stub('gr-reporting', { | |
| pluginsLoaded: (...args) => pluginsLoadedStub(...args), | |
| }); | |
| Gerrit._loadPlugins(plugins); | |
| flush(() => { | |
| assert.isTrue(pluginsLoadedStub.calledWithExactly(['bar'])); | |
| assert.isTrue(Gerrit._arePluginsLoaded()); | |
| assert.isTrue(alertStub.calledOnce); | |
| done(); | |
| }); | |
| }); | |
| test('isPluginEnabled and isPluginLoaded for mixed results', done => { | |
| const plugins = [ | |
| 'http://test.com/plugins/foo/static/test.js', | |
| 'http://test.com/plugins/bar/static/test.js', | |
| ]; | |
| const alertStub = sandbox.stub(); | |
| document.addEventListener('show-alert', alertStub); | |
| sandbox.stub(Gerrit._pluginLoader, '_loadJsPlugin', url => { | |
| Gerrit.install(() => { | |
| if (url === plugins[0]) { | |
| throw new Error('failed'); | |
| } | |
| }, undefined, url); | |
| }); | |
| const pluginsLoadedStub = sandbox.stub(); | |
| stub('gr-reporting', { | |
| pluginsLoaded: (...args) => pluginsLoadedStub(...args), | |
| }); | |
| Gerrit._loadPlugins(plugins); | |
| assert.isTrue( | |
| plugins.every(plugin => Gerrit._pluginLoader.isPluginEnabled(plugin)) | |
| ); | |
| flush(() => { | |
| assert.isTrue(pluginsLoadedStub.calledWithExactly(['bar'])); | |
| assert.isTrue(Gerrit._arePluginsLoaded()); | |
| assert.isTrue(alertStub.calledOnce); | |
| assert.isTrue(Gerrit._pluginLoader.isPluginLoaded(plugins[1])); | |
| assert.isFalse(Gerrit._pluginLoader.isPluginLoaded(plugins[0])); | |
| done(); | |
| }); | |
| }); | |
| test('plugins installed all failed', done => { | |
| const plugins = [ | |
| 'http://test.com/plugins/foo/static/test.js', | |
| 'http://test.com/plugins/bar/static/test.js', | |
| ]; | |
| const alertStub = sandbox.stub(); | |
| document.addEventListener('show-alert', alertStub); | |
| sandbox.stub(Gerrit._pluginLoader, '_loadJsPlugin', url => { | |
| Gerrit.install(() => { | |
| throw new Error('failed'); | |
| }, undefined, url); | |
| }); | |
| const pluginsLoadedStub = sandbox.stub(); | |
| stub('gr-reporting', { | |
| pluginsLoaded: (...args) => pluginsLoadedStub(...args), | |
| }); | |
| Gerrit._loadPlugins(plugins); | |
| flush(() => { | |
| assert.isTrue(pluginsLoadedStub.calledWithExactly([])); | |
| assert.isTrue(Gerrit._arePluginsLoaded()); | |
| assert.isTrue(alertStub.calledTwice); | |
| done(); | |
| }); | |
| }); | |
| test('plugins installed failed becasue of wrong version', done => { | |
| const plugins = [ | |
| 'http://test.com/plugins/foo/static/test.js', | |
| 'http://test.com/plugins/bar/static/test.js', | |
| ]; | |
| const alertStub = sandbox.stub(); | |
| document.addEventListener('show-alert', alertStub); | |
| sandbox.stub(Gerrit._pluginLoader, '_loadJsPlugin', url => { | |
| Gerrit.install(() => { | |
| }, url === plugins[0] ? '' : 'alpha', url); | |
| }); | |
| const pluginsLoadedStub = sandbox.stub(); | |
| stub('gr-reporting', { | |
| pluginsLoaded: (...args) => pluginsLoadedStub(...args), | |
| }); | |
| Gerrit._loadPlugins(plugins); | |
| flush(() => { | |
| assert.isTrue(pluginsLoadedStub.calledWithExactly(['foo'])); | |
| assert.isTrue(Gerrit._arePluginsLoaded()); | |
| assert.isTrue(alertStub.calledOnce); | |
| done(); | |
| }); | |
| }); | |
| test('multiple assets for same plugin installed successfully', done => { | |
| sandbox.stub(Gerrit._pluginLoader, '_loadJsPlugin', url => { | |
| Gerrit.install(() => void 0, undefined, url); | |
| }); | |
| const pluginsLoadedStub = sandbox.stub(); | |
| stub('gr-reporting', { | |
| pluginsLoaded: (...args) => pluginsLoadedStub(...args), | |
| }); | |
| const plugins = [ | |
| 'http://test.com/plugins/foo/static/test.js', | |
| 'http://test.com/plugins/foo/static/test2.js', | |
| 'http://test.com/plugins/bar/static/test.js', | |
| ]; | |
| Gerrit._loadPlugins(plugins); | |
| flush(() => { | |
| assert.isTrue(pluginsLoadedStub.calledWithExactly(['foo', 'bar'])); | |
| assert.isTrue(Gerrit._arePluginsLoaded()); | |
| done(); | |
| }); | |
| }); | |
| suite('plugin path and url', () => { | |
| let importHtmlPluginStub; | |
| let loadJsPluginStub; | |
| setup(() => { | |
| importHtmlPluginStub = sandbox.stub(); | |
| sandbox.stub(Gerrit._pluginLoader, '_importHtmlPlugin', url => { | |
| importHtmlPluginStub(url); | |
| }); | |
| loadJsPluginStub = sandbox.stub(); | |
| sandbox.stub(Gerrit._pluginLoader, '_loadJsPlugin', url => { | |
| loadJsPluginStub(url); | |
| }); | |
| }); | |
| test('invalid plugin path', () => { | |
| const failToLoadStub = sandbox.stub(); | |
| sandbox.stub(Gerrit._pluginLoader, '_failToLoad', (...args) => { | |
| failToLoadStub(...args); | |
| }); | |
| Gerrit._loadPlugins([ | |
| 'foo/bar', | |
| ]); | |
| assert.isTrue(failToLoadStub.calledOnce); | |
| assert.isTrue(failToLoadStub.calledWithExactly( | |
| `Unrecognized plugin url ${url}/foo/bar`, | |
| `${url}/foo/bar` | |
| )); | |
| }); | |
| test('relative path for plugins', () => { | |
| Gerrit._loadPlugins([ | |
| 'foo/bar.js', | |
| 'foo/bar.html', | |
| ]); | |
| assert.isTrue(importHtmlPluginStub.calledOnce); | |
| assert.isTrue( | |
| importHtmlPluginStub.calledWithExactly(`${url}/foo/bar.html`) | |
| ); | |
| assert.isTrue(loadJsPluginStub.calledOnce); | |
| assert.isTrue( | |
| loadJsPluginStub.calledWithExactly(`${url}/foo/bar.js`) | |
| ); | |
| }); | |
| test('relative path should honor getBaseUrl', () => { | |
| const testUrl = '/test'; | |
| sandbox.stub(Gerrit.BaseUrlBehavior, 'getBaseUrl', () => { | |
| return testUrl; | |
| }); | |
| Gerrit._loadPlugins([ | |
| 'foo/bar.js', | |
| 'foo/bar.html', | |
| ]); | |
| assert.isTrue(importHtmlPluginStub.calledOnce); | |
| assert.isTrue(loadJsPluginStub.calledOnce); | |
| assert.isTrue( | |
| importHtmlPluginStub.calledWithExactly( | |
| `${url}${testUrl}/foo/bar.html` | |
| ) | |
| ); | |
| assert.isTrue( | |
| loadJsPluginStub.calledWithExactly(`${url}${testUrl}/foo/bar.js`) | |
| ); | |
| }); | |
| test('absolute path for plugins', () => { | |
| Gerrit._loadPlugins([ | |
| 'http://e.com/foo/bar.js', | |
| 'http://e.com/foo/bar.html', | |
| ]); | |
| assert.isTrue(importHtmlPluginStub.calledOnce); | |
| assert.isTrue( | |
| importHtmlPluginStub.calledWithExactly(`http://e.com/foo/bar.html`) | |
| ); | |
| assert.isTrue(loadJsPluginStub.calledOnce); | |
| assert.isTrue( | |
| loadJsPluginStub.calledWithExactly(`http://e.com/foo/bar.js`) | |
| ); | |
| }); | |
| }); | |
| test('adds js plugins will call the body', () => { | |
| Gerrit._loadPlugins([ | |
| 'http://e.com/foo/bar.js', | |
| 'http://e.com/bar/foo.js', | |
| ]); | |
| assert.isTrue(document.body.appendChild.calledTwice); | |
| }); | |
| test('can call awaitPluginsLoaded multiple times', done => { | |
| const plugins = [ | |
| 'http://e.com/foo/bar.js', | |
| 'http://e.com/bar/foo.js', | |
| ]; | |
| let installed = false; | |
| function pluginCallback(url) { | |
| if (url === plugins[1]) { | |
| installed = true; | |
| } | |
| } | |
| sandbox.stub(Gerrit._pluginLoader, '_loadJsPlugin', url => { | |
| Gerrit.install(() => pluginCallback(url), undefined, url); | |
| }); | |
| Gerrit._loadPlugins(plugins); | |
| Gerrit.awaitPluginsLoaded().then(() => { | |
| assert.isTrue(installed); | |
| Gerrit.awaitPluginsLoaded().then(() => { | |
| done(); | |
| }); | |
| }); | |
| }); | |
| suite('preloaded plugins', () => { | |
| test('skips preloaded plugins when load plugins', () => { | |
| const importHtmlPluginStub = sandbox.stub(); | |
| sandbox.stub(Gerrit._pluginLoader, '_importHtmlPlugin', url => { | |
| importHtmlPluginStub(url); | |
| }); | |
| const loadJsPluginStub = sandbox.stub(); | |
| sandbox.stub(Gerrit._pluginLoader, '_loadJsPlugin', url => { | |
| loadJsPluginStub(url); | |
| }); | |
| Gerrit._preloadedPlugins = { | |
| foo: () => void 0, | |
| bar: () => void 0, | |
| }; | |
| Gerrit._loadPlugins([ | |
| 'http://e.com/plugins/foo.js', | |
| 'plugins/bar.html', | |
| 'http://e.com/plugins/test/foo.js', | |
| ]); | |
| assert.isTrue(importHtmlPluginStub.notCalled); | |
| assert.isTrue(loadJsPluginStub.calledOnce); | |
| }); | |
| test('isPluginPreloaded', () => { | |
| Gerrit._preloadedPlugins = {baz: ()=>{}}; | |
| assert.isFalse(Gerrit._pluginLoader.isPluginPreloaded('plugins/foo/bar')); | |
| assert.isFalse(Gerrit._pluginLoader.isPluginPreloaded('http://a.com/42')); | |
| assert.isTrue( | |
| Gerrit._pluginLoader.isPluginPreloaded(PRELOADED_PROTOCOL + 'baz') | |
| ); | |
| Gerrit._preloadedPlugins = null; | |
| }); | |
| test('preloaded plugins are installed', () => { | |
| const installStub = sandbox.stub(); | |
| Gerrit._preloadedPlugins = {foo: installStub}; | |
| Gerrit._pluginLoader.installPreloadedPlugins(); | |
| assert.isTrue(installStub.called); | |
| const pluginApi = installStub.lastCall.args[0]; | |
| assert.strictEqual(pluginApi.getPluginName(), 'foo'); | |
| }); | |
| test('installing preloaded plugin', () => { | |
| let plugin; | |
| window.ASSETS_PATH = 'http://blips.com/chitz'; | |
| Gerrit.install(p => { plugin = p; }, '0.1', 'preloaded:foo'); | |
| assert.strictEqual(plugin.getPluginName(), 'foo'); | |
| assert.strictEqual(plugin.url('/some/thing.html'), | |
| 'http://blips.com/chitz/plugins/foo/some/thing.html'); | |
| delete window.ASSETS_PATH; | |
| }); | |
| }); | |
| }); | |
| </script> |