Spell checker improvements
- Add/Remove Dictionaries window - Better account for the (unlikely) possibility that a dictionary could be replaced by another more popular dictionary provided by a different extension id (tested) - Better account for the (very unlikely) possibility that an extension could bundle multiple dictionaries (untested) - Use toolkit version comparator for proper extension version comparisons - Localize strings - Add tests for updating
This commit is contained in:
parent
7f2296b1fb
commit
9a7016ad64
9 changed files with 583 additions and 85 deletions
193
test/tests/dictionariesTest.js
Normal file
193
test/tests/dictionariesTest.js
Normal file
|
@ -0,0 +1,193 @@
|
|||
"use strict";
|
||||
|
||||
var sandbox = sinon.createSandbox();
|
||||
|
||||
describe("Dictionaries", function () {
|
||||
var win;
|
||||
var enUKXPIOld, frFRv1XPI, unKNXPI, enUKXPINew, frFRv2XPI;
|
||||
|
||||
async function makeFakeDictionary({ id, locale, version }) {
|
||||
var dir = await getTempDirectory();
|
||||
var extDir = OS.Path.join(dir, 'sub');
|
||||
var dictDir = OS.Path.join(extDir, 'dictionaries');
|
||||
await OS.File.makeDir(dictDir, { from: dir });
|
||||
var manifest = {
|
||||
dictionaries: {
|
||||
[locale]: `dictionaries/${locale}.dic`,
|
||||
},
|
||||
version,
|
||||
applications: {
|
||||
gecko: {
|
||||
id
|
||||
}
|
||||
},
|
||||
name,
|
||||
manifest_version: 2
|
||||
};
|
||||
await Zotero.File.putContentsAsync(
|
||||
OS.Path.join(extDir, 'manifest.json'),
|
||||
JSON.stringify(manifest)
|
||||
);
|
||||
await Zotero.File.putContentsAsync(
|
||||
OS.Path.join(dictDir, locale + '.dic'),
|
||||
"1\n0/nm"
|
||||
);
|
||||
var path = OS.Path.join(dir, id + '.xpi');
|
||||
await Zotero.File.zipDirectory(extDir, path);
|
||||
return path;
|
||||
}
|
||||
|
||||
before(async function () {
|
||||
// Make fake installed dictionaries
|
||||
enUKXPIOld = await makeFakeDictionary({
|
||||
id: '@fake-en-UK-dictionary',
|
||||
locale: 'en-UK',
|
||||
version: 5,
|
||||
name: "Fake English UK Dictionary"
|
||||
});
|
||||
frFRv1XPI = await makeFakeDictionary({
|
||||
id: '@fake-fr-FR-dictionary',
|
||||
locale: 'fr-FR',
|
||||
version: 1,
|
||||
name: "Fake French Dictionary"
|
||||
});
|
||||
unKNXPI = await makeFakeDictionary({
|
||||
id: '@fake-unknown-dictionary',
|
||||
locale: 'xx-UN',
|
||||
version: 5,
|
||||
name: "Fake Unknown Dictionary"
|
||||
});
|
||||
// Make fake updated dictionaries
|
||||
enUKXPINew = await makeFakeDictionary({
|
||||
id: '@another-fake-en-UK-dictionary',
|
||||
locale: 'en-UK',
|
||||
version: 1,
|
||||
name: "Another Fake English UK Dictionary"
|
||||
});
|
||||
frFRv2XPI = await makeFakeDictionary({
|
||||
id: '@fake-fr-FR-dictionary',
|
||||
locale: 'fr-FR',
|
||||
version: 2,
|
||||
name: "Fake French Dictionary"
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(async function () {
|
||||
for (let id of Zotero.Dictionaries.dictionaries.map(x => x.id)) {
|
||||
await Zotero.Dictionaries.remove(id);
|
||||
}
|
||||
|
||||
sandbox.stub(Zotero.File, 'download').callsFake(async (url, downloadPath) => {
|
||||
if (url.includes('en-UK')) {
|
||||
return OS.File.copy(enUKXPIOld, downloadPath);
|
||||
}
|
||||
if (url.includes('fr-FR')) {
|
||||
return OS.File.copy(frFRv1XPI, downloadPath);
|
||||
}
|
||||
if (url.includes('xx-UN')) {
|
||||
return OS.File.copy(unKNXPI, downloadPath);
|
||||
}
|
||||
throw new Error("Unexpected URL " + url);
|
||||
});
|
||||
await Zotero.Dictionaries.install('@fake-en-UK-dictionary');
|
||||
await Zotero.Dictionaries.install('@fake-fr-FR-dictionary');
|
||||
await Zotero.Dictionaries.install('@fake-xx-UN-dictionary');
|
||||
sandbox.restore();
|
||||
|
||||
// Create metadata response for available dictionaries
|
||||
sandbox.stub(Zotero.Dictionaries, 'fetchDictionariesList')
|
||||
.resolves([
|
||||
{
|
||||
id: '@another-fake-en-UK-dictionary',
|
||||
locale: 'en-UK',
|
||||
name: "English (UK)",
|
||||
version: 1
|
||||
},
|
||||
{
|
||||
id: '@fake-fr-FR-dictionary',
|
||||
locale: 'fr-FR',
|
||||
name: "Français",
|
||||
version: 2
|
||||
}
|
||||
]);
|
||||
|
||||
sandbox.stub(Zotero.File, 'download').callsFake(async (url, downloadPath) => {
|
||||
if (url.includes('en-UK')) {
|
||||
return OS.File.copy(enUKXPINew, downloadPath);
|
||||
}
|
||||
if (url.includes('fr-FR')) {
|
||||
return OS.File.copy(frFRv2XPI, downloadPath);
|
||||
}
|
||||
throw new Error("Unexpected URL " + url);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe("Zotero.Dictionaries", function () {
|
||||
describe("#update()", function () {
|
||||
it("should update outdated dictionary and replace an installed dictionary with a new one with a different id", async function () {
|
||||
var numDictionaries = Zotero.Dictionaries.dictionaries.length;
|
||||
function updated() {
|
||||
return !!(
|
||||
!Zotero.Dictionaries.dictionaries.find(x => x.id == '@fake-en-UK-dictionary')
|
||||
&& Zotero.Dictionaries.dictionaries.find(x => x.id == '@another-fake-en-UK-dictionary')
|
||||
// Version update happens too
|
||||
&& !Zotero.Dictionaries.dictionaries.find(x => x.id == '@fake-fr-FR-dictionary' && x.version == 1)
|
||||
&& Zotero.Dictionaries.dictionaries.find(x => x.id == '@fake-fr-FR-dictionary' && x.version == 2)
|
||||
);
|
||||
}
|
||||
assert.isFalse(updated());
|
||||
await Zotero.Dictionaries.update();
|
||||
assert.isTrue(updated());
|
||||
assert.lengthOf(Zotero.Dictionaries.dictionaries, numDictionaries);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Dictionary Manager", function () {
|
||||
beforeEach(async function () {
|
||||
win = Services.ww.openWindow(
|
||||
null,
|
||||
'chrome://zotero/content/dictionaryManager.xul',
|
||||
'dictionary-manager',
|
||||
'chrome,centerscreen',
|
||||
{}
|
||||
);
|
||||
while (!win.document.querySelectorAll('input[type="checkbox"]').length) {
|
||||
await Zotero.Promise.delay(50);
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
win.close();
|
||||
});
|
||||
|
||||
it("should show unknown dictionary as installed", async function () {
|
||||
var elems = win.document.querySelectorAll('input[type="checkbox"]');
|
||||
var names = [...elems].map(elem => elem.dataset.dictName);
|
||||
assert.sameMembers(names, ['English (UK)', 'Français', 'xx (UN)']);
|
||||
});
|
||||
|
||||
it("should update outdated dictionary and replace an installed dictionary with a new one with a different id", async function () {
|
||||
var numDictionaries = Zotero.Dictionaries.dictionaries.length;
|
||||
function updated() {
|
||||
return !!(
|
||||
!Zotero.Dictionaries.dictionaries.find(x => x.id == '@fake-en-UK-dictionary')
|
||||
&& Zotero.Dictionaries.dictionaries.find(x => x.id == '@another-fake-en-UK-dictionary')
|
||||
// Version update happens too
|
||||
&& !Zotero.Dictionaries.dictionaries.find(x => x.id == '@fake-fr-FR-dictionary' && x.version == 1)
|
||||
&& Zotero.Dictionaries.dictionaries.find(x => x.id == '@fake-fr-FR-dictionary' && x.version == 2)
|
||||
);
|
||||
}
|
||||
assert.isFalse(updated());
|
||||
win.document.querySelector('button[dlgtype="accept"]').click();
|
||||
while (!updated()) {
|
||||
await Zotero.Promise.delay(50);
|
||||
}
|
||||
assert.lengthOf(Zotero.Dictionaries.dictionaries, numDictionaries);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue