diff --git a/toolkit/components/extensions/moz.build b/toolkit/components/extensions/moz.build index 614b05507adf..76afd553ce6c 100644 --- a/toolkit/components/extensions/moz.build +++ b/toolkit/components/extensions/moz.build @@ -15,3 +15,5 @@ EXTRA_JS_MODULES += [ JAR_MANIFESTS += ['jar.mn'] MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini'] + +XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini'] diff --git a/toolkit/components/extensions/test/xpcshell/head.js b/toolkit/components/extensions/test/xpcshell/head.js new file mode 100644 index 000000000000..71823e9e8284 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/head.js @@ -0,0 +1,10 @@ +"use strict"; + +const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", + "resource://gre/modules/NetUtil.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Services", + "resource://gre/modules/Services.jsm"); diff --git a/toolkit/components/extensions/test/xpcshell/test_locale_converter.js b/toolkit/components/extensions/test/xpcshell/test_locale_converter.js new file mode 100644 index 000000000000..4b3f6c4e156a --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_locale_converter.js @@ -0,0 +1,118 @@ +"use strict"; + +const convService = Cc["@mozilla.org/streamConverters;1"] + .getService(Ci.nsIStreamConverterService); + +const UUID = "72b61ee3-aceb-476c-be1b-0822b036c9f1"; +const ADDON_ID = "test@web.extension"; +const URI = NetUtil.newURI(`moz-extension://${UUID}/file.css`); + +const FROM_TYPE = "application/vnd.mozilla.webext.unlocalized"; +const TO_TYPE = "text/css"; + + +function StringStream(string) { + let stream = Cc["@mozilla.org/io/string-input-stream;1"] + .createInstance(Ci.nsIStringInputStream); + + stream.data = string; + return stream; +} + + +// Initialize the policy service with a stub localizer for our +// add-on ID. +add_task(function* init() { + const aps = Cc["@mozilla.org/addons/policy-service;1"] + .getService(Ci.nsIAddonPolicyService).wrappedJSObject; + + let oldCallback = aps.setExtensionURIToAddonIdCallback(uri => { + if (uri.host == UUID) { + return ADDON_ID; + } + }); + + aps.setAddonLocalizeCallback(ADDON_ID, string => { + return string.replace(/__MSG_(.*?)__/g, ""); + }); + + do_register_cleanup(() => { + aps.setExtensionURIToAddonIdCallback(oldCallback); + aps.setAddonLocalizeCallback(ADDON_ID, null); + }); +}); + + +// Test that the synchronous converter works as expected with a +// simple string. +add_task(function* testSynchronousConvert() { + let stream = StringStream("Foo __MSG_xxx__ bar __MSG_yyy__ baz"); + + let resultStream = convService.convert(stream, FROM_TYPE, TO_TYPE, URI); + + let result = NetUtil.readInputStreamToString(resultStream, resultStream.available()); + + equal(result, "Foo bar baz"); +}); + + +// Test that the asynchronous converter works as expected with input +// split into multiple chunks, and a boundary in the middle of a +// replacement token. +add_task(function* testAsyncConvert() { + let listener; + let awaitResult = new Promise((resolve, reject) => { + listener = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener]), + + onDataAvailable(request, context, inputStream, offset, count) { + this.resultParts.push(NetUtil.readInputStreamToString(inputStream, count)); + }, + + onStartRequest() { + ok(!("resultParts" in this)); + this.resultParts = []; + }, + + onStopRequest(request, context, statusCode) { + if (!Components.isSuccessCode(statusCode)) { + reject(new Error(statusCode)); + } + + resolve(this.resultParts.join("\n")); + }, + }; + }); + + let parts = ["Foo __MSG_x", "xx__ bar __MSG_yyy__ baz"]; + + let converter = convService.asyncConvertData(FROM_TYPE, TO_TYPE, listener, URI); + converter.onStartRequest(null, null); + + for (let part of parts) { + converter.onDataAvailable(null, null, StringStream(part), 0, part.length); + } + + converter.onStopRequest(null, null, Cr.NS_OK); + + + let result = yield awaitResult; + equal(result, "Foo bar baz"); +}); + + +// Test that attempting to initialize a converter with the URI of a +// nonexistent WebExtension fails. +add_task(function* testInvalidUUID() { + let uri = NetUtil.newURI("moz-extension://eb4f3be8-41c9-4970-aa6d-b84d1ecc02b2/file.css"); + + Assert.throws(() => { + convService.convert(stream, FROM_TYPE, TO_TYPE, uri); + }); + + Assert.throws(() => { + let listener = { QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener]) }; + + convService.asyncConvertData(FROM_TYPE, TO_TYPE, listener, uri); + }); +}); diff --git a/toolkit/components/extensions/test/xpcshell/xpcshell.ini b/toolkit/components/extensions/test/xpcshell/xpcshell.ini new file mode 100644 index 000000000000..ea2f7d8a63d7 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/xpcshell.ini @@ -0,0 +1,5 @@ +[DEFAULT] +head = head.js +tail = + +[test_locale_converter.js]