Bug 913711 - Added methods for finding manifest and updates project location if necessary. r=pablo

This commit is contained in:
Pablo Terradillos 2014-09-18 08:14:00 +02:00
parent 869d88deb2
commit 3911a75096
6 changed files with 133 additions and 20 deletions

View File

@ -206,6 +206,14 @@ const AppProjects = {
return IDB.update(project);
},
updateLocation: function(project, newLocation) {
return IDB.remove(project.location)
.then(() => {
project.location = newLocation;
return IDB.add(project);
});
},
remove: function(location) {
return IDB.remove(location).then(function () {
let projects = store.object.projects;
@ -235,4 +243,3 @@ const AppProjects = {
EventEmitter.decorate(AppProjects);
exports.AppProjects = AppProjects;

View File

@ -8,6 +8,7 @@ const promise = require("devtools/toolkit/deprecated-sync-thenables");
const {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
const {Services} = Cu.import("resource://gre/modules/Services.jsm");
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
let XMLHttpRequest = CC("@mozilla.org/xmlextras/xmlhttprequest;1");
let strings = Services.strings.createBundle("chrome://browser/locale/devtools/app-manager.properties");
@ -51,44 +52,101 @@ AppValidator.prototype._getPackagedManifestURL = function () {
return Services.io.newFileURI(manifestFile).spec;
};
AppValidator.prototype._fetchManifest = function (manifestURL) {
AppValidator.checkManifest = function(manifestURL) {
let deferred = promise.defer();
this.manifestURL = manifestURL;
let error;
let req = new XMLHttpRequest();
req.overrideMimeType('text/plain');
try {
req.open("GET", manifestURL, true);
} catch(e) {
this.error(strings.formatStringFromName("validator.invalidManifestURL", [manifestURL], 1));
deferred.resolve(null);
error = strings.formatStringFromName("validator.invalidManifestURL", [manifestURL], 1);
deferred.reject(error);
return deferred.promise;
}
req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_CACHING;
req.onload = (function () {
req.onload = function () {
let manifest = null;
try {
manifest = JSON.parse(req.responseText);
} catch(e) {
this.error(strings.formatStringFromName("validator.invalidManifestJSON", [e, manifestURL], 2));
error = strings.formatStringFromName("validator.invalidManifestJSON", [e, manifestURL], 2);
deferred.reject(error);
}
deferred.resolve(manifest);
}).bind(this);
req.onerror = (function () {
this.error(strings.formatStringFromName("validator.noAccessManifestURL", [req.statusText, manifestURL], 2));
deferred.resolve(null);
}).bind(this);
deferred.resolve({manifest, manifestURL});
};
req.onerror = function () {
error = strings.formatStringFromName("validator.noAccessManifestURL", [req.statusText, manifestURL], 2);
deferred.reject(error);
};
try {
req.send(null);
} catch(e) {
this.error(strings.formatStringFromName("validator.noAccessManifestURL", [e, manifestURL], 2));
deferred.resolve();
error = strings.formatStringFromName("validator.noAccessManifestURL", [e, manifestURL], 2);
deferred.reject(error);
}
return deferred.promise;
};
AppValidator.findManifestAtOrigin = function(manifestURL) {
let fixedManifest = Services.io.newURI(manifestURL, null, null).prePath + '/manifest.webapp';
return AppValidator.checkManifest(fixedManifest);
};
AppValidator.findManifestPath = function(manifestURL) {
let deferred = promise.defer();
if (manifestURL.endsWith('manifest.webapp')) {
deferred.reject();
} else {
let fixedManifest = manifestURL + '/manifest.webapp';
deferred.resolve(AppValidator.checkManifest(fixedManifest));
}
return deferred.promise;
};
AppValidator.checkAlternateManifest = function(manifestURL) {
return Task.spawn(function*() {
let result;
try {
result = yield AppValidator.findManifestPath(manifestURL);
} catch(e) {
result = yield AppValidator.findManifestAtOrigin(manifestURL);
}
return result;
});
};
AppValidator.prototype._fetchManifest = function (manifestURL) {
let deferred = promise.defer();
this.manifestURL = manifestURL;
AppValidator.checkManifest(manifestURL)
.then(({manifest, manifestURL}) => {
deferred.resolve(manifest);
}, error => {
AppValidator.checkAlternateManifest(manifestURL)
.then(({manifest, manifestURL}) => {
this.manifestURL = manifestURL;
deferred.resolve(manifest);
}, () => {
this.error(error);
deferred.resolve(null);
});
});
return deferred.promise;
};
AppValidator.prototype._getManifest = function () {
let manifestURL;
if (this.project.type == "packaged") {

View File

@ -40,12 +40,12 @@
next();
}
function createHosted(path) {
function createHosted(path, manifestFile="/manifest.webapp") {
let dirPath = getTestFilePath("validator/" + path);
httpserver.registerDirectory("/", nsFile(dirPath));
return new AppValidator({
type: "hosted",
location: origin + "/manifest.webapp"
location: origin + manifestFile
});
}
@ -154,6 +154,38 @@
validator.validate().then(() => {
checkNoNameOrIcon(validator);
});
},
// Test a regular URL instead of a direct link to the manifest
function () {
let validator = createHosted("valid", "/");
validator.validate().then(() => {
is(validator.warnings.length, 0, "manifest found got no warning");
is(validator.errors.length, 0, "manifest found got no error");
next();
});
},
// Test finding a manifest at origin's root
function () {
let validator = createHosted("valid", "/unexisting-dir");
validator.validate().then(() => {
is(validator.warnings.length, 0, "manifest found at origin root got no warning");
is(validator.errors.length, 0, "manifest found at origin root got no error");
next();
});
},
// Test priorization of manifest.webapp at provided location instead of a manifest located at origin's root
function() {
let validator = createHosted("valid", "/alsoValid");
validator.validate().then(() => {
is(validator.manifest.name, "valid at subfolder", "manifest at subfolder was used");
next();
});
}
];

View File

@ -0,0 +1,7 @@
{
"name": "valid at subfolder",
"launch_path": "/home.html",
"icons": {
"128": "/icon.png"
}
}

View File

@ -619,7 +619,9 @@ exports.AppManager = AppManager = {
project.validationStatus = "error warning";
}
if (AppProjects.get(project.location)) {
if (project.type === "hosted" && project.location !== validation.manifestURL) {
yield AppProjects.updateLocation(project, validation.manifestURL);
} else if (AppProjects.get(project.location)) {
yield AppProjects.update(project);
}

View File

@ -45,6 +45,14 @@
is(project.location, hostedAppManifest, "Location is valid");
is(project.name, "hosted manifest name property", "name field has been updated");
yield nextTick();
hostedAppManifest = TEST_BASE + "/app";
yield win.Cmds.importHostedApp(hostedAppManifest);
project = win.AppManager.selectedProject;
ok(project.location.endsWith('manifest.webapp'), "The manifest was found and the project was updated");
info("opening panel");
yield win.Cmds.showProjectPanel();
info("panel open");
@ -52,7 +60,7 @@
let panelNode = win.document.querySelector("#project-panel");
let items = panelNode.querySelectorAll(".panel-item");
// 3 controls, + 2 projects
is(items.length, 5, "5 projects in panel");
is(items.length, 6, "6 projects in panel");
is(items[3].getAttribute("label"), "A name (in app directory)", "Panel label is correct");
is(items[4].getAttribute("label"), "hosted manifest name property", "Panel label is correct");
@ -71,4 +79,3 @@
</script>
</body>
</html>