Fix server_connector tests broken in 69ab4b0b

Don't display error prompt in standalone when style install fails.
Fixes an import bug when import input is invalid.
This commit is contained in:
Adomas Venčkauskas 2016-11-30 13:53:58 +02:00
parent 1b67ed071e
commit 45c944e731
5 changed files with 88 additions and 33 deletions

View file

@ -605,7 +605,7 @@ Zotero.Server.Connector.Import.prototype = {
translate.setString(data);
let translators = yield translate.getTranslators();
if (!translators || !translators.length) {
return sendResponseCallback(404);
return sendResponseCallback(400);
}
translate.setTranslator(translators[0]);
let items = yield translate.translate();
@ -628,7 +628,11 @@ Zotero.Server.Connector.InstallStyle.prototype = {
permitBookmarklet: false,
init: Zotero.Promise.coroutine(function* (url, data, sendResponseCallback){
let styleName = yield Zotero.Styles.install(data, url.query.origin || null, true);
try {
var styleName = yield Zotero.Styles.install(data, url.query.origin || null, true);
} catch (e) {
sendResponseCallback(400, "text/plain", e.message)
}
sendResponseCallback(201, "application/json", JSON.stringify({name: styleName}));
})
};

View file

@ -242,33 +242,42 @@ Zotero.Styles = new function() {
* containing the style data
* @param {String} origin The origin of the style, either a filename or URL, to be
* displayed in dialogs referencing the style
* @param {Boolean} [noPrompt=false] Skip the confirmation prompt
* @param {Boolean} [silent=false] Skip prompts
*/
this.install = Zotero.Promise.coroutine(function* (style, origin, noPrompt=false) {
this.install = Zotero.Promise.coroutine(function* (style, origin, silent=false) {
var styleTitle;
origin = origin || Zotero.getString('styles.unknownOrigin');
try {
if (style instanceof Components.interfaces.nsIFile) {
// handle nsIFiles
var url = Services.io.newFileURI(style);
var xmlhttp = yield Zotero.HTTP.request("GET", url.spec);
styleTitle = yield _install(xmlhttp.responseText, style.leafName, false, noPrompt);
styleTitle = yield _install(xmlhttp.responseText, style.leafName, false, silent);
} else {
styleTitle = yield _install(style, origin, false, noPrompt);
styleTitle = yield _install(style, origin, false, silent);
}
}
catch (error) {
// Unless user cancelled, show an alert with the error
if(typeof error === "object" && error instanceof Zotero.Exception.UserCancelled) return;
if(typeof error === "object" && error instanceof Zotero.Exception.Alert) {
error.present();
error.log();
if (silent) {
throw (error)
} else {
error.present();
}
} else {
Zotero.logError(error);
if (silent) {
throw error
} else {
(new Zotero.Exception.Alert("styles.install.unexpectedError",
origin, "styles.install.title", error)).present();
}
}
}
return styleTitle;
});
@ -278,10 +287,10 @@ Zotero.Styles = new function() {
* @param {String} origin The origin of the style, either a filename or URL, to be
* displayed in dialogs referencing the style
* @param {Boolean} [hidden] Whether style is to be hidden.
* @param {Boolean} [noPrompt=false] Skip the confirmation prompt
* @param {Boolean} [silent=false] Skip prompts
* @return {Promise}
*/
var _install = Zotero.Promise.coroutine(function* (style, origin, hidden, noPrompt=false) {
var _install = Zotero.Promise.coroutine(function* (style, origin, hidden, silent=false) {
if (!_initialized) yield Zotero.Styles.init();
var existingFile, destFile, source;
@ -364,7 +373,7 @@ Zotero.Styles = new function() {
// display a dialog to tell the user we're about to install the style
if(hidden) {
destFile = destFileHidden;
} else if (!noPrompt) {
} else if (!silent) {
if(existingTitle) {
var text = Zotero.getString('styles.updateStyle', [existingTitle, title, origin]);
} else {

View file

@ -1094,6 +1094,8 @@ Zotero.Translate.Base.prototype = {
if(this._currentState === "detect") throw new Error("getTranslators: detection is already running");
this._currentState = "detect";
this._getAllTranslators = getAllTranslators;
this._potentialTranslators = [];
this._foundTranslators = [];
if(checkSetTranslator) {
// setTranslator must be called beforehand if checkSetTranslator is set
@ -1123,8 +1125,6 @@ Zotero.Translate.Base.prototype = {
return potentialTranslators.then(function(result) {
var allPotentialTranslators = result[0];
var properToProxyFunctions = result[1];
this._potentialTranslators = [];
this._foundTranslators = [];
// this gets passed out by Zotero.Translators.getWebTranslatorsForLocation() because it is
// specific for each translator, but we want to avoid making a copy of a translator whenever
@ -1441,7 +1441,6 @@ Zotero.Translate.Base.prototype = {
var errorString = null;
if(!returnValue && error) errorString = this._generateErrorString(error);
if(this._currentState === "detect") {
if(this._potentialTranslators.length) {
var lastTranslator = this._potentialTranslators.shift();

View file

@ -832,6 +832,7 @@ styles.validationWarning = "%S" is not a valid CSL 1.0.1 style file, and may n
styles.installSourceError = %1$S references an invalid or non-existent CSL file at %2$S as its source.
styles.deleteStyle = Are you sure you want to delete the style "%1$S"?
styles.deleteStyles = Are you sure you want to delete the selected styles?
styles.unknownOrigin = External Style
styles.abbreviations.title = Load Abbreviations
styles.abbreviations.parseError = The abbreviations file "%1$S" is not valid JSON.

View file

@ -6,11 +6,13 @@ describe("Connector Server", function () {
var testServerPort = 16213;
before(function* () {
this.timeout(20000);
Zotero.Prefs.set("httpServer.enabled", true);
yield resetDB({
thisArg: this,
skipBundledFiles: true
});
yield Zotero.Translators.init();
win = yield loadZoteroPane();
connectorServerPath = 'http://127.0.0.1:' + Zotero.Prefs.get('httpServer.port');
@ -314,30 +316,30 @@ describe("Connector Server", function () {
});
});
describe('/connector/importStyle', function() {
describe('/connector/installStyle', function() {
var endpoint;
before(function() {
endpoint = connectorServerPath + "/connector/importStyle";
endpoint = connectorServerPath + "/connector/installStyle";
});
it('should reject application/json requests', function* () {
try {
var response = yield Zotero.HTTP.request(
it('should reject styles with invalid text', function* () {
var error = yield getPromiseError(Zotero.HTTP.request(
'POST',
endpoint,
{
headers: { "Content-Type": "application/json" },
body: '{}'
}
);
} catch(e) {
assert.instanceOf(e, Zotero.HTTP.UnexpectedStatusException);
assert.equal(e.xmlhttp.status, 400);
}
));
assert.instanceOf(error, Zotero.HTTP.UnexpectedStatusException);
assert.equal(error.xmlhttp.status, 400);
assert.equal(error.xmlhttp.responseText,
Zotero.getString("styles.installError",
Zotero.getString('styles.unknownOrigin')));
});
it('should import a style with text/x-csl content-type', function* () {
it('should import a style with application/vnd.citationstyles.style+xml content-type', function* () {
sinon.stub(Zotero.Styles, 'install', function(style) {
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Components.interfaces.nsIDOMParser),
@ -362,7 +364,7 @@ describe("Connector Server", function () {
'POST',
endpoint,
{
headers: { "Content-Type": "text/x-csl" },
headers: { "Content-Type": "application/vnd.citationstyles.style+xml" },
body: style
}
);
@ -371,4 +373,44 @@ describe("Connector Server", function () {
Zotero.Styles.install.restore();
});
});
describe('/connector/import', function() {
var endpoint;
before(function() {
endpoint = connectorServerPath + "/connector/import";
});
it('should reject resources that do not contain import data', function* () {
var error = yield getPromiseError(Zotero.HTTP.request(
'POST',
endpoint,
{
headers: { "Content-Type": "text/plain" },
body: 'Owl'
}
));
assert.instanceOf(error, Zotero.HTTP.UnexpectedStatusException);
assert.equal(error.xmlhttp.status, 400);
});
it('should import resources (BibTeX)', function* () {
var resource = `@book{test1,
title={Test1},
author={Owl},
year={1000},
publisher={Curly Braces Publishing}
}`;
var response = yield Zotero.HTTP.request(
'POST',
endpoint,
{
headers: { "Content-Type": "application/x-bibtex" },
body: resource
}
);
assert.equal(response.status, 201);
assert.equal(JSON.parse(response.responseText)[0].title, 'Test1');
});
});
});