2023-04-14 11:37:07 -04:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const { HiddenBrowser } = ChromeUtils.import("chrome://zotero/content/HiddenBrowser.jsm");
|
|
|
|
const { RemoteTranslate } = ChromeUtils.import("chrome://zotero/content/RemoteTranslate.jsm");
|
|
|
|
|
|
|
|
describe("RemoteTranslate", function () {
|
|
|
|
let dummyTranslator;
|
|
|
|
let translatorProvider;
|
2025-06-25 10:26:38 -04:00
|
|
|
let httpd;
|
|
|
|
let port = 16213;
|
|
|
|
|
|
|
|
before(async function () {
|
2023-04-14 11:37:07 -04:00
|
|
|
dummyTranslator = buildDummyTranslator('web', `
|
|
|
|
function detectWeb() {
|
|
|
|
Zotero.debug("test string");
|
|
|
|
return "book";
|
|
|
|
}
|
|
|
|
|
|
|
|
function doWeb() {
|
|
|
|
let item = new Zotero.Item("book");
|
|
|
|
item.title = "Title";
|
|
|
|
item.complete();
|
|
|
|
}
|
|
|
|
`);
|
|
|
|
|
|
|
|
translatorProvider = Zotero.Translators.makeTranslatorProvider({
|
|
|
|
get(translatorID) {
|
|
|
|
if (translatorID == dummyTranslator.translatorID) {
|
|
|
|
return dummyTranslator;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
async getAllForType(type) {
|
|
|
|
var translators = [];
|
|
|
|
if (type == 'web') {
|
|
|
|
translators.push(dummyTranslator);
|
|
|
|
}
|
|
|
|
return translators;
|
|
|
|
}
|
|
|
|
});
|
2025-06-25 10:26:38 -04:00
|
|
|
|
|
|
|
var { HttpServer } = ChromeUtils.import("chrome://remote/content/server/HTTPD.jsm");
|
|
|
|
httpd = new HttpServer();
|
|
|
|
httpd.start(port);
|
|
|
|
httpd.registerPathHandler(
|
|
|
|
'/readCookie',
|
|
|
|
{
|
|
|
|
handle: function (request, response) {
|
|
|
|
if (request.getHeader('Cookie') === 'sessionID=1') {
|
|
|
|
response.setStatusLine(null, 200, 'OK');
|
|
|
|
response.write('OK');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
response.setStatusLine(null, 403, 'Forbidden');
|
|
|
|
response.write('Header not set');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
after(async function () {
|
|
|
|
await new Promise(resolve => httpd.stop(resolve));
|
2023-04-14 11:37:07 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
describe("#setHandler()", function () {
|
|
|
|
it("should receive handler calls from the translator", async function () {
|
|
|
|
let translate = new RemoteTranslate();
|
2023-12-27 11:43:50 +02:00
|
|
|
let browser = new HiddenBrowser();
|
|
|
|
await browser.load(getTestDataUrl('test.html'));
|
2023-04-14 11:37:07 -04:00
|
|
|
await translate.setBrowser(browser);
|
|
|
|
await translate.setTranslator(dummyTranslator);
|
|
|
|
|
|
|
|
let debug = sinon.spy();
|
|
|
|
translate.setHandler('debug', debug);
|
|
|
|
await translate.detect();
|
|
|
|
sinon.assert.calledWith(debug, translate, 'test string');
|
|
|
|
|
2023-12-27 11:43:50 +02:00
|
|
|
browser.destroy();
|
2023-04-14 11:37:07 -04:00
|
|
|
translate.dispose();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe("#setTranslatorProvider()", function () {
|
|
|
|
it("should cause the passed provider to be queried instead of Zotero.Translators", async function () {
|
|
|
|
let translate = new RemoteTranslate();
|
2023-12-27 11:43:50 +02:00
|
|
|
let browser = new HiddenBrowser();
|
|
|
|
await browser.load(getTestDataUrl('test.html'));
|
2023-04-14 11:37:07 -04:00
|
|
|
await translate.setBrowser(browser);
|
|
|
|
translate.setTranslatorProvider(translatorProvider);
|
|
|
|
|
|
|
|
let detectedTranslators = await translate.detect();
|
|
|
|
assert.deepEqual(detectedTranslators.map(t => t.translatorID), [dummyTranslator.translatorID]);
|
|
|
|
|
2023-12-27 11:43:50 +02:00
|
|
|
browser.destroy();
|
2023-04-14 11:37:07 -04:00
|
|
|
translate.dispose();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe("#translate()", function () {
|
|
|
|
it("should return items without saving when libraryID is false", async function () {
|
|
|
|
let translate = new RemoteTranslate();
|
2023-12-27 11:43:50 +02:00
|
|
|
let browser = new HiddenBrowser();
|
|
|
|
await browser.load(getTestDataUrl('test.html'));
|
2023-04-14 11:37:07 -04:00
|
|
|
await translate.setBrowser(browser);
|
|
|
|
translate.setTranslatorProvider(translatorProvider);
|
|
|
|
|
|
|
|
let detectedTranslators = await translate.detect();
|
|
|
|
assert.equal(detectedTranslators[0].translatorID, dummyTranslator.translatorID);
|
|
|
|
|
|
|
|
let itemDone = sinon.spy();
|
|
|
|
translate.setHandler('itemDone', itemDone);
|
|
|
|
|
|
|
|
let items = await translate.translate({ libraryID: false });
|
|
|
|
sinon.assert.notCalled(itemDone); // No items should be saved
|
|
|
|
assert.equal(items[0].title, 'Title');
|
|
|
|
|
2023-12-27 11:43:50 +02:00
|
|
|
browser.destroy();
|
2023-04-14 11:37:07 -04:00
|
|
|
translate.dispose();
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should save items and call itemDone when libraryID is not false", async function () {
|
|
|
|
let translate = new RemoteTranslate();
|
2023-12-27 11:43:50 +02:00
|
|
|
let browser = new HiddenBrowser();
|
|
|
|
await browser.load(getTestDataUrl('test.html'));
|
2023-04-14 11:37:07 -04:00
|
|
|
await translate.setBrowser(browser);
|
|
|
|
translate.setTranslator(dummyTranslator);
|
|
|
|
|
|
|
|
let itemDone = sinon.spy();
|
|
|
|
translate.setHandler('itemDone', itemDone);
|
|
|
|
|
|
|
|
let items = await translate.translate({ libraryID: null }); // User library
|
|
|
|
sinon.assert.calledWith(itemDone, translate,
|
|
|
|
sinon.match({
|
|
|
|
libraryID: Zotero.Libraries.userLibraryID
|
|
|
|
}),
|
|
|
|
sinon.match({
|
|
|
|
title: 'Title'
|
|
|
|
}));
|
|
|
|
// Item should still be returned
|
2023-04-27 00:52:01 -04:00
|
|
|
assert.equal(items[0].getField('title'), 'Title');
|
2023-04-14 11:37:07 -04:00
|
|
|
|
2023-12-27 11:43:50 +02:00
|
|
|
browser.destroy();
|
2023-04-14 11:37:07 -04:00
|
|
|
translate.dispose();
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should call itemDone before done", async function () {
|
|
|
|
let translate = new RemoteTranslate();
|
2023-12-27 11:43:50 +02:00
|
|
|
let browser = new HiddenBrowser();
|
|
|
|
await browser.load(getTestDataUrl('test.html'));
|
2023-04-14 11:37:07 -04:00
|
|
|
await translate.setBrowser(browser);
|
|
|
|
translate.setTranslator(dummyTranslator);
|
|
|
|
|
|
|
|
let itemDone = sinon.spy();
|
|
|
|
translate.setHandler('itemDone', itemDone);
|
|
|
|
let done = sinon.spy();
|
|
|
|
translate.setHandler('done', done);
|
|
|
|
|
|
|
|
await translate.translate({ libraryID: null }); // User library
|
|
|
|
sinon.assert.calledOnce(itemDone);
|
|
|
|
sinon.assert.calledOnce(done);
|
|
|
|
assert.isTrue(itemDone.calledBefore(done));
|
|
|
|
|
2023-12-27 11:43:50 +02:00
|
|
|
browser.destroy();
|
2023-04-14 11:37:07 -04:00
|
|
|
translate.dispose();
|
|
|
|
});
|
2023-05-23 22:30:24 +03:00
|
|
|
|
|
|
|
it("should support DOMParser", async function () {
|
2025-06-25 10:26:38 -04:00
|
|
|
let dummy = buildDummyTranslator('web', `
|
2023-05-23 22:30:24 +03:00
|
|
|
function detectWeb() {
|
|
|
|
return "book";
|
|
|
|
}
|
|
|
|
|
|
|
|
function doWeb() {
|
|
|
|
let item = new Zotero.Item("book");
|
|
|
|
item.title = new DOMParser().parseFromString("<body>content</body>", "text/html").body.textContent;
|
|
|
|
item.complete();
|
|
|
|
}
|
|
|
|
`);
|
|
|
|
|
|
|
|
let translate = new RemoteTranslate();
|
2023-12-27 11:43:50 +02:00
|
|
|
let browser = new HiddenBrowser();
|
|
|
|
await browser.load(getTestDataUrl('test.html'));
|
2023-05-23 22:30:24 +03:00
|
|
|
await translate.setBrowser(browser);
|
2025-06-25 10:26:38 -04:00
|
|
|
translate.setTranslator(dummy);
|
2023-05-23 22:30:24 +03:00
|
|
|
|
|
|
|
let items = await translate.translate({ libraryID: false });
|
|
|
|
assert.equal(items[0].title, 'content');
|
|
|
|
|
2023-12-27 11:43:50 +02:00
|
|
|
browser.destroy();
|
2023-05-23 22:30:24 +03:00
|
|
|
translate.dispose();
|
|
|
|
});
|
2023-09-20 12:41:09 -04:00
|
|
|
|
|
|
|
it("should be able to access hidden prefs", async function () {
|
2025-06-25 10:26:38 -04:00
|
|
|
let dummy = buildDummyTranslator('web', `
|
2023-09-20 12:41:09 -04:00
|
|
|
function detectWeb() {
|
|
|
|
return "book";
|
|
|
|
}
|
|
|
|
|
|
|
|
function doWeb() {
|
|
|
|
let item = new Zotero.Item("book");
|
|
|
|
item.title = Zotero.getHiddenPref("testPref");
|
|
|
|
item.complete();
|
|
|
|
}
|
|
|
|
`);
|
|
|
|
|
|
|
|
Zotero.Prefs.set('translators.testPref', 'Test value');
|
|
|
|
|
|
|
|
let translate = new RemoteTranslate();
|
2023-12-27 11:43:50 +02:00
|
|
|
let browser = new HiddenBrowser();
|
|
|
|
await browser.load(getTestDataUrl('test.html'));
|
2023-09-20 12:41:09 -04:00
|
|
|
await translate.setBrowser(browser);
|
2025-06-25 10:26:38 -04:00
|
|
|
translate.setTranslator(dummy);
|
2023-09-20 12:41:09 -04:00
|
|
|
|
|
|
|
let items = await translate.translate({ libraryID: false });
|
|
|
|
assert.equal(items[0].title, 'Test value');
|
|
|
|
|
2023-12-27 11:43:50 +02:00
|
|
|
browser.destroy();
|
2023-09-20 12:41:09 -04:00
|
|
|
translate.dispose();
|
|
|
|
});
|
2025-06-25 10:26:38 -04:00
|
|
|
|
|
|
|
it("should send cookies", async function () {
|
|
|
|
let dummy = buildDummyTranslator('web', `
|
|
|
|
function detectWeb() {
|
|
|
|
return "book";
|
|
|
|
}
|
|
|
|
|
|
|
|
async function doWeb() {
|
|
|
|
let item = new Zotero.Item("book");
|
|
|
|
item.title = await requestText("http://localhost:${port}/readCookie", {
|
|
|
|
headers: { Cookie: "sessionID=1" },
|
|
|
|
});
|
|
|
|
item.complete();
|
|
|
|
}
|
|
|
|
`);
|
|
|
|
|
|
|
|
let translate = new RemoteTranslate();
|
|
|
|
let browser = new HiddenBrowser();
|
|
|
|
await browser.load(getTestDataUrl('test.html'));
|
|
|
|
await translate.setBrowser(browser);
|
|
|
|
translate.setTranslator(dummy);
|
|
|
|
|
|
|
|
let items = await translate.translate({ libraryID: false });
|
|
|
|
assert.equal(items[0].title, 'OK');
|
|
|
|
|
|
|
|
browser.destroy();
|
|
|
|
translate.dispose();
|
|
|
|
});
|
2023-04-14 11:37:07 -04:00
|
|
|
});
|
|
|
|
});
|