michael@0: "use strict"; michael@0: michael@0: const Cu = Components.utils; michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: michael@0: Cu.import("resource://gre/modules/OperatorApps.jsm"); michael@0: Cu.import("resource://gre/modules/FileUtils.jsm"); michael@0: Cu.import("resource://gre/modules/NetUtil.jsm"); michael@0: michael@0: // From prio.h michael@0: const PR_RDWR = 0x04; michael@0: const PR_CREATE_FILE = 0x08; michael@0: const PR_TRUNCATE = 0x20; michael@0: michael@0: SimpleTest.waitForExplicitFinish(); michael@0: michael@0: var gApp = null; michael@0: michael@0: var index = -1; michael@0: var singlevariantDir = undefined; michael@0: michael@0: function debug(aMsg) { michael@0: //dump("== Tests debug == " + aMsg + "\n"); michael@0: } michael@0: michael@0: michael@0: var updateData = { michael@0: name : "testOperatorApp1", michael@0: version : 2, michael@0: size : 767, michael@0: package_path: "http://test/tests/dom/apps/tests/file_packaged_app.sjs", michael@0: description: "Updated even faster than Firefox, just to annoy slashdotters", michael@0: developer: { michael@0: name: "Tester Operator App", michael@0: url: "http://mochi.test:8888" michael@0: } michael@0: }; michael@0: michael@0: var manifestData = { michael@0: name : "testOperatorApp1", michael@0: version : 2, michael@0: description: "Updated even faster than Firefox, just to annoy slashdotters", michael@0: launch_path: "index.html", michael@0: developer: { michael@0: name: "Tester Operator App", michael@0: url: "http://mochi.test:8888" michael@0: }, michael@0: default_locale: "en-US" michael@0: }; michael@0: michael@0: var metadataData = { michael@0: id: "testOperatorApp1", michael@0: installOrigin: "http://mochi.test:8888", michael@0: manifestURL: "http://test/tests/dom/apps/tests/file_packaged_app.sjs", michael@0: origin: "http://test" michael@0: }; michael@0: michael@0: function writeFile(aFile, aData, aCb) { michael@0: debug("Saving " + aFile.path); michael@0: // Initialize the file output stream. michael@0: let ostream = FileUtils.openSafeFileOutputStream(aFile); michael@0: michael@0: // Obtain a converter to convert our data to a UTF-8 encoded input stream. michael@0: let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] michael@0: .createInstance(Ci.nsIScriptableUnicodeConverter); michael@0: converter.charset = "UTF-8"; michael@0: michael@0: // Asynchronously copy the data to the file. michael@0: let istream = converter.convertToInputStream(aData); michael@0: NetUtil.asyncCopy(istream, ostream, function(rc) { michael@0: FileUtils.closeSafeFileOutputStream(ostream); michael@0: if (aCb) michael@0: aCb(); michael@0: }); michael@0: } michael@0: michael@0: // File and resources helpers michael@0: function addZipEntry(zipWriter, entry, entryName) { michael@0: var stream = Cc["@mozilla.org/io/string-input-stream;1"] michael@0: .createInstance(Ci.nsIStringInputStream); michael@0: stream.setData(entry, entry.length); michael@0: zipWriter.addEntryStream(entryName, Date.now(), michael@0: Ci.nsIZipWriter.COMPRESSION_BEST, stream, false); michael@0: } michael@0: michael@0: function setupDataDirs(aCb) { michael@0: let dirNum = "tmp_" + Math.floor(Math.random() * 10000000 + 1); michael@0: let tmpDir = FileUtils.getDir("TmpD", [dirNum, "singlevariantapps"], true, michael@0: true); michael@0: let appDir = FileUtils.getDir("TmpD", [dirNum, "singlevariantapps", michael@0: "testOperatorApp1"], true, true); michael@0: michael@0: singlevariantDir = tmpDir.path; michael@0: let singlevariantFile = tmpDir.clone(); michael@0: singlevariantFile.append("singlevariantconf.json"); michael@0: michael@0: michael@0: writeFile(singlevariantFile, JSON.stringify({"214-007":["testOperatorApp1"]}), michael@0: function() { michael@0: let indexhtml = ""; michael@0: let manifest = JSON.stringify(manifestData); michael@0: // Create the application package. michael@0: var zipWriter = Cc["@mozilla.org/zipwriter;1"] michael@0: .createInstance(Ci.nsIZipWriter); michael@0: var zipFile = FileUtils.getFile("TmpD", [ michael@0: dirNum, michael@0: "singlevariantapps", michael@0: "testOperatorApp1", michael@0: "application.zip"]); michael@0: zipWriter.open(zipFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); michael@0: addZipEntry(zipWriter, indexhtml, "index.html"); michael@0: addZipEntry(zipWriter, manifest, "manifest.webapp"); michael@0: zipWriter.close(); michael@0: michael@0: var metadataFile = appDir.clone(); michael@0: metadataFile.append("metadata.json"); michael@0: writeFile(metadataFile, JSON.stringify(metadataData), function() { michael@0: var updateFile = appDir.clone(); michael@0: updateFile.append("update.webapp"); michael@0: writeFile(updateFile, JSON.stringify(updateData), aCb); michael@0: }); michael@0: }); michael@0: } michael@0: michael@0: function next() { michael@0: index += 1; michael@0: if (index >= steps.length) { michael@0: ok(false, "Shouldn't get here!"); michael@0: return; michael@0: } michael@0: try { michael@0: steps[index](); michael@0: } catch(ex) { michael@0: ok(false, "Caught exception", ex); michael@0: } michael@0: } michael@0: michael@0: function go() { michael@0: next(); michael@0: } michael@0: michael@0: function finish() { michael@0: SimpleTest.finish(); michael@0: } michael@0: michael@0: function mozAppsError() { michael@0: ok(false, "mozApps error: " + this.error.name); michael@0: finish(); michael@0: } michael@0: michael@0: function installOperatorApp(aMcc, aMnc) { michael@0: OperatorAppsRegistry.appsDir = singlevariantDir; michael@0: OperatorAppsRegistry._installOperatorApps(aMcc, aMnc); michael@0: } michael@0: michael@0: function checkAppState(aApp, michael@0: aVersion, michael@0: aExpectedApp, michael@0: aCb) { michael@0: debug(JSON.stringify(aApp, null, 2)); michael@0: if (aApp.manifest) { michael@0: debug(JSON.stringify(aApp.manifest, null, 2)); michael@0: } michael@0: michael@0: if (aExpectedApp.name) { michael@0: if (aApp.manifest) { michael@0: is(aApp.manifest.name, aExpectedApp.name, "Check name"); michael@0: } michael@0: is(aApp.updateManifest.name, aExpectedApp.name, "Check name mini-manifest"); michael@0: } michael@0: if (aApp.manifest) { michael@0: is(aApp.manifest.version, aVersion, "Check version"); michael@0: } michael@0: if (typeof aExpectedApp.size !== "undefined" && aApp.manifest) { michael@0: is(aApp.manifest.size, aExpectedApp.size, "Check size"); michael@0: } michael@0: if (aApp.manifest) { michael@0: is(aApp.manifest.launch_path, "index.html", "Check launch path"); michael@0: } michael@0: if (aExpectedApp.manifestURL) { michael@0: is(aApp.manifestURL, aExpectedApp.manifestURL, "Check manifestURL"); michael@0: } michael@0: if (aExpectedApp.installOrigin) { michael@0: is(aApp.installOrigin, aExpectedApp.installOrigin, "Check installOrigin"); michael@0: } michael@0: ok(aApp.removable, "Removable app"); michael@0: if (typeof aExpectedApp.progress !== "undefined") { michael@0: todo(aApp.progress == aExpectedApp.progress, "Check progress"); michael@0: } michael@0: if (aExpectedApp.installState) { michael@0: is(aApp.installState, aExpectedApp.installState, "Check installState"); michael@0: } michael@0: if (typeof aExpectedApp.downloadAvailable !== "undefined") { michael@0: is(aApp.downloadAvailable, aExpectedApp.downloadAvailable, michael@0: "Check download available"); michael@0: } michael@0: if (typeof aExpectedApp.downloading !== "undefined") { michael@0: is(aApp.downloading, aExpectedApp.downloading, "Check downloading"); michael@0: } michael@0: if (typeof aExpectedApp.downloadSize !== "undefined") { michael@0: is(aApp.downloadSize, aExpectedApp.downloadSize, "Check downloadSize"); michael@0: } michael@0: if (typeof aExpectedApp.readyToApplyDownload !== "undefined") { michael@0: is(aApp.readyToApplyDownload, aExpectedApp.readyToApplyDownload, michael@0: "Check readyToApplyDownload"); michael@0: } michael@0: if (aCb && typeof aCb === 'function') { michael@0: aCb(); michael@0: } michael@0: return; michael@0: } michael@0: michael@0: var steps = [ michael@0: function() { michael@0: setupDataDirs(next); michael@0: ok(true, "Data directory set up to " + singlevariantDir); michael@0: }, michael@0: function() { michael@0: ok(true, "autoConfirmAppInstall"); michael@0: SpecialPowers.autoConfirmAppInstall(next); michael@0: }, michael@0: function() { michael@0: ok(true, "== TEST == Install operator app"); michael@0: michael@0: navigator.mozApps.mgmt.oninstall = function(evt) { michael@0: ok(true, "Got oninstall event"); michael@0: gApp = evt.application; michael@0: gApp.ondownloaderror = function() { michael@0: ok(false, "Download error " + gApp.downloadError.name); michael@0: finish(); michael@0: }; michael@0: let downloadsuccessHandler = function() { michael@0: gApp.ondownloadsuccess = null; michael@0: ok(true, "App downloaded"); michael@0: michael@0: var expected = { michael@0: name: manifestData.name, michael@0: manifestURL: metadataData.manifestURL, michael@0: installOrigin: metadataData.installOrigin, michael@0: progress: 0, michael@0: installState: "installed", michael@0: downloadAvailable: false, michael@0: downloading: false, michael@0: downloadSize: 767, michael@0: readyToApplyDownload: false michael@0: }; michael@0: checkAppState(gApp, manifestData.version, expected, next); michael@0: }; michael@0: gApp.ondownloadsuccess = downloadsuccessHandler; michael@0: if (!gApp.downloading && gApp.ondownloadsuccess) { michael@0: ok(true, "Got an earlier event"); michael@0: // Seems we set the handler too late. michael@0: gApp.ondownloadsuccess = null; michael@0: downloadsuccessHandler(); michael@0: } michael@0: }; michael@0: installOperatorApp("214", "007"); michael@0: }, michael@0: function() { michael@0: ok(true, "all done!\n"); michael@0: finish(); michael@0: } michael@0: ]; michael@0: michael@0: go(); michael@0: