From fe554b909cf127200f01edade4a238a858eea187 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Thu, 11 Jul 2013 14:43:53 -0400 Subject: [PATCH] Bug 889356 - Add test for app `redirects` manifest feature. r=fabrice --- .../apps/tests/unit/data/app-redirect.zip | Bin 0 -> 1077 bytes toolkit/devtools/apps/tests/unit/head_apps.js | 128 ++++++++++++++++++ toolkit/devtools/apps/tests/unit/tail_apps.js | 6 + .../apps/tests/unit/test_appInstall.js | 71 ++++++++++ .../apps/tests/unit/test_webappsActor.js | 116 ++-------------- toolkit/devtools/apps/tests/unit/xpcshell.ini | 5 +- 6 files changed, 223 insertions(+), 103 deletions(-) create mode 100644 toolkit/devtools/apps/tests/unit/data/app-redirect.zip create mode 100644 toolkit/devtools/apps/tests/unit/head_apps.js create mode 100644 toolkit/devtools/apps/tests/unit/tail_apps.js create mode 100644 toolkit/devtools/apps/tests/unit/test_appInstall.js diff --git a/toolkit/devtools/apps/tests/unit/data/app-redirect.zip b/toolkit/devtools/apps/tests/unit/data/app-redirect.zip new file mode 100644 index 0000000000000000000000000000000000000000..ddfcab193c560f6bd84c602c375bb1395f5e9cd4 GIT binary patch literal 1077 zcmWIWW@Zs#U|`^2&|!V$^nI^uj|-3&3dCGMoSB!BTA`OwlAE*nq{hj!8y|1-JmtTV zCFtl$*O{!UT&h!9S8nrCT`8*iE3z}SQy@^a_0gh~=%r`&Ou53fcTJM2wRCL;R@d22FMWFX$*1sxQ@;zOUYNIOdc~oyIg>Acj+0mNS=|+XzJZu%cSYC z>hKMNT~;TWuP*q!vh(=wj|NNTrWWUh%WQFpFj>%1GqdrW!S9JJG1&n!ob4)yxHN-9 zW-i(;#&|EZfqTP_#^t+D>Pny8_UOxI_JE!JmBO5>4Fgte{C?Cu$?@3s4Vgv7e<$!L zWNz>Oe8)nwr)c7_^q8L?FX@JEpTg>$sI+OKJJ^``q`>*c>We27FOa(h@Fwz|zxsbX^74WdYueock0e zam@LWc7|a~^a9qdMuSgZrf>Q5lD$^_XqsiS2(3RvRJ3_+{wz6d++1* z(|P6G?0_YjhPzI`j9GF>@9d=-cnhB4xkS~806EU)RfGk)Z~)X6mW8P zEGSS&%gjj)@MdHZVZfb1fI1l%85BSi5FoM(NS_=tL?32imjJ5Iz_HLW?wnX6!ykXnqCMj1~?7-mGjO1uQ@aw1Pn%m=hTo05sQ# A;{X5v literal 0 HcmV?d00001 diff --git a/toolkit/devtools/apps/tests/unit/head_apps.js b/toolkit/devtools/apps/tests/unit/head_apps.js new file mode 100644 index 00000000000..7e41f79bc8b --- /dev/null +++ b/toolkit/devtools/apps/tests/unit/head_apps.js @@ -0,0 +1,128 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; +const Cr = Components.results; +const CC = Components.Constructor; + +Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); +Cu.import("resource://gre/modules/devtools/dbg-client.jsm"); + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/FileUtils.jsm"); + +let gClient, gActor; + +function connect(onDone) { + // Initialize a loopback remote protocol connection + DebuggerServer.init(function () { return true; }); + // We need to register browser actors to have `listTabs` working + // and also have a root actor + DebuggerServer.addBrowserActors(); + + // Setup client and actor used in all tests + gClient = new DebuggerClient(DebuggerServer.connectPipe()); + gClient.connect(function onConnect() { + gClient.listTabs(function onListTabs(aResponse) { + gActor = aResponse.webappsActor; + onDone(); + }); + }); +} + +function webappActorRequest(request, onResponse) { + if (!gActor) { + connect(webappActorRequest.bind(null, request, onResponse)); + return; + } + + request.to = gActor; + gClient.request(request, onResponse); +} + +// Install a test packaged webapp from data folder +function installTestApp(zipName, appId, onDone) { + // Copy our package to tmp folder, where the actor retrieves it + let zip = do_get_file("data/" + zipName); + let appDir = FileUtils.getDir("TmpD", ["b2g", appId], true, true); + zip.copyTo(appDir, "application.zip"); + + let request = {type: "install", appId: appId}; + webappActorRequest(request, function (aResponse) { + do_check_eq(aResponse.appId, appId); + }); + + // The install request is asynchronous and send back an event to tell + // if the installation succeed or failed + gClient.addListener("webappsEvent", function (aState, aType, aPacket) { + do_check_eq(aType.appId, appId); + if ("error" in aType) { + do_throw("Error: " + aType.error); + } + if ("message" in aType) { + do_throw("Error message: " + aType.message); + } + do_check_false("error" in aType); + + onDone(); + }); +}; + +function setup() { + // We have to setup a profile, otherwise indexed db used by webapps + // will throw random exception when trying to get profile folder + do_get_profile(); + + // The webapps dir isn't registered on b2g xpcshell tests, + // we have to manually set it to the directory service. + do_get_webappsdir(); + + // We also need a valid nsIXulAppInfo service as Webapps.jsm is querying it + Components.utils.import("resource://testing-common/AppInfo.jsm"); + updateAppInfo(); + + // We have to toggle this flag in order to have apps being listed in getAll + // as only launchable apps are returned + Components.utils.import('resource://gre/modules/Webapps.jsm'); + DOMApplicationRegistry.allAppsLaunchable = true; +} + +function do_get_webappsdir() { + var webappsDir = Services.dirsvc.get("ProfD", Ci.nsILocalFile); + webappsDir.append("test_webapps"); + if (!webappsDir.exists()) + webappsDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); + + var coreAppsDir = Services.dirsvc.get("ProfD", Ci.nsILocalFile); + coreAppsDir.append("test_coreapps"); + if (!coreAppsDir.exists()) + coreAppsDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); + + // Register our own provider for the profile directory. + // It will return our special docshell profile directory. + var provider = { + getFile: function(prop, persistent) { + persistent.value = true; + if (prop == "webappsDir") { + return webappsDir.clone(); + } + else if (prop == "coreAppsDir") { + return coreAppsDir.clone(); + } + throw Cr.NS_ERROR_FAILURE; + }, + QueryInterface: function(iid) { + if (iid.equals(Ci.nsIDirectoryServiceProvider) || + iid.equals(Ci.nsISupports)) { + return this; + } + throw Cr.NS_ERROR_NO_INTERFACE; + } + }; + Services.dirsvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider); +} + + diff --git a/toolkit/devtools/apps/tests/unit/tail_apps.js b/toolkit/devtools/apps/tests/unit/tail_apps.js new file mode 100644 index 00000000000..0a5fb4b50d9 --- /dev/null +++ b/toolkit/devtools/apps/tests/unit/tail_apps.js @@ -0,0 +1,6 @@ +if (gClient) { + // Close the test remote connection before leaving this test + gClient.close(function () { + run_next_test(); + }); +} diff --git a/toolkit/devtools/apps/tests/unit/test_appInstall.js b/toolkit/devtools/apps/tests/unit/test_appInstall.js new file mode 100644 index 00000000000..196454dd173 --- /dev/null +++ b/toolkit/devtools/apps/tests/unit/test_appInstall.js @@ -0,0 +1,71 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +Cu.import("resource://testing-common/httpd.js"); + +// We need to lazily instanciate apps service, +// as we have to wait for head setup before being +// able to instanciate it without exception +XPCOMUtils.defineLazyGetter(this, "appsService", function() { + return Cc["@mozilla.org/AppsService;1"] + .getService(Ci.nsIAppsService); +}); + +const SERVER_PORT = 4444; +const HTTP_BASE = "http://localhost:" + SERVER_PORT + "/"; + +const APP_ID = "actor-test"; +const APP_BASE = "app://" + APP_ID + "/"; + +const APP_MANIFEST = APP_BASE + "manifest.webapp"; +// The remote url being redirect to... +const REDIRECTED_URL = HTTP_BASE + "redirection-source.html"; +// ...redirected to this another remote url. +const REMOTE_REDIRECTION_URL = HTTP_BASE + "redirection-target.html"; +// The app local file URL that overide REMOTE_REDIRECTION_URL +const LOCAL_REDIRECTION_URL = APP_BASE + "redirected.html"; + +add_test(function testInstallApp() { + installTestApp("app-redirect.zip", APP_ID, run_next_test); +}); + +add_test(function testLaunchApp() { + let server = new HttpServer(); + + // First register the URL that redirect + // from /redirection-source.html + // to /redirection-target.html + server.registerPathHandler("/redirection-source.html", function handle(request, response) { + response.setStatusLine(request.httpVersion, 301, "Moved Permanently"); + response.setHeader("Location", REMOTE_REDIRECTION_URL, false); + + // We have to wait for one even loop cycle before checking the new document location + do_timeout(0, function () { + do_check_eq(d.document.documentURIObject.spec, LOCAL_REDIRECTION_URL); + server.stop(run_next_test); + }); + }); + server.registerPathHandler("/redirection-target.html", function handle(request, response) { + do_throw("We shouldn't receive any request to the remote redirection"); + }); + server.start(SERVER_PORT) + + // Load the remote URL in a docshell configured as an app + let d = Cc["@mozilla.org/docshell;1"].createInstance(Ci.nsIDocShell); + d.QueryInterface(Ci.nsIWebNavigation); + d.QueryInterface(Ci.nsIWebProgress); + + let localAppId = appsService.getAppLocalIdByManifestURL(APP_MANIFEST); + d.setIsApp(localAppId); + do_check_true(d.isApp); + do_check_eq(d.appId, localAppId); + + d.loadURI(REDIRECTED_URL, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null); +}); + +function run_test() { + setup(); + + run_next_test(); +} + diff --git a/toolkit/devtools/apps/tests/unit/test_webappsActor.js b/toolkit/devtools/apps/tests/unit/test_webappsActor.js index 126d8a100b2..829f764682c 100644 --- a/toolkit/devtools/apps/tests/unit/test_webappsActor.js +++ b/toolkit/devtools/apps/tests/unit/test_webappsActor.js @@ -1,48 +1,19 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ -Components.utils.import("resource://gre/modules/devtools/dbg-server.jsm"); -Components.utils.import("resource://gre/modules/devtools/dbg-client.jsm"); - -Components.utils.import("resource://gre/modules/FileUtils.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); - -const Ci = Components.interfaces; -const Cc = Components.classes; -const Cu = Components.utils; -const Cr = Components.results; - -let gClient, gActor; let gAppId = "actor-test"; -add_test(function testSetup() { - // Initialize a loopback remote protocol connection - DebuggerServer.init(function () { return true; }); - // We need to register browser actors to have `listTabs` working - // and also have a root actor - DebuggerServer.addBrowserActors(); - - // Setup client and actor used in all tests - gClient = new DebuggerClient(DebuggerServer.connectPipe()); - gClient.connect(function onConnect() { - gClient.listTabs(function onListTabs(aResponse) { - gActor = aResponse.webappsActor; - run_next_test(); - }); - }); -}); - add_test(function testLaunchInexistantApp() { - let request = {to: gActor, type: "launch", manifestURL: "http://foo.com"}; - gClient.request(request, function (aResponse) { + let request = {type: "launch", manifestURL: "http://foo.com"}; + webappActorRequest(request, function (aResponse) { do_check_eq(aResponse.error, "NO_SUCH_APP"); run_next_test(); }); }); add_test(function testCloseInexistantApp() { - let request = {to: gActor, type: "close", manifestURL: "http://foo.com"}; - gClient.request(request, function (aResponse) { + let request = {type: "close", manifestURL: "http://foo.com"}; + webappActorRequest(request, function (aResponse) { do_check_eq(aResponse.error, "missingParameter"); do_check_eq(aResponse.message, "No application for http://foo.com"); run_next_test(); @@ -56,8 +27,8 @@ add_test(function testInstallPackaged() { let appDir = FileUtils.getDir("TmpD", ["b2g", gAppId], true, true); zip.copyTo(appDir, "application.zip"); - let request = {to: gActor, type: "install", appId: gAppId}; - gClient.request(request, function (aResponse) { + let request = {type: "install", appId: gAppId}; + webappActorRequest(request, function (aResponse) { do_check_eq(aResponse.appId, gAppId); }); @@ -80,8 +51,8 @@ add_test(function testInstallPackaged() { // Now check that the app appear in getAll add_test(function testGetAll() { - let request = {to: gActor, type: "getAll"}; - gClient.request(request, function (aResponse) { + let request = {type: "getAll"}; + webappActorRequest(request, function (aResponse) { do_check_true("apps" in aResponse); let apps = aResponse.apps; do_check_true(apps.length > 0); @@ -106,7 +77,7 @@ add_test(function testLaunchApp() { let manifestURL = "app://" + gAppId + "/manifest.webapp"; let startPoint = "/index.html"; let request = { - to: gActor, type: "launch", + type: "launch", manifestURL: manifestURL, startPoint: startPoint }; @@ -118,7 +89,7 @@ add_test(function testLaunchApp() { run_next_test(); }, "webapps-launch", false); - gClient.request(request, function (aResponse) { + webappActorRequest(request, function (aResponse) { do_check_false("error" in aResponse); }); }); @@ -126,7 +97,7 @@ add_test(function testLaunchApp() { add_test(function testCloseApp() { let manifestURL = "app://" + gAppId + "/manifest.webapp"; let request = { - to: gActor, type: "close", + type: "close", manifestURL: manifestURL }; Services.obs.addObserver(function observer(subject, topic, data) { @@ -136,7 +107,7 @@ add_test(function testCloseApp() { run_next_test(); }, "webapps-close", false); - gClient.request(request, function (aResponse) { + webappActorRequest(request, function (aResponse) { do_check_false("error" in aResponse); }); }); @@ -145,7 +116,7 @@ add_test(function testUninstall() { let origin = "app://" + gAppId; let manifestURL = origin + "/manifest.webapp"; let request = { - to: gActor, type: "uninstall", + type: "uninstall", manifestURL: manifestURL }; @@ -168,72 +139,15 @@ add_test(function testUninstall() { run_next_test(); }, "webapps-sync-uninstall", false); - gClient.request(request, function (aResponse) { + webappActorRequest(request, function (aResponse) { do_check_false("error" in aResponse); }); }); -// Close the test remote connection before leaving this test -add_test(function testTearDown() { - gClient.close(function () { - run_next_test(); - }); -}); function run_test() { - // We have to setup a profile, otherwise indexed db used by webapps - // will throw random exception when trying to get profile folder - do_get_profile(); - - // The webapps dir isn't registered on b2g xpcshell tests, - // we have to manually set it to the directory service. - do_get_webappsdir(); - - // We also need a valid nsIXulAppInfo service as Webapps.jsm is querying it - Components.utils.import("resource://testing-common/AppInfo.jsm"); - updateAppInfo(); - - // We have to toggle this flag in order to have apps being listed in getAll - // as only launchable apps are returned - Components.utils.import('resource://gre/modules/Webapps.jsm'); - DOMApplicationRegistry.allAppsLaunchable = true; + setup(); run_next_test(); } -function do_get_webappsdir() { - var webappsDir = Services.dirsvc.get("ProfD", Ci.nsILocalFile); - webappsDir.append("test_webapps"); - if (!webappsDir.exists()) - webappsDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); - - var coreAppsDir = Services.dirsvc.get("ProfD", Ci.nsILocalFile); - coreAppsDir.append("test_coreapps"); - if (!coreAppsDir.exists()) - coreAppsDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755); - - // Register our own provider for the profile directory. - // It will return our special docshell profile directory. - var provider = { - getFile: function(prop, persistent) { - persistent.value = true; - if (prop == "webappsDir") { - return webappsDir.clone(); - } - else if (prop == "coreAppsDir") { - return coreAppsDir.clone(); - } - throw Cr.NS_ERROR_FAILURE; - }, - QueryInterface: function(iid) { - if (iid.equals(Ci.nsIDirectoryServiceProvider) || - iid.equals(Ci.nsISupports)) { - return this; - } - throw Cr.NS_ERROR_NO_INTERFACE; - } - }; - Services.dirsvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider); -} - - diff --git a/toolkit/devtools/apps/tests/unit/xpcshell.ini b/toolkit/devtools/apps/tests/unit/xpcshell.ini index 06e25f96304..37f6872cb94 100644 --- a/toolkit/devtools/apps/tests/unit/xpcshell.ini +++ b/toolkit/devtools/apps/tests/unit/xpcshell.ini @@ -1,5 +1,6 @@ [DEFAULT] -head = -tail = +head = head_apps.js +tail = tail_apps.js [test_webappsActor.js] +[test_appInstall.js]