Make Connector Server tests compatible with electron

Refactor /detect and /savePage endpoints
This commit is contained in:
Adomas Venčkauskas 2018-08-23 15:57:59 +03:00
parent 57fd05c7e3
commit 377f8d0aa8
4 changed files with 239 additions and 274 deletions

View file

@ -100,7 +100,7 @@ Zotero.Server.Connector = {
case 'C': case 'C':
collection = Zotero.Collections.get(id); collection = Zotero.Collections.get(id);
library = collection.library; library = collection.library;
editable = collection.editable; editable = collection.library.editable;
break; break;
default: default:
@ -447,59 +447,25 @@ Zotero.Server.Connector.Detect.prototype = {
* @param {Object} data POST data or GET query string * @param {Object} data POST data or GET query string
* @param {Function} sendResponseCallback function to send HTTP response * @param {Function} sendResponseCallback function to send HTTP response
*/ */
init: function(url, data, sendResponseCallback) { init: async function({data}) {
this.sendResponse = sendResponseCallback; var translate = new Zotero.Translate.Web();
this._parsedPostData = data;
this._translate = new Zotero.Translate("web"); var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
this._translate.setHandler("translators", function(obj, item) { me._translatorsAvailable(obj, item) }); .createInstance(Components.interfaces.nsIDOMParser);
var doc = parser.parseFromString(`<html>${data.html}</html>`, 'text/html');
Zotero.Server.Connector.Data[this._parsedPostData["uri"]] = "<html>"+this._parsedPostData["html"]+"</html>"; doc = Zotero.HTTP.wrapDocument(doc, data.uri);
this._browser = Zotero.Browser.createHiddenBrowser();
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri = ioService.newURI(this._parsedPostData["uri"], "UTF-8", null);
var pageShowCalled = false;
var me = this;
this._translate.setCookieSandbox(new Zotero.CookieSandbox(this._browser,
this._parsedPostData["uri"], this._parsedPostData["cookie"], url.userAgent));
this._browser.addEventListener("DOMContentLoaded", function() {
try {
if(me._browser.contentDocument.location.href == "about:blank") return;
if(pageShowCalled) return;
pageShowCalled = true;
delete Zotero.Server.Connector.Data[me._parsedPostData["uri"]];
// get translators // get translators
me._translate.setDocument(me._browser.contentDocument); translate.setDocument(doc);
me._translate.setLocation(me._parsedPostData["uri"], me._parsedPostData["uri"]);
me._translate.getTranslators();
} catch(e) {
sendResponseCallback(500);
throw e;
}
}, false);
me._browser.loadURI("zotero://connector/"+encodeURIComponent(this._parsedPostData["uri"])); var translators = await translate.getTranslators();
},
/**
* Callback to be executed when list of translators becomes available. Sends standard
* translator passing properties with proxies where available for translators.
* @param {Zotero.Translate} translate
* @param {Zotero.Translator[]} translators
*/
_translatorsAvailable: function(translate, translators) {
translators = translators.map(function(translator) { translators = translators.map(function(translator) {
translator = translator.serialize(TRANSLATOR_PASSING_PROPERTIES.concat('proxy')); translator = translator.serialize(Zotero.Translator.TRANSLATOR_PASSING_PROPERTIES.concat('proxy'));
translator.proxy = translator.proxy ? translator.proxy.toJSON() : null; translator.proxy = translator.proxy ? translator.proxy.toJSON() : null;
return translator; return translator;
}); });
this.sendResponse(200, "application/json", JSON.stringify(translators)); return [200, "application/json", JSON.stringify(translators)];
Zotero.Browser.deleteHiddenBrowser(this._browser);
} }
} }
@ -532,7 +498,9 @@ Zotero.Server.Connector.SavePage.prototype = {
* @param {Object} data POST data or GET query string * @param {Object} data POST data or GET query string
* @param {Function} sendResponseCallback function to send HTTP response * @param {Function} sendResponseCallback function to send HTTP response
*/ */
init: function(url, data, sendResponseCallback) { init: async function(url, data, sendResponseCallback) {
try {
this.sendResponse = sendResponseCallback;
var { library, collection, editable } = Zotero.Server.Connector.getSaveTarget(); var { library, collection, editable } = Zotero.Server.Connector.getSaveTarget();
// Shouldn't happen as long as My Library exists // Shouldn't happen as long as My Library exists
@ -540,9 +508,46 @@ Zotero.Server.Connector.SavePage.prototype = {
Zotero.logError("Can't add item to read-only library " + library.name); Zotero.logError("Can't add item to read-only library " + library.name);
return sendResponseCallback(500, "application/json", JSON.stringify({ libraryEditable: false })); return sendResponseCallback(500, "application/json", JSON.stringify({ libraryEditable: false }));
} }
var libraryID = library.libraryID;
this.sendResponse = sendResponseCallback; var translate = new Zotero.Translate.Web();
Zotero.Server.Connector.Detect.prototype.init.apply(this, [url, data, sendResponseCallback])
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Components.interfaces.nsIDOMParser);
var doc = parser.parseFromString(`<html>${data.html}</html>`, 'text/html');
doc = Zotero.HTTP.wrapDocument(doc, data.uri);
// get translators
translate.setDocument(doc);
var translators = await translate.getTranslators();
// make sure translatorsAvailable succeded
if(!translators.length) {
return sendResponseCallback(500);
}
// set handlers for translation
var jsonItems = [];
translate.setHandler("select", function(obj, item, callback) { return me._selectItems(obj, item, callback) });
translate.setHandler("itemDone", function(obj, item, jsonItem) {
jsonItems.push(jsonItem);
});
translate.setHandler("done", function(obj, item) {
if(jsonItems.length || me.selectedItems === false) {
sendResponseCallback(201, "application/json", JSON.stringify({items: jsonItems}));
} else {
sendResponseCallback(500);
}
});
Zotero.debug(data.translatorID || translators[0]);
translate.setTranslator(data.translatorID || translators[0]);
translate.translate({libraryID, collections: collection ? [collection.id] : false});
} catch (e) {
Zotero.logError(e);
sendResponseCallback(500);
}
}, },
/** /**
@ -567,51 +572,6 @@ Zotero.Server.Connector.SavePage.prototype = {
this.sendResponse(300, "application/json", JSON.stringify({selectItems: itemList, instanceID: instanceID, uri: this._parsedPostData.uri})); this.sendResponse(300, "application/json", JSON.stringify({selectItems: itemList, instanceID: instanceID, uri: this._parsedPostData.uri}));
this.selectedItemsCallback = callback; this.selectedItemsCallback = callback;
}, },
/**
* Callback to be executed when list of translators becomes available. Opens progress window,
* selects specified translator, and initiates translation.
* @param {Zotero.Translate} translate
* @param {Zotero.Translator[]} translators
*/
_translatorsAvailable: function(translate, translators) {
// make sure translatorsAvailable succeded
if(!translators.length) {
Zotero.Browser.deleteHiddenBrowser(this._browser);
this.sendResponse(500);
return;
}
var { library, collection, editable } = Zotero.Server.Connector.getSaveTarget();
var libraryID = library.libraryID;
// set handlers for translation
var me = this;
var jsonItems = [];
translate.setHandler("select", function(obj, item, callback) { return me._selectItems(obj, item, callback) });
translate.setHandler("itemDone", function(obj, item, jsonItem) {
//Zotero.Server.Connector.AttachmentProgressManager.add(jsonItem.attachments);
jsonItems.push(jsonItem);
});
translate.setHandler("attachmentProgress", function(obj, attachment, progress, error) {
//Zotero.Server.Connector.AttachmentProgressManager.onProgress(attachment, progress, error);
});
translate.setHandler("done", function(obj, item) {
Zotero.Browser.deleteHiddenBrowser(me._browser);
if(jsonItems.length || me.selectedItems === false) {
me.sendResponse(201, "application/json", JSON.stringify({items: jsonItems}));
} else {
me.sendResponse(500);
}
});
if (this._parsedPostData.translatorID) {
translate.setTranslator(this._parsedPostData.translatorID);
} else {
translate.setTranslator(translators[0]);
}
translate.translate({libraryID, collections: collection ? [collection.id] : false});
}
} }
/** /**

View file

@ -219,3 +219,4 @@ Zotero.Translator.RUN_MODE_ZOTERO_SERVER = 4;
Zotero.Translator.TRANSLATOR_TYPES = TRANSLATOR_TYPES; Zotero.Translator.TRANSLATOR_TYPES = TRANSLATOR_TYPES;
Zotero.Translator.TRANSLATOR_OPTIONAL_PROPERTIES = TRANSLATOR_OPTIONAL_PROPERTIES; Zotero.Translator.TRANSLATOR_OPTIONAL_PROPERTIES = TRANSLATOR_OPTIONAL_PROPERTIES;
Zotero.Translator.TRANSLATOR_REQUIRED_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES; Zotero.Translator.TRANSLATOR_REQUIRED_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES;
Zotero.Translator.TRANSLATOR_PASSING_PROPERTIES = TRANSLATOR_PASSING_PROPERTIES;

View file

@ -81,6 +81,7 @@ Zotero.Translators = new function() {
var translatorsDir = Zotero.getTranslatorsDirectory().path; var translatorsDir = Zotero.getTranslatorsDirectory().path;
var iterator = new OS.File.DirectoryIterator(translatorsDir); var iterator = new OS.File.DirectoryIterator(translatorsDir);
try { try {
yield Zotero.DB.executeTransaction(function* () {
while (true) { while (true) {
let entries = yield iterator.nextBatch(5); // TODO: adjust as necessary let entries = yield iterator.nextBatch(5); // TODO: adjust as necessary
if (!entries.length) break; if (!entries.length) break;
@ -202,6 +203,7 @@ Zotero.Translators = new function() {
numCached++; numCached++;
} }
} }
}.bind(this))
} }
finally { finally {
iterator.close(); iterator.close();

View file

@ -472,7 +472,7 @@ describe("Connector Server", function () {
continue; continue;
} }
} }
await Zotero.Promise.delay(10); await Zotero.Promise.delay(100);
} }
// Legacy endpoint should show 100 // Legacy endpoint should show 100
@ -579,7 +579,7 @@ describe("Connector Server", function () {
} }
} }
assert.isFalse(response.done); assert.isFalse(response.done);
await Zotero.Promise.delay(10); await Zotero.Promise.delay(100);
} }
assert.isTrue(wasZero); assert.isTrue(wasZero);
@ -791,6 +791,7 @@ describe("Connector Server", function () {
}); });
it("should save a PDF to the current selected collection and retrieve metadata", async function () { it("should save a PDF to the current selected collection and retrieve metadata", async function () {
try {
var collection = await createDataObject('collection'); var collection = await createDataObject('collection');
await waitForItemsLoad(win); await waitForItemsLoad(win);
@ -845,8 +846,9 @@ describe("Connector Server", function () {
progressWindow.close(); progressWindow.close();
Zotero.RecognizePDF.cancel(); Zotero.RecognizePDF.cancel();
assert.isFalse(item.isTopLevelItem()); assert.isFalse(item.isTopLevelItem());
} finally {
stub.restore(); stub.restore();
}
}); });
it("should switch to My Library if a read-only library is selected", function* () { it("should switch to My Library if a read-only library is selected", function* () {
@ -912,7 +914,7 @@ describe("Connector Server", function () {
}); });
it("should translate a page if translators are available", function* () { it("should translate a page if translators are available", function* () {
var html = Zotero.File.getContentsFromURL(getTestDataUrl('coins.html')); var html = yield Zotero.File.getContentsFromURLAsync(getTestDataUrl('coins.html'));
var promise = waitForItemEvent('add'); var promise = waitForItemEvent('add');
var xmlhttp = yield Zotero.HTTP.request( var xmlhttp = yield Zotero.HTTP.request(
'POST', 'POST',
@ -929,12 +931,12 @@ describe("Connector Server", function () {
} }
); );
assert.equal(xmlhttp.status, 201);
let ids = yield promise; let ids = yield promise;
var item = Zotero.Items.get(ids[0]); var item = Zotero.Items.get(ids[0]);
var title = "Test Page"; var title = "Test Page";
assert.equal(JSON.parse(xmlhttp.responseText).items[0].title, title); assert.equal(JSON.parse(xmlhttp.responseText).items[0].title, title);
assert.equal(item.getField('title'), title); assert.equal(item.getField('title'), title);
assert.equal(xmlhttp.status, 201);
}); });
}); });