Bug 1011738 - Theme support for b2g/gaia, Part 5 : tests r=myk
authorFabrice Desré <fabrice@mozilla.com>
Thu, 28 Aug 2014 17:20:27 -0700
changeset 224053 0ec69047db59ec776c21c7b117706f55a8bc266f
parent 224052 c87e98b19ffae6674318eb4a092e387a6fdf8347
child 224054 c108c1bcce7984aedf975dbf7d478ed8e103ead0
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmyk
bugs1011738
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1011738 - Theme support for b2g/gaia, Part 5 : tests r=myk
dom/apps/tests/file_app.sjs
dom/apps/tests/file_hosted_app.template.webapp
dom/apps/tests/file_packaged_app.sjs
dom/apps/tests/file_packaged_app.template.webapp
dom/apps/tests/mochitest.ini
dom/apps/tests/test_packaged_app_common.js
dom/apps/tests/test_theme_role.html
--- a/dom/apps/tests/file_app.sjs
+++ b/dom/apps/tests/file_app.sjs
@@ -1,19 +1,20 @@
 var gBasePath = "tests/dom/apps/tests/";
 var gAppTemplatePath = "tests/dom/apps/tests/file_app.template.html";
 var gAppcacheTemplatePath = "tests/dom/apps/tests/file_cached_app.template.appcache";
 var gWidgetTemplatePath = "tests/dom/apps/tests/file_widget_app.template.html";
 var gDefaultIcon = "default_icon";
 
-function makeResource(templatePath, version, apptype) {
+function makeResource(templatePath, version, apptype, role) {
   let icon = getState('icon') || gDefaultIcon;
   var res = readTemplate(templatePath).replace(/VERSIONTOKEN/g, version)
                                       .replace(/APPTYPETOKEN/g, apptype)
-                                      .replace(/ICONTOKEN/g, icon);
+                                      .replace(/ICONTOKEN/g, icon)
+                                      .replace(/ROLE/g, role);
 
   // Hack - This is necessary to make the tests pass, but hbambas says it
   // shouldn't be necessary. Comment it out and watch the tests fail.
   if (templatePath == gAppTemplatePath && apptype == 'cached') {
     res = res.replace('<html>', '<html manifest="file_app.sjs?apptype=cached&getappcache=true">');
   }
   return res;
 }
@@ -44,16 +45,18 @@ function handleRequest(request, response
     return;
   }
 
   // Get the app type.
   var apptype = query.apptype;
   if (apptype != 'hosted' && apptype != 'cached' && apptype != 'widget'  && apptype != 'invalidWidget')
     throw "Invalid app type: " + apptype;
 
+  var role = query.role;
+
   // Get the version from server state and handle the etag.
   var version = Number(getState('version'));
   var etag = getEtag(request, version);
   dump("Server Etag: " + etag + "\n");
 
   if (etagMatches(request, etag)) {
     dump("Etags Match. Sending 304\n");
     response.setStatusLine(request.httpVersion, "304", "Not Modified");
@@ -65,38 +68,38 @@ function handleRequest(request, response
     dump("Client Etag: " + request.getHeader("If-None-Match") + "\n");
   else
     dump("No Client Etag\n");
 
   // Check if we're generating a webapp manifest.
   if ('getmanifest' in query) {
     var template = gBasePath + 'file_' + apptype + '_app.template.webapp';
     response.setHeader("Content-Type", "application/x-web-app-manifest+json", false);
-    response.write(makeResource(template, version, apptype));
+    response.write(makeResource(template, version, apptype, role));
     return;
   }
 
   // If apptype==cached, we might be generating the appcache manifest.
   //
   // NB: Among other reasons, we use the same sjs file here so that the version
   //     state is shared.
   if (apptype == 'cached' && 'getappcache' in query) {
     response.setHeader("Content-Type", "text/cache-manifest", false);
-    response.write(makeResource(gAppcacheTemplatePath, version, apptype));
+    response.write(makeResource(gAppcacheTemplatePath, version, apptype, role));
     return;
   }
   else if (apptype == 'widget' || apptype == 'invalidWidget')
   {
     response.setHeader("Content-Type", "text/html", false);
-    response.write(makeResource(gWidgetTemplatePath, version, apptype));
+    response.write(makeResource(gWidgetTemplatePath, version, apptype, role));
     return;
   }
   // Generate the app.
   response.setHeader("Content-Type", "text/html", false);
-  response.write(makeResource(gAppTemplatePath, version, apptype));
+  response.write(makeResource(gAppTemplatePath, version, apptype, role));
 }
 
 function getEtag(request, version) {
   return request.queryString.replace(/&/g, '-').replace(/=/g, '-') + '-' + version;
 }
 
 function etagMatches(request, etag) {
   return request.hasHeader("If-None-Match") && request.getHeader("If-None-Match") == etag;
--- a/dom/apps/tests/file_hosted_app.template.webapp
+++ b/dom/apps/tests/file_hosted_app.template.webapp
@@ -1,8 +1,9 @@
 {
   "name": "Really Rapid Release (hosted)",
   "description": "Updated even faster than <a href='http://mozilla.org'>Firefox</a>, just to annoy slashdotters.",
   "launch_path": "/tests/dom/apps/tests/file_app.sjs?apptype=hosted",
   "icons": {
     "128": "ICONTOKEN"
-  }
+  },
+  "role": "ROLE"
 }
--- a/dom/apps/tests/file_packaged_app.sjs
+++ b/dom/apps/tests/file_packaged_app.sjs
@@ -23,16 +23,17 @@ function handleRequest(request, response
   var packageSize = ("packageSize" in query) ? query.packageSize : 0;
   var appName = ("appName" in query) ? query.appName : gAppName;
   var devName = ("devName" in query) ? query.devName : gDevName;
   var devUrl = ("devUrl" in query) ? query.devUrl : gDevUrl;
   // allowCancel just means deliver the file slowly so we have time to cancel it
   var allowCancel = "allowCancel" in query;
   var getPackage = "getPackage" in query;
   var alreadyDeferred = Number(getState("alreadyDeferred"));
+  var role = query.role || "";
 
   if (allowCancel && getPackage && !alreadyDeferred) {
     // Only do this for the actual package delivery.
     response.processAsync();
     // And to avoid timer problems, only do this once.
     setState("alreadyDeferred", "1");
   }
 
@@ -58,17 +59,17 @@ function handleRequest(request, response
                         .createInstance(Ci.nsIZipWriter);
       var zipFile = FileUtils.getFile("TmpD", [packageName]);
       zipWriter.open(zipFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE);
 
       // We want to run some tests without the manifest included in the zip.
       if (version != "0") {
         var manifestTemplate = gBasePath + gMiniManifestTemplate;
         var manifest = makeResource(manifestTemplate, version, packagePath,
-                                    packageSize, appName, devName, devUrl);
+                                    packageSize, appName, devName, devUrl, role);
         addZipEntry(zipWriter, manifest, "manifest.webapp");
       }
 
       var appTemplate = gBasePath + gAppTemplate;
       var app = makeResource(appTemplate, version, packagePath, packageSize,
                              appName, devName, devUrl);
       addZipEntry(zipWriter, app, "index.html");
 
@@ -117,17 +118,17 @@ function handleRequest(request, response
   if ("getManifest" in query) {
     var template = gBasePath + gMiniManifestTemplate;
     if (!("noManifestContentType" in query)) {
       response.setHeader("Content-Type",
                          "application/x-web-app-manifest+json", false);
     }
     packagePath = "wrongPackagePath" in query ? "" : packagePath;
     var manifest = makeResource(template, version, packagePath, packageSize,
-                                appName, devName, devUrl);
+                                appName, devName, devUrl, role);
     response.write(manifest);
     return;
   }
 
   response.setHeader("Content-type", "text-html", false);
   response.write("KO");
 }
 
@@ -173,18 +174,19 @@ function readFile(path, fromTmp) {
   }
   fstream.init(file, -1, 0, 0);
   var data = NetUtil.readInputStreamToString(fstream, fstream.available());
   fstream.close();
   return data;
 }
 
 function makeResource(templatePath, version, packagePath, packageSize,
-                      appName, developerName, developerUrl) {
+                      appName, developerName, developerUrl, role) {
   var res = readFile(templatePath, false)
             .replace(/VERSIONTOKEN/g, version)
             .replace(/PACKAGEPATHTOKEN/g, packagePath)
             .replace(/PACKAGESIZETOKEN/g, packageSize)
             .replace(/NAMETOKEN/g, appName)
             .replace(/DEVELOPERTOKEN/g, developerName)
-            .replace(/DEVELOPERURLTOKEN/g, developerUrl);
+            .replace(/DEVELOPERURLTOKEN/g, developerUrl)
+            .replace(/ROLETOKEN/g, role);
   return res;
 }
--- a/dom/apps/tests/file_packaged_app.template.webapp
+++ b/dom/apps/tests/file_packaged_app.template.webapp
@@ -11,10 +11,11 @@
      "test-permission": {"access": "readonly"},
      "downloads": {}
    },
   "launch_path": "tests/dom/apps/tests/file_packaged_app.sjs",
   "developer": {
     "name": "DEVELOPERTOKEN",
     "url": "DEVELOPERURLTOKEN"
   },
-  "default_locale": "en-US"
+  "default_locale": "en-US",
+  "role": "ROLETOKEN"
 }
--- a/dom/apps/tests/mochitest.ini
+++ b/dom/apps/tests/mochitest.ini
@@ -26,9 +26,10 @@ support-files =
 [test_install_receipts.html]
 [test_marketplace_pkg_install.html]
 skip-if = buildapp == "b2g" || toolkit == "android" # see bug 989806
 [test_packaged_app_install.html]
 [test_packaged_app_update.html]
 [test_receipt_operations.html]
 [test_signed_pkg_install.html]
 [test_uninstall_errors.html]
+[test_theme_role.html]
 [test_widget.html]
--- a/dom/apps/tests/test_packaged_app_common.js
+++ b/dom/apps/tests/test_packaged_app_common.js
@@ -52,27 +52,30 @@ var PackagedTestHelper = (function Packa
     finish();
   }
 
   function xhrAbort(url) {
     ok(false, "XHR abort loading " + url);
     finish();
   }
 
-  function setAppVersion(aVersion, aCb, aDontUpdatePackage, aAllowCancel) {
+  function setAppVersion(aVersion, aCb, aDontUpdatePackage, aAllowCancel, aRole) {
     var xhr = new XMLHttpRequest();
     var dontUpdate = "";
     var allowCancel = "";
     if (aDontUpdatePackage) {
       dontUpdate = "&dontUpdatePackage=1";
     }
     if (aAllowCancel) {
       allowCancel= "&allowCancel=1";
     }
     var url = gSJS + "?setVersion=" + aVersion + dontUpdate + allowCancel;
+    if (aRole) {
+      url += "&role=" + aRole;
+    }
     xhr.addEventListener("load", function() {
                            is(xhr.responseText, "OK", "setAppVersion OK");
                            aCb();
                          });
     xhr.addEventListener("error", event => xhrError(event, url));
     xhr.addEventListener("abort", event => xhrAbort(url));
     xhr.open("GET", url, true);
     xhr.send();
new file mode 100644
--- /dev/null
+++ b/dom/apps/tests/test_theme_role.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id={1011738}
+-->
+<head>
+  <title>Test for Bug {1011738}</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="test_packaged_app_common.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1011738}">Mozilla Bug {1011738}</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="application/javascript;version=1.7">
+
+var gHostedURL = "http://test/tests/dom/apps/tests/file_app.sjs?apptype=hosted&getmanifest=true&role=theme";
+
+var gPackageURL = PackagedTestHelper.gSJS + "?getManifest=true&test_role";
+var gGenerator = runTest();
+
+function go() {
+  SpecialPowers.pushPermissions(
+    [{ "type": "webapps-manage", "allow": 1, "context": document }],
+    function() { gGenerator.next() });
+}
+
+function continueTest() {
+  try {
+    gGenerator.next();
+  } catch (e if e instanceof StopIteration) {
+    finish();
+  }
+}
+
+function finish() {
+  SimpleTest.finish();
+}
+
+function cbError(aEvent) {
+  ok(false, "Error callback invoked " +
+            aEvent.target.error.name + " " + aEvent.target.error.message);
+  finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+/**
+  * Checks that no apps that are not certified can be installed as themes.
+  */
+function runTest() {
+  SpecialPowers.setAllAppsLaunchable(true);
+
+  SpecialPowers.autoConfirmAppInstall(continueTest);
+  yield undefined;
+
+  // Test that a hosted app can't be a theme.
+  info("Hosted apps can't be themes.");
+  var request = navigator.mozApps.install(gHostedURL, { });
+  request.onerror = function() {
+    is(request.error.name, "INVALID_ROLE");
+    continueTest();
+  };
+  request.onsuccess = function() {
+    ok(false, "We should not install this app!");
+  };
+  yield undefined;
+
+  info("Non certified packaged apps can't be themes.");
+
+  PackagedTestHelper.setAppVersion(1, continueTest, false, false, "theme");
+  yield undefined;
+
+  request = navigator.mozApps.installPackage(gPackageURL, { });
+  request.onerror = cbError;
+
+  request.onsuccess = function() {
+    info("Installing package.");
+  };
+  navigator.mozApps.mgmt.oninstall = function(evt) {
+      info("Got oninstall event");
+      PackagedTestHelper.gApp = evt.application;
+
+      PackagedTestHelper.gApp.ondownloaderror = function() {
+        is(PackagedTestHelper.gApp.downloadError.name, "INVALID_ROLE");
+        continueTest();
+      };
+
+      PackagedTestHelper.gApp.ondownloadapplied = function() {
+        info("App download applied.");
+        ok(false, "We should not install this app!");
+        continueTest();
+      }
+
+    };
+  yield undefined;
+}
+
+addLoadEvent(go);
+
+</script>
+</pre>
+</body>
+</html>