/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; const { WebChannel } = ChromeUtils.importESModule( "resource://gre/modules/WebChannel.sys.mjs" ); const { PermissionTestUtils } = ChromeUtils.importESModule( "resource://testing-common/PermissionTestUtils.sys.mjs" ); const ERROR_ID_ORIGIN_REQUIRED = "WebChannel id and originOrPermission are required."; const VALID_WEB_CHANNEL_ID = "id"; const URL_STRING = "http://example.com"; const VALID_WEB_CHANNEL_ORIGIN = Services.io.newURI(URL_STRING); const TEST_PERMISSION_NAME = "test-webchannel-permissions"; var MockWebChannelBroker = { _channelMap: new Map(), registerChannel(channel) { if (!this._channelMap.has(channel)) { this._channelMap.set(channel); } }, unregisterChannel(channelToRemove) { this._channelMap.delete(channelToRemove); }, }; /** * Web channel tests */ /** * Test channel listening with originOrPermission being an nsIURI. */ add_task(function test_web_channel_listen() { return new Promise((resolve, reject) => { let channel = new WebChannel( VALID_WEB_CHANNEL_ID, VALID_WEB_CHANNEL_ORIGIN, { broker: MockWebChannelBroker, } ); let delivered = 0; Assert.equal(channel.id, VALID_WEB_CHANNEL_ID); Assert.equal( channel._originOrPermission.spec, VALID_WEB_CHANNEL_ORIGIN.spec ); Assert.equal(channel._deliverCallback, null); channel.listen(function (id, message, target) { Assert.equal(id, VALID_WEB_CHANNEL_ID); Assert.ok(message); Assert.ok(message.command); Assert.ok(target.sender); delivered++; // 2 messages should be delivered if (delivered === 2) { channel.stopListening(); Assert.equal(channel._deliverCallback, null); resolve(); } }); // send two messages channel.deliver( { id: VALID_WEB_CHANNEL_ID, message: { command: "one", }, }, { sender: true } ); channel.deliver( { id: VALID_WEB_CHANNEL_ID, message: { command: "two", }, }, { sender: true } ); }); }); /** * Test channel listening with originOrPermission being a permission string. */ add_task(function test_web_channel_listen_permission() { return new Promise((resolve, reject) => { // add a new permission PermissionTestUtils.add( VALID_WEB_CHANNEL_ORIGIN, TEST_PERMISSION_NAME, Services.perms.ALLOW_ACTION ); registerCleanupFunction(() => PermissionTestUtils.remove(VALID_WEB_CHANNEL_ORIGIN, TEST_PERMISSION_NAME) ); let channel = new WebChannel(VALID_WEB_CHANNEL_ID, TEST_PERMISSION_NAME, { broker: MockWebChannelBroker, }); let delivered = 0; Assert.equal(channel.id, VALID_WEB_CHANNEL_ID); Assert.equal(channel._originOrPermission, TEST_PERMISSION_NAME); Assert.equal(channel._deliverCallback, null); channel.listen(function (id, message, target) { Assert.equal(id, VALID_WEB_CHANNEL_ID); Assert.ok(message); Assert.ok(message.command); Assert.ok(target.sender); delivered++; // 2 messages should be delivered if (delivered === 2) { channel.stopListening(); Assert.equal(channel._deliverCallback, null); resolve(); } }); // send two messages channel.deliver( { id: VALID_WEB_CHANNEL_ID, message: { command: "one", }, }, { sender: true } ); channel.deliver( { id: VALID_WEB_CHANNEL_ID, message: { command: "two", }, }, { sender: true } ); }); }); /** * Test constructor */ add_test(function test_web_channel_constructor() { Assert.equal(constructorTester(), ERROR_ID_ORIGIN_REQUIRED); Assert.equal(constructorTester(undefined), ERROR_ID_ORIGIN_REQUIRED); Assert.equal( constructorTester(undefined, VALID_WEB_CHANNEL_ORIGIN), ERROR_ID_ORIGIN_REQUIRED ); Assert.equal( constructorTester(VALID_WEB_CHANNEL_ID, undefined), ERROR_ID_ORIGIN_REQUIRED ); Assert.ok(!constructorTester(VALID_WEB_CHANNEL_ID, VALID_WEB_CHANNEL_ORIGIN)); run_next_test(); }); function constructorTester(id, origin) { try { new WebChannel(id, origin); } catch (e) { return e.message; } return false; }