diff options
Diffstat (limited to 'addon-sdk/source/test/test-addon-installer.js')
-rw-r--r-- | addon-sdk/source/test/test-addon-installer.js | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/addon-sdk/source/test/test-addon-installer.js b/addon-sdk/source/test/test-addon-installer.js new file mode 100644 index 000000000..bb39cca2d --- /dev/null +++ b/addon-sdk/source/test/test-addon-installer.js @@ -0,0 +1,230 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +const { Cc, Ci, Cu } = require("chrome"); +const { pathFor } = require("sdk/system"); +const AddonInstaller = require("sdk/addon/installer"); +const { on, off } = require("sdk/system/events"); +const { setTimeout } = require("sdk/timers"); +const fs = require("sdk/io/fs"); +const path = require("sdk/fs/path"); +const { OS } = require("resource://gre/modules/osfile.jsm"); +const { toFilename } = require("sdk/url"); + +// Retrieve the path to the OS temporary directory: +const tmpDir = pathFor("TmpD"); + +const profilePath = pathFor("ProfD"); +const corruptXPIPath = path.join(profilePath, "sdk-corrupt.xpi"); +const testFolderURL = module.uri.split('test-addon-installer.js')[0]; +const ADDON_URL = toFilename(testFolderURL + "fixtures/addon-install-unit-test@mozilla.com.xpi"); + +exports["test Install"] = function*(assert) { + var ADDON_PATH = OS.Path.join(OS.Constants.Path.tmpDir, "install-test.xpi"); + + assert.pass("Copying test add-on " + ADDON_URL + " to " + ADDON_PATH); + + yield OS.File.copy(ADDON_URL, ADDON_PATH); + + assert.pass("Copied test add-on to " + ADDON_PATH); + + // Save all events distpatched by bootstrap.js of the installed addon + let events = []; + function eventsObserver({ data }) { + events.push(data); + } + on("addon-install-unit-test", eventsObserver); + + // Install the test addon + yield AddonInstaller.install(ADDON_PATH).then((id) => { + assert.equal(id, "addon-install-unit-test@mozilla.com", "`id` is valid"); + + // Now uninstall it + return AddonInstaller.uninstall(id).then(function () { + // Ensure that bootstrap.js methods of the addon have been called + // successfully and in the right order + let expectedEvents = ["install", "startup", "shutdown", "uninstall"]; + assert.equal(JSON.stringify(events), + JSON.stringify(expectedEvents), + "addon's bootstrap.js functions have been called"); + + off("addon-install-unit-test", eventsObserver); + }); + }, (code) => { + assert.fail("Install failed: "+code); + off("addon-install-unit-test", eventsObserver); + }); + + assert.pass("Add-on was uninstalled."); + + yield OS.File.remove(ADDON_PATH); + + assert.pass("Removed the temp file"); +}; + +exports["test Failing Install With Invalid Path"] = function (assert, done) { + AddonInstaller.install("invalid-path").then( + function onInstalled(id) { + assert.fail("Unexpected success"); + done(); + }, + function onFailure(code) { + assert.equal(code, AddonInstaller.ERROR_FILE_ACCESS, + "Got expected error code"); + done(); + } + ); +}; + +exports["test Failing Install With Invalid File"] = function (assert, done) { + const content = "bad xpi"; + const path = corruptXPIPath; + + fs.writeFile(path, content, (error) => { + assert.equal(fs.readFileSync(path).toString(), + content, + "contet was written"); + + AddonInstaller.install(path).then( + () => { + assert.fail("Unexpected success"); + fs.unlink(path, done); + }, + (code) => { + assert.equal(code, AddonInstaller.ERROR_CORRUPT_FILE, + "Got expected error code"); + fs.unlink(path, done); + } + ); + }); +} + +exports["test Update"] = function*(assert) { + var ADDON_PATH = OS.Path.join(OS.Constants.Path.tmpDir, "update-test.xpi"); + + assert.pass("Copying test add-on " + ADDON_URL + " to " + ADDON_PATH); + + yield OS.File.copy(ADDON_URL, ADDON_PATH); + + assert.pass("Copied test add-on to " + ADDON_PATH); + + // Save all events distpatched by bootstrap.js of the installed addon + let events = []; + let iteration = 1; + let eventsObserver = ({data}) => events.push(data); + on("addon-install-unit-test", eventsObserver); + + yield new Promise(resolve => { + function onInstalled(id) { + let prefix = "[" + iteration + "] "; + assert.equal(id, "addon-install-unit-test@mozilla.com", + prefix + "`id` is valid"); + + // On 2nd and 3rd iteration, we receive uninstall events from the last + // previously installed addon + let expectedEvents = + iteration == 1 + ? ["install", "startup"] + : ["shutdown", "uninstall", "install", "startup"]; + assert.equal(JSON.stringify(events), + JSON.stringify(expectedEvents), + prefix + "addon's bootstrap.js functions have been called"); + + if (iteration++ < 3) { + next(); + } + else { + events = []; + AddonInstaller.uninstall(id).then(function() { + let expectedEvents = ["shutdown", "uninstall"]; + assert.equal(JSON.stringify(events), + JSON.stringify(expectedEvents), + prefix + "addon's bootstrap.js functions have been called"); + + off("addon-install-unit-test", eventsObserver); + resolve(); + }); + } + } + function onFailure(code) { + assert.fail("Install failed: "+code); + off("addon-install-unit-test", eventsObserver); + resolve(); + } + + function next() { + events = []; + AddonInstaller.install(ADDON_PATH).then(onInstalled, onFailure); + } + + next(); + }); + + assert.pass("Add-on was uninstalled."); + + yield OS.File.remove(ADDON_PATH); + + assert.pass("Removed the temp file"); +}; + +exports['test Uninstall failure'] = function (assert, done) { + AddonInstaller.uninstall('invalid-addon-path').then( + () => assert.fail('Addon uninstall should not resolve successfully'), + () => assert.pass('Addon correctly rejected invalid uninstall') + ).then(done, assert.fail); +}; + +exports['test Addon Disable and Enable'] = function*(assert) { + var ADDON_PATH = OS.Path.join(OS.Constants.Path.tmpDir, "disable-enable-test.xpi"); + + assert.pass("Copying test add-on " + ADDON_URL + " to " + ADDON_PATH); + + yield OS.File.copy(ADDON_URL, ADDON_PATH); + + assert.pass("Copied test add-on to " + ADDON_PATH); + + let ensureActive = (addonId) => AddonInstaller.isActive(addonId).then(state => { + assert.equal(state, true, 'Addon should be enabled by default'); + return addonId; + }); + let ensureInactive = (addonId) => AddonInstaller.isActive(addonId).then(state => { + assert.equal(state, false, 'Addon should be disabled after disabling'); + return addonId; + }); + + yield AddonInstaller.install(ADDON_PATH) + .then(ensureActive) + .then(AddonInstaller.enable) // should do nothing, yet not fail + .then(ensureActive) + .then(AddonInstaller.disable) + .then(ensureInactive) + .then(AddonInstaller.disable) // should do nothing, yet not fail + .then(ensureInactive) + .then(AddonInstaller.enable) + .then(ensureActive) + .then(AddonInstaller.uninstall); + + assert.pass("Add-on was uninstalled."); + + yield OS.File.remove(ADDON_PATH); + + assert.pass("Removed the temp file"); +}; + +exports['test Disable failure'] = function (assert, done) { + AddonInstaller.disable('not-an-id').then( + () => assert.fail('Addon disable should not resolve successfully'), + () => assert.pass('Addon correctly rejected invalid disable') + ).then(done, assert.fail); +}; + +exports['test Enable failure'] = function (assert, done) { + AddonInstaller.enable('not-an-id').then( + () => assert.fail('Addon enable should not resolve successfully'), + () => assert.pass('Addon correctly rejected invalid enable') + ).then(done, assert.fail); +}; + +require("sdk/test").run(exports); |