Handle additional cases of conflicting translators

And fix test failure from bde9a74f9d in CI, where the file list order is
different
This commit is contained in:
Dan Stillman 2021-06-26 18:23:11 -04:00
parent 06075a25c0
commit fdcd4e51c5
2 changed files with 56 additions and 33 deletions

View file

@ -161,7 +161,7 @@ Zotero.Translators = new function() {
// Check if there's already a cached translator with the same id // Check if there's already a cached translator with the same id
if (_translators[translator.translatorID]) { if (_translators[translator.translatorID]) {
let existingTranslator = _translators[translator.translatorID]; let existingTranslator = _translators[translator.translatorID];
// If cached translator is older, delete it // If cached translator is older, delete it and install this one
if (existingTranslator.lastUpdated < translator.lastUpdated) { if (existingTranslator.lastUpdated < translator.lastUpdated) {
translator.logError("Deleting older translator " translator.logError("Deleting older translator "
+ existingTranslator.fileName + " with same ID as " + existingTranslator.fileName + " with same ID as "
@ -169,15 +169,33 @@ Zotero.Translators = new function() {
yield OS.File.remove(existingTranslator.path); yield OS.File.remove(existingTranslator.path);
yield removeFromCaches(existingTranslator); yield removeFromCaches(existingTranslator);
} }
// If cached translator is newer or the same, delete the current one // If cached translator is newer, keep it and discard this one
else { else if (existingTranslator.lastUpdated > translator.lastUpdated) {
translator.logError("Deleting older translator "
+ translator.fileName + " with same ID as "
+ existingTranslator.fileName);
yield OS.File.remove(translator.path);
yield removeFromDBCache(translator.fileName);
continue;
}
// If cached translator has the same timestamp and matches the label, keep
// it and discard this one
else if (this.getFileNameFromLabel(existingTranslator.label) == existingTranslator.fileName) {
translator.logError("Translator " + existingTranslator.fileName translator.logError("Translator " + existingTranslator.fileName
+ " with same ID is already loaded -- deleting " + " with same ID is already loaded and matches label -- deleting "
+ translator.fileName); + translator.fileName);
yield OS.File.remove(translator.path); yield OS.File.remove(translator.path);
yield removeFromDBCache(translator.fileName); yield removeFromDBCache(translator.fileName);
continue; continue;
} }
// Otherwise delete the cached one and install this one
else {
translator.logError("Deleting translator " + translator.fileName
+ " with same ID as " + existingTranslator.fileName + " but with "
+ "mismatched filename");
yield OS.File.remove(existingTranslator.path);
yield removeFromCaches(existingTranslator);
}
} }
// add to cache // add to cache

View file

@ -1,75 +1,80 @@
"use strict"; "use strict";
describe("Zotero.Translators", function () { describe.only("Zotero.Translators", function () {
describe("#init()", function () { describe("#init()", function () {
async function testUpdateCache({ translatorID, oldLabel, newLabel, oldLastUpdated, newLastUpdated }) { async function testUpdateCache({ translatorID, label1, label2, lastUpdated1, lastUpdated2, expect }) {
var oldTranslator = buildDummyTranslator('web', `function doDetect() {}; function doSearch(); {}`, { var translator1 = buildDummyTranslator('web', `function doDetect() {}; function doSearch(); {}`, {
label: oldLabel, label: label1,
translatorID, translatorID,
translatorType: 8, translatorType: 8,
lastUpdated: oldLastUpdated lastUpdated: lastUpdated1
}); });
await Zotero.Translators.save(oldTranslator.metadata, oldTranslator.code); await Zotero.Translators.save(translator1.metadata, translator1.code);
await Zotero.Translators.reinit(); await Zotero.Translators.reinit();
var matched = (await Zotero.Translators.getAllForType('search')) var matched = (await Zotero.Translators.getAllForType('search'))
.filter(x => x.translatorID == translatorID); .filter(x => x.translatorID == translatorID);
assert.lengthOf(matched, 1); assert.lengthOf(matched, 1);
assert.equal(matched[0].label, oldLabel); assert.equal(matched[0].label, label1);
var oldPath = matched[0].path; var path1 = matched[0].path;
assert.isTrue(await OS.File.exists(oldPath)); assert.isTrue(await OS.File.exists(path1));
var rows = await Zotero.DB.valueQueryAsync( var rows = await Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM translatorCache WHERE fileName=?", "SELECT COUNT(*) FROM translatorCache WHERE fileName=?",
oldTranslator.label + ".js" translator1.label + ".js"
); );
assert.equal(rows, 1); assert.equal(rows, 1);
var newTranslator = buildDummyTranslator('web', `function doDetect() {}; function doSearch(); {}`, { var translator2 = buildDummyTranslator('web', `function doDetect() {}; function doSearch(); {}`, {
label: newLabel, label: label2,
translatorID, translatorID,
translatorType: 8, translatorType: 8,
lastUpdated: newLastUpdated lastUpdated: lastUpdated2
}); });
await Zotero.Translators.save(newTranslator.metadata, newTranslator.code); await Zotero.Translators.save(translator2.metadata, translator2.code);
await Zotero.Translators.reinit(); await Zotero.Translators.reinit();
matched = (await Zotero.Translators.getAllForType('search')) matched = (await Zotero.Translators.getAllForType('search'))
.filter(x => x.translatorID == translatorID); .filter(x => x.translatorID == translatorID);
assert.lengthOf(matched, 1); assert.lengthOf(matched, 1);
assert.equal(matched[0].label, newLabel); assert.equal(matched[0].label, expect == 1 ? label1 : label2);
assert.isFalse(await OS.File.exists(oldPath)); // If keeping the second translator, make sure the first one was deleted
if (expect == 2) {
assert.isFalse(await OS.File.exists(path1));
}
assert.isTrue(await OS.File.exists(matched[0].path)); assert.isTrue(await OS.File.exists(matched[0].path));
rows = await Zotero.DB.valueQueryAsync( rows = await Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM translatorCache WHERE fileName=?", "SELECT COUNT(*) FROM translatorCache WHERE fileName=?",
oldTranslator.label + ".js" (expect == 1 ? translator2.label : translator1.label) + ".js"
); );
assert.equal(rows, 0); assert.equal(rows, 0);
rows = await Zotero.DB.valueQueryAsync( rows = await Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM translatorCache WHERE fileName=?", "SELECT COUNT(*) FROM translatorCache WHERE fileName=?",
newTranslator.label + ".js" (expect == 1 ? translator1.label : translator2.label) + ".js"
); );
assert.equal(rows, 1); assert.equal(rows, 1);
} }
it("should update cache when deleting old translator with same id", async function () { it("should delete older translator with same id", async function () {
await testUpdateCache({ await testUpdateCache({
translatorID: 'f678741b-b82d-48a3-a7c2-26764d08cc34', translatorID: 'f678741b-b82d-48a3-a7c2-26764d08cc34',
oldLabel: 'Old Test Translator', label1: 'Test Translator A 1',
newLabel: 'New Test Translator', label2: 'Test Translator A 2',
oldLastUpdated: '2021-06-25 00:00:00', lastUpdated1: '2021-06-25 00:00:00',
newLastUpdated: '2021-06-25 00:05:00', lastUpdated2: '2021-06-25 00:05:00',
expect: 2
}); });
}); });
it("should update cache when deleting second translator with same id and timestamp", async function () { it("should delete newer translator with same id", async function () {
await testUpdateCache({ await testUpdateCache({
translatorID: '4bff4da8-b3f6-47dc-957a-dcb96dc48d4f', translatorID: 'abd90f38-0900-4952-9935-3938933699b9',
oldLabel: 'Old Test Translator 2', label1: 'Test Translator B 1',
newLabel: 'New Test Translator 2', label2: 'Test Translator B 2',
oldLastUpdated: '2021-06-25 00:00:00', lastUpdated1: '2021-06-25 00:05:00',
newLastUpdated: '2021-06-25 00:00:00', lastUpdated2: '2021-06-25 00:00:00',
expect: 1
}); });
}); });
}); });