Asyncify/ESMify tests

They seem to be succeeding when run individually, but failing when
run as a whole. Not sure why yet.
This commit is contained in:
Abe Jellinek 2025-07-11 10:25:06 -04:00
parent aaee272c41
commit e31d8bca44
77 changed files with 3824 additions and 3840 deletions

View file

@ -23,7 +23,8 @@
***** END LICENSE BLOCK *****
*/
Components.utils.import("resource://gre/modules/ComponentUtils.jsm");
const { ComponentUtils } = ChromeUtils.importESModule("resource://gre/modules/ComponentUtils.sys.mjs");
function ZoteroUnit() {
this.wrappedJSObject = this;

View file

@ -1,5 +1,6 @@
var { FileUtils } = ChromeUtils.importESModule("resource://gre/modules/FileUtils.sys.mjs");
var { ZOTERO_CONFIG } = ChromeUtils.importESModule('resource://zotero/config.mjs');
var { Zotero } = ChromeUtils.importESModule("chrome://zotero/content/zotero.mjs");
var { TestOptions } = ChromeUtils.importESModule("chrome://zotero/content/modules/commandLineOptions.mjs");
var { OS } = ChromeUtils.importESModule("chrome://zotero/content/osfile.mjs");
@ -51,8 +52,8 @@ if (TestOptions.makeTestData) {
args: [false]
}
];
Zotero.Promise.coroutine(function* () {
yield Zotero.initializationPromise;
(async function () {
await Zotero.initializationPromise;
for (let i=0; i<dataFiles.length; i++) {
let first = !i;
let params = dataFiles[i];
@ -62,7 +63,7 @@ if (TestOptions.makeTestData) {
dump('Generating data for ' + params.name + '...');
let filePath = PathUtils.join(dataPath, params.name + '.js');
let exists = yield IOUtils.exists(filePath);
let exists = await IOUtils.exists(filePath);
let currentData;
if (exists) {
currentData = loadSampleData(params.name);
@ -71,12 +72,12 @@ if (TestOptions.makeTestData) {
let args = params.args || [];
args.push(currentData);
let newData = params.func.apply(null, args);
if (newData instanceof Zotero.Promise) {
newData = yield newData;
if (newData instanceof Promise) {
newData = await newData;
}
let str = stableStringify(newData);
yield IOUtils.writeUTF8(PathUtils.join(dataPath, params.name + '.js'), str);
await IOUtils.writeUTF8(PathUtils.join(dataPath, params.name + '.js'), str);
dump('\nWritten to ' + PathUtils.join(dataPath, params.name + '.js\n'));
}
dump("\n");
@ -169,7 +170,6 @@ coMocha(Mocha);
before(function () {
// Store all prefs set in runtests.sh
Components.utils.import("resource://zotero/config.js");
var prefBranch = Services.prefs.getBranch(ZOTERO_CONFIG.PREF_BRANCH);
TestOptions.customPrefs = {};
prefBranch.getChildList("", {})
@ -181,7 +181,6 @@ before(function () {
* Clear all prefs, and reset those set in runtests.sh to original values
*/
function resetPrefs() {
Components.utils.import("resource://zotero/config.js");
var prefBranch = Services.prefs.getBranch(ZOTERO_CONFIG.PREF_BRANCH);
prefBranch.getChildList("", {}).forEach(key => {
var origVal = TestOptions.customPrefs[key];

View file

@ -192,7 +192,7 @@ function waitForWindow(uri, callback) {
* @return {Promise}
*/
function waitForDialog(onOpen, button='accept', url) {
return waitForWindow(url || "chrome://global/content/commonDialog.xhtml", Zotero.Promise.method(function (win) {
return waitForWindow(url || "chrome://global/content/commonDialog.xhtml", function (win) {
var dialog = win.document.querySelector('dialog');
var failure = false;
if (onOpen) {
@ -236,7 +236,7 @@ function waitForDialog(onOpen, button='accept', url) {
throw failure;
}
}
}))
});
}
async function select(win, object) {
@ -278,16 +278,16 @@ async function selectTrash(win, libraryID = Zotero.Libraries.userLibraryID) {
await waitForItemsLoad(win);
}
var waitForItemsLoad = Zotero.Promise.coroutine(function* (win, collectionRowToSelect) {
var waitForItemsLoad = async function (win, collectionRowToSelect) {
var zp = win.ZoteroPane;
var cv = zp.collectionsView;
yield cv.waitForLoad();
await cv.waitForLoad();
if (collectionRowToSelect !== undefined) {
yield cv.selectWait(collectionRowToSelect);
await cv.selectWait(collectionRowToSelect);
}
yield zp.itemsView.waitForLoad();
});
await zp.itemsView.waitForLoad();
};
/**
* Return a promise that resolves once the tag selector has updated
@ -303,7 +303,7 @@ var waitForTagSelector = function (win, numUpdates = 1) {
if (zp.tagSelectorShown()) {
let tagSelector = zp.tagSelector;
let componentDidUpdate = tagSelector.componentDidUpdate;
tagSelector.componentDidUpdate = function() {
tagSelector.componentDidUpdate = function () {
updates++;
if (updates == numUpdates) {
deferred.resolve();
@ -341,7 +341,7 @@ function waitForNotifierEvent(event, type) {
if (!event) throw new Error("event not provided");
var deferred = Zotero.Promise.defer();
var notifierID = Zotero.Notifier.registerObserver({notify:function(ev, type, ids, extraData) {
var notifierID = Zotero.Notifier.registerObserver({notify:function (ev, type, ids, extraData) {
if(ev == event) {
Zotero.Notifier.unregisterObserver(notifierID);
deferred.resolve({
@ -460,7 +460,7 @@ function gunzip(gzdata) {
* Get a default group used by all tests that want one, creating one if necessary
*/
var _defaultGroup;
var getGroup = Zotero.Promise.method(function () {
var getGroup = function () {
// Cleared in resetDB()
if (_defaultGroup) {
return _defaultGroup;
@ -468,14 +468,14 @@ var getGroup = Zotero.Promise.method(function () {
return _defaultGroup = createGroup({
name: "My Group"
});
});
};
var createGroup = Zotero.Promise.coroutine(function* (props = {}) {
var createGroup = async function (props = {}) {
// Create a group item requires the current user to be set
if (!Zotero.Users.getCurrentUserID()) {
yield Zotero.Users.setCurrentUserID(1);
yield Zotero.Users.setName(1, 'Name');
await Zotero.Users.setCurrentUserID(1);
await Zotero.Users.setName(1, 'Name');
}
var group = new Zotero.Group;
@ -489,11 +489,11 @@ var createGroup = Zotero.Promise.coroutine(function* (props = {}) {
group.libraryVersion = props.libraryVersion;
}
group.archived = props.archived === undefined ? false : props.archived;
yield group.saveTx();
await group.saveTx();
return group;
});
};
var createFeed = Zotero.Promise.coroutine(function* (props = {}) {
var createFeed = async function (props = {}) {
var feed = new Zotero.Feed;
feed.name = props.name || "Test " + Zotero.Utilities.randomString();
feed.description = props.description || "";
@ -501,16 +501,16 @@ var createFeed = Zotero.Promise.coroutine(function* (props = {}) {
feed.refreshInterval = props.refreshInterval || 12;
feed.cleanupReadAfter = props.cleanupReadAfter || 2;
feed.cleanupUnreadAfter = props.cleanupUnreadAfter || 30;
yield feed.saveTx(props.saveOptions);
await feed.saveTx(props.saveOptions);
return feed;
});
};
var clearFeeds = Zotero.Promise.coroutine(function* () {
var clearFeeds = async function () {
let feeds = Zotero.Feeds.getAll();
for (let i=0; i<feeds.length; i++) {
yield feeds[i].eraseTx();
await feeds[i].eraseTx();
}
});
};
//
// Data objects
@ -659,14 +659,14 @@ function getTestDataUrl(path) {
/**
* Returns an absolute path to an empty temporary directory
*/
var getTempDirectory = Zotero.Promise.coroutine(function* getTempDirectory() {
var getTempDirectory = async function getTempDirectory() {
let path,
attempts = 3,
zoteroTmpDirPath = Zotero.getTempDirectory().path;
while (attempts--) {
path = PathUtils.join(zoteroTmpDirPath, Zotero.Utilities.randomString());
try {
yield IOUtils.makeDirectory(path, { ignoreExisting: false });
await IOUtils.makeDirectory(path, { ignoreExisting: false });
break;
} catch (e) {
if (!attempts) throw e; // Throw on last attempt
@ -674,9 +674,9 @@ var getTempDirectory = Zotero.Promise.coroutine(function* getTempDirectory() {
}
return path;
});
};
var removeDir = Zotero.Promise.coroutine(function* (dir) {
var removeDir = async function (dir) {
// OS.File.DirectoryIterator, used by OS.File.removeDir(), isn't reliable on Travis,
// returning entry.isDir == false for subdirectories, so use nsIFile instead
//yield OS.File.removeDir(zipDir);
@ -684,7 +684,7 @@ var removeDir = Zotero.Promise.coroutine(function* (dir) {
if (dir.exists()) {
dir.remove(true);
}
});
};
/**
* Resets the Zotero DB and restarts Zotero. Returns a promise resolved
@ -849,12 +849,12 @@ function populateDBWithSampleData(data) {
});
}
var generateItemJSONData = Zotero.Promise.coroutine(function* generateItemJSONData(options, currentData) {
let items = yield populateDBWithSampleData(loadSampleData('allTypesAndFields')),
var generateItemJSONData = async function generateItemJSONData(options, currentData) {
let items = await populateDBWithSampleData(loadSampleData('allTypesAndFields')),
jsonData = {};
for (let itemName in items) {
let zItem = yield Zotero.Items.getAsync(items[itemName].id);
let zItem = await Zotero.Items.getAsync(items[itemName].id);
jsonData[itemName] = zItem.toJSON(options || {});
// Don't replace some fields that _always_ change (e.g. item keys)
@ -884,14 +884,14 @@ var generateItemJSONData = Zotero.Promise.coroutine(function* generateItemJSONDa
}
return jsonData;
});
};
var generateCiteProcJSExportData = Zotero.Promise.coroutine(function* generateCiteProcJSExportData(currentData) {
let items = yield populateDBWithSampleData(loadSampleData('allTypesAndFields')),
var generateCiteProcJSExportData = async function generateCiteProcJSExportData(currentData) {
let items = await populateDBWithSampleData(loadSampleData('allTypesAndFields')),
cslExportData = {};
for (let itemName in items) {
let zItem = yield Zotero.Items.getAsync(items[itemName].id);
let zItem = await Zotero.Items.getAsync(items[itemName].id);
cslExportData[itemName] = Zotero.Cite.System.prototype.retrieveItem(zItem);
if (!currentData || !currentData[itemName]) continue;
@ -905,17 +905,17 @@ var generateCiteProcJSExportData = Zotero.Promise.coroutine(function* generateCi
}
return cslExportData;
});
};
var generateTranslatorExportData = Zotero.Promise.coroutine(function* generateTranslatorExportData(legacy, currentData) {
let items = yield populateDBWithSampleData(loadSampleData('allTypesAndFields')),
var generateTranslatorExportData = async function generateTranslatorExportData(legacy, currentData) {
let items = await populateDBWithSampleData(loadSampleData('allTypesAndFields')),
translatorExportData = {};
let itemGetter = new Zotero.Translate.ItemGetter();
itemGetter.legacy = !!legacy;
for (let itemName in items) {
let zItem = yield Zotero.Items.getAsync(items[itemName].id);
let zItem = await Zotero.Items.getAsync(items[itemName].id);
itemGetter._itemsLeft = [zItem];
translatorExportData[itemName] = itemGetter.nextItem();
@ -957,7 +957,7 @@ var generateTranslatorExportData = Zotero.Promise.coroutine(function* generateTr
}
return translatorExportData;
});
};
/**

View file

@ -67,13 +67,13 @@ describe("Advanced Search", function () {
});
describe("Collection", function () {
it("should show collections and saved searches", function* () {
var col1 = yield createDataObject('collection', { name: "A" });
var col2 = yield createDataObject('collection', { name: "C", parentID: col1.id });
var col3 = yield createDataObject('collection', { name: "D", parentID: col2.id });
var col4 = yield createDataObject('collection', { name: "B" });
var search1 = yield createDataObject('search', { name: "A" });
var search2 = yield createDataObject('search', { name: "B" });
it("should show collections and saved searches", async function () {
var col1 = await createDataObject('collection', { name: "A" });
var col2 = await createDataObject('collection', { name: "C", parentID: col1.id });
var col3 = await createDataObject('collection', { name: "D", parentID: col2.id });
var col4 = await createDataObject('collection', { name: "B" });
var search1 = await createDataObject('search', { name: "A" });
var search2 = await createDataObject('search', { name: "B" });
// Add condition
var s = new Zotero.Search();
@ -109,12 +109,12 @@ describe("Advanced Search", function () {
assert.equal(valueMenuItem.getAttribute('label'), search2.name);
assert.equal(valueMenuItem.getAttribute('value'), "S" + search2.key);
yield Zotero.Collections.erase([col1.id, col2.id, col3.id, col4.id]);
yield Zotero.Searches.erase([search1.id, search2.id]);
await Zotero.Collections.erase([col1.id, col2.id, col3.id, col4.id]);
await Zotero.Searches.erase([search1.id, search2.id]);
});
it("should be selected for 'savedSearch' condition", function* () {
var search = yield createDataObject('search', { name: "A" });
it("should be selected for 'savedSearch' condition", async function () {
var search = await createDataObject('search', { name: "A" });
var s = new Zotero.Search();
s.addCondition('savedSearch', 'is', search.key);
@ -128,12 +128,12 @@ describe("Advanced Search", function () {
assert.isFalse(valueMenu.hidden);
assert.equal(valueMenu.selectedItem.value, "S" + search.key);
yield search.eraseTx();
await search.eraseTx();
});
it("should set 'savedSearch' condition when a search is selected", function* () {
var collection = yield createDataObject('collection', { name: "A" });
var search = yield createDataObject('search', { name: "B" });
it("should set 'savedSearch' condition when a search is selected", async function () {
var collection = await createDataObject('collection', { name: "A" });
var search = await createDataObject('search', { name: "B" });
var s = new Zotero.Search();
s.addCondition('title', 'is', '');
@ -164,18 +164,18 @@ describe("Advanced Search", function () {
assert.equal(condition.condition, 'savedSearch');
assert.equal(condition.value, search.key);
yield collection.eraseTx();
yield search.eraseTx();
await collection.eraseTx();
await search.eraseTx();
});
it("should update when the library is changed", function* () {
var group = yield getGroup();
it("should update when the library is changed", async function () {
var group = await getGroup();
var groupLibraryID = group.libraryID;
var collection1 = yield createDataObject('collection', { name: "A" });
var search1 = yield createDataObject('search', { name: "B" });
var collection2 = yield createDataObject('collection', { name: "C", libraryID: groupLibraryID });
var search2 = yield createDataObject('search', { name: "D", libraryID: groupLibraryID });
var collection1 = await createDataObject('collection', { name: "A" });
var search1 = await createDataObject('search', { name: "B" });
var collection2 = await createDataObject('collection', { name: "C", libraryID: groupLibraryID });
var search2 = await createDataObject('search', { name: "D", libraryID: groupLibraryID });
var s = new Zotero.Search();
s.addCondition('title', 'is', '');
@ -224,13 +224,13 @@ describe("Advanced Search", function () {
assert.include(values, "C" + collection2.key);
assert.include(values, "S" + search2.key);
yield Zotero.Collections.erase([collection1.id, collection2.id]);
yield Zotero.Searches.erase([search1.id, search2.id]);
await Zotero.Collections.erase([collection1.id, collection2.id]);
await Zotero.Searches.erase([search1.id, search2.id]);
});
});
describe("Saved Search", function () {
it("shouldn't appear", function* () {
it("shouldn't appear", async function () {
var searchCondition = conditions.firstChild;
var conditionsMenu = searchCondition.querySelector('#conditionsmenu');

View file

@ -1,4 +1,4 @@
describe("Zotero.Attachments", function() {
describe("Zotero.Attachments", function () {
var HiddenBrowser;
var browser;
@ -14,83 +14,83 @@ describe("Zotero.Attachments", function() {
});
describe("#importFromFile()", function () {
it("should create a child attachment from a text file", function* () {
it("should create a child attachment from a text file", async function () {
// Create test file
var contents = "Test";
var tmpFile = Zotero.getTempDirectory();
tmpFile.append('test.txt');
yield Zotero.File.putContentsAsync(tmpFile, contents);
await Zotero.File.putContentsAsync(tmpFile, contents);
// Create parent item
var item = new Zotero.Item('book');
var parentItemID = yield item.saveTx();
var parentItemID = await item.saveTx();
// Create attachment and compare content
var item = yield Zotero.Attachments.importFromFile({
var item = await Zotero.Attachments.importFromFile({
file: tmpFile,
parentItemID: parentItemID
});
var storedFile = item.getFile();
assert.equal((yield Zotero.File.getContentsAsync(storedFile)), contents);
assert.equal(((await Zotero.File.getContentsAsync(storedFile))), contents);
// Clean up
yield Zotero.Items.erase(item.id);
await Zotero.Items.erase(item.id);
});
it("should create a top-level attachment from a PNG file", function* () {
it("should create a top-level attachment from a PNG file", async function () {
var file = getTestDataDirectory();
file.append('test.png');
var contents = yield Zotero.File.getBinaryContentsAsync(file);
var contents = await Zotero.File.getBinaryContentsAsync(file);
// Create attachment and compare content
var item = yield Zotero.Attachments.importFromFile({
var item = await Zotero.Attachments.importFromFile({
file: file
});
var storedFile = item.getFile();
assert.equal((yield Zotero.File.getBinaryContentsAsync(storedFile)), contents);
assert.equal(((await Zotero.File.getBinaryContentsAsync(storedFile))), contents);
// Clean up
yield Zotero.Items.erase(item.id);
await Zotero.Items.erase(item.id);
});
it("should create a top-level attachment from a PNG file in a collection", function* () {
it("should create a top-level attachment from a PNG file in a collection", async function () {
var file = getTestDataDirectory();
file.append('test.png');
var contents = yield Zotero.File.getBinaryContentsAsync(file);
var contents = await Zotero.File.getBinaryContentsAsync(file);
var collection = yield createDataObject('collection');
var collection = await createDataObject('collection');
// Create attachment and compare content
var item = yield Zotero.Attachments.importFromFile({
var item = await Zotero.Attachments.importFromFile({
file: file,
collections: [collection.id]
});
var storedFile = item.getFile();
assert.equal((yield Zotero.File.getBinaryContentsAsync(storedFile)), contents);
assert.equal(((await Zotero.File.getBinaryContentsAsync(storedFile))), contents);
// Clean up
yield Zotero.Items.erase(item.id);
await Zotero.Items.erase(item.id);
});
it("should create a child attachment from a PNG file", function* () {
it("should create a child attachment from a PNG file", async function () {
var file = getTestDataDirectory();
file.append('test.png');
var contents = yield Zotero.File.getBinaryContentsAsync(file);
var contents = await Zotero.File.getBinaryContentsAsync(file);
// Create parent item
var item = new Zotero.Item('book');
var parentItemID = yield item.saveTx();
var parentItemID = await item.saveTx();
// Create attachment and compare content
var item = yield Zotero.Attachments.importFromFile({
var item = await Zotero.Attachments.importFromFile({
file: file,
parentItemID: parentItemID
});
var storedFile = item.getFile();
assert.equal((yield Zotero.File.getBinaryContentsAsync(storedFile)), contents);
assert.equal(((await Zotero.File.getBinaryContentsAsync(storedFile))), contents);
// Clean up
yield Zotero.Items.erase(item.id);
await Zotero.Items.erase(item.id);
});
it("should set a top-level item's title to the filename, minus its extension", async function () {
@ -117,12 +117,12 @@ describe("Zotero.Attachments", function() {
})
describe("#linkFromFile()", function () {
it("should link to a file in My Library", function* () {
var item = yield createDataObject('item');
it("should link to a file in My Library", async function () {
var item = await createDataObject('item');
var file = getTestDataDirectory();
file.append('test.png');
var attachment = yield Zotero.Attachments.linkFromFile({
var attachment = await Zotero.Attachments.linkFromFile({
file: file,
parentItemID: item.id
});
@ -267,11 +267,11 @@ describe("Zotero.Attachments", function() {
describe("#importSnapshotFromFile()", function () {
it("should import an HTML file", function* () {
var item = yield createDataObject('item');
it("should import an HTML file", async function () {
var item = await createDataObject('item');
var file = getTestDataDirectory();
file.append('test.html');
var attachment = yield Zotero.Attachments.importSnapshotFromFile({
var attachment = await Zotero.Attachments.importSnapshotFromFile({
title: 'Snapshot',
url: 'http://example.com',
file,
@ -280,16 +280,16 @@ describe("Zotero.Attachments", function() {
charset: 'utf-8'
});
var matches = yield Zotero.Fulltext.findTextInItems([attachment.id], 'test');
var matches = await Zotero.Fulltext.findTextInItems([attachment.id], 'test');
assert.lengthOf(matches, 1);
assert.propertyVal(matches[0], 'id', attachment.id);
});
it("should detect charset for an HTML file", function* () {
var item = yield createDataObject('item');
it("should detect charset for an HTML file", async function () {
var item = await createDataObject('item');
var file = getTestDataDirectory();
file.append('test.html');
var attachment = yield Zotero.Attachments.importSnapshotFromFile({
var attachment = await Zotero.Attachments.importSnapshotFromFile({
title: 'Snapshot',
url: 'http://example.com',
file,
@ -299,7 +299,7 @@ describe("Zotero.Attachments", function() {
assert.equal(attachment.attachmentCharset, 'utf-8');
var matches = yield Zotero.Fulltext.findTextInItems([attachment.id], 'test');
var matches = await Zotero.Fulltext.findTextInItems([attachment.id], 'test');
assert.lengthOf(matches, 1);
assert.propertyVal(matches[0], 'id', attachment.id);
});
@ -350,31 +350,31 @@ describe("Zotero.Attachments", function() {
describe("#linkFromDocument", function () {
it("should add a link attachment for the current webpage", function* () {
var item = yield createDataObject('item');
it("should add a link attachment for the current webpage", async function () {
var item = await createDataObject('item');
var uri = OS.Path.join(getTestDataDirectory().path, "snapshot", "index.html");
browser = new HiddenBrowser(uri);
yield browser.load(uri);
await browser.load(uri);
var file = getTestDataDirectory();
file.append('test.png');
var attachment = yield Zotero.Attachments.linkFromDocument({
document: yield browser.getDocument(),
var attachment = await Zotero.Attachments.linkFromDocument({
document: await browser.getDocument(),
parentItemID: item.id
});
assert.equal(attachment.getField('url'), "file://" + uri);
// Check indexing
var matches = yield Zotero.Fulltext.findTextInItems([attachment.id], 'share your research');
var matches = await Zotero.Fulltext.findTextInItems([attachment.id], 'share your research');
assert.lengthOf(matches, 1);
assert.propertyVal(matches[0], 'id', attachment.id);
})
})
describe("#importFromDocument()", function () {
Components.utils.import("resource://gre/modules/FileUtils.jsm");
ChromeUtils.importESModule("resource://gre/modules/FileUtils.sys.mjs");
var testServerPath, httpd, prefix;
var testServerPort;
@ -1937,92 +1937,92 @@ describe("Zotero.Attachments", function() {
});
describe("#getTotalFileSize", function () {
it("should return the size for a single-file attachment", function* () {
it("should return the size for a single-file attachment", async function () {
var file = getTestDataDirectory();
file.append('test.png');
// Create attachment and compare content
var item = yield Zotero.Attachments.importFromFile({
var item = await Zotero.Attachments.importFromFile({
file: file
});
assert.equal((yield Zotero.Attachments.getTotalFileSize(item)), file.fileSize);
assert.equal(((await Zotero.Attachments.getTotalFileSize(item))), file.fileSize);
})
})
describe("#hasMultipleFiles and #getNumFiles()", function () {
it("should return false and 1 for a single file", function* () {
it("should return false and 1 for a single file", async function () {
var file = getTestDataDirectory();
file.append('test.png');
// Create attachment and compare content
var item = yield Zotero.Attachments.importFromFile({
var item = await Zotero.Attachments.importFromFile({
file: file
});
assert.isFalse(yield Zotero.Attachments.hasMultipleFiles(item));
assert.equal((yield Zotero.Attachments.getNumFiles(item)), 1);
assert.isFalse(await Zotero.Attachments.hasMultipleFiles(item));
assert.equal(((await Zotero.Attachments.getNumFiles(item))), 1);
})
it("should return false and 1 for single HTML file with hidden file", function* () {
it("should return false and 1 for single HTML file with hidden file", async function () {
var file = getTestDataDirectory();
file.append('test.html');
// Create attachment and compare content
var item = yield Zotero.Attachments.importFromFile({
var item = await Zotero.Attachments.importFromFile({
file: file
});
var path = OS.Path.join(OS.Path.dirname(item.getFilePath()), '.zotero-ft-cache');
yield Zotero.File.putContentsAsync(path, "");
await Zotero.File.putContentsAsync(path, "");
assert.isFalse(yield Zotero.Attachments.hasMultipleFiles(item));
assert.equal((yield Zotero.Attachments.getNumFiles(item)), 1);
assert.isFalse(await Zotero.Attachments.hasMultipleFiles(item));
assert.equal(((await Zotero.Attachments.getNumFiles(item))), 1);
})
it("should return true and 2 for multiple files", function* () {
it("should return true and 2 for multiple files", async function () {
var file = getTestDataDirectory();
file.append('test.html');
// Create attachment and compare content
var item = yield Zotero.Attachments.importFromFile({
var item = await Zotero.Attachments.importFromFile({
file: file
});
var path = OS.Path.join(OS.Path.dirname(item.getFilePath()), 'test.png');
yield Zotero.File.putContentsAsync(path, "");
await Zotero.File.putContentsAsync(path, "");
assert.isTrue(yield Zotero.Attachments.hasMultipleFiles(item));
assert.equal((yield Zotero.Attachments.getNumFiles(item)), 2);
assert.isTrue(await Zotero.Attachments.hasMultipleFiles(item));
assert.equal(((await Zotero.Attachments.getNumFiles(item))), 2);
})
});
describe("#createDirectoryForItem()", function () {
it("should create missing directory", function* () {
var item = yield importFileAttachment('test.png');
it("should create missing directory", async function () {
var item = await importFileAttachment('test.png');
var path = OS.Path.dirname(item.getFilePath());
yield OS.File.removeDir(path);
yield Zotero.Attachments.createDirectoryForItem(item);
assert.isTrue(yield OS.File.exists(path));
await OS.File.removeDir(path);
await Zotero.Attachments.createDirectoryForItem(item);
assert.isTrue(await OS.File.exists(path));
});
it("should delete all existing files", function* () {
var item = yield importFileAttachment('test.html');
it("should delete all existing files", async function () {
var item = await importFileAttachment('test.html');
var path = OS.Path.dirname(item.getFilePath());
var files = ['a', 'b', 'c', 'd'];
for (let file of files) {
yield Zotero.File.putContentsAsync(OS.Path.join(path, file), file);
await Zotero.File.putContentsAsync(OS.Path.join(path, file), file);
}
yield Zotero.Attachments.createDirectoryForItem(item);
assert.isTrue(yield Zotero.File.directoryIsEmpty(path));
assert.isTrue(yield OS.File.exists(path));
await Zotero.Attachments.createDirectoryForItem(item);
assert.isTrue(await Zotero.File.directoryIsEmpty(path));
assert.isTrue(await OS.File.exists(path));
});
it("should handle empty directory", function* () {
var item = yield importFileAttachment('test.png');
it("should handle empty directory", async function () {
var item = await importFileAttachment('test.png');
var file = item.getFilePath();
var dir = OS.Path.dirname(item.getFilePath());
yield OS.File.remove(file);
yield Zotero.Attachments.createDirectoryForItem(item);
assert.isTrue(yield OS.File.exists(dir));
await OS.File.remove(file);
await Zotero.Attachments.createDirectoryForItem(item);
assert.isTrue(await OS.File.exists(dir));
});
});

View file

@ -13,7 +13,7 @@ describe("Citation Dialog", function () {
getItems() {
return [];
},
allCitedDataLoadedPromise: Zotero.Promise.resolve(),
allCitedDataLoadedPromise: Promise.resolve(),
};
let dialog, win, IOManager, CitationDataManager, SearchHandler;
@ -511,50 +511,50 @@ describe("Citation Dialog", function () {
describe("Helpers.extractLocator", function () {
let locator;
describe("Invalid locators", function () {
it("has no locator label with numeric locator value", function() {
it("has no locator label with numeric locator value", function () {
locator = dialog.Helpers.extractLocator('history of the US 10-15');
assert.isNull(locator);
locator = dialog.Helpers.extractLocator('10-15');
assert.isNull(locator);
});
it("has no locator label with textual locator value", function() {
it("has no locator label with textual locator value", function () {
locator = dialog.Helpers.extractLocator('history of the US "test"');
assert.isNull(locator);
locator = dialog.Helpers.extractLocator('"test"');
assert.isNull(locator);
});
it("has no quotes around textual locator value", function() {
it("has no quotes around textual locator value", function () {
locator = dialog.Helpers.extractLocator('history of the US chapter something');
assert.isNull(locator);
locator = dialog.Helpers.extractLocator('chapter search query');
assert.isNull(locator);
});
it("has no locator value", function() {
it("has no locator value", function () {
locator = dialog.Helpers.extractLocator('history of the US p');
assert.isNull(locator);
locator = dialog.Helpers.extractLocator('page');
assert.isNull(locator);
});
it("has textual locator value that does not follow locator label", function() {
it("has textual locator value that does not follow locator label", function () {
locator = dialog.Helpers.extractLocator('history of the US note blank "testing"');
assert.isNull(locator);
});
it("has numeric locator value that does not follow locator label", function() {
it("has numeric locator value that does not follow locator label", function () {
locator = dialog.Helpers.extractLocator('history of the US p blank 11-12');
assert.isNull(locator);
});
it("has textual locator value not in the end of the string", function() {
it("has textual locator value not in the end of the string", function () {
locator = dialog.Helpers.extractLocator('history of the US chapter "some quotations" some more text');
assert.isNull(locator);
});
it("has numeric locator value not in the end of the string", function() {
it("has numeric locator value not in the end of the string", function () {
locator = dialog.Helpers.extractLocator('history of the US page 10-15 some more text');
assert.isNull(locator);
});

View file

@ -88,7 +88,7 @@ describe("Zotero.CiteprocRs", function () {
creatorType: "author"
}
]);
await Zotero.Promise.all([item1.saveTx(), item2SameLastName.saveTx(), item3.saveTx()]);
await Promise.all([item1.saveTx(), item2SameLastName.saveTx(), item3.saveTx()]);
});
after(function () {

View file

@ -1,64 +1,64 @@
"use strict";
describe("Zotero.Collection", function() {
describe("Zotero.Collection", function () {
describe("#save()", function () {
it("should save a new collection", function* () {
it("should save a new collection", async function () {
var name = "Test";
var collection = new Zotero.Collection;
collection.name = name;
var id = yield collection.saveTx();
var id = await collection.saveTx();
assert.equal(collection.name, name);
collection = yield Zotero.Collections.getAsync(id);
collection = await Zotero.Collections.getAsync(id);
assert.equal(collection.name, name);
});
})
describe("#erase()", function () {
it("should delete a collection but not its descendant item by default", function* () {
var collection = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [collection.id] });
it("should delete a collection but not its descendant item by default", async function () {
var collection = await createDataObject('collection');
var item = await createDataObject('item', { collections: [collection.id] });
assert.isTrue(collection.hasItem(item.id));
yield collection.eraseTx();
await collection.eraseTx();
assert.isFalse((yield Zotero.Items.getAsync(item.id)).deleted);
assert.isFalse(((await Zotero.Items.getAsync(item.id))).deleted);
})
it("should delete a collection and trash its descendant items with deleteItems: true", function* () {
var collection = yield createDataObject('collection');
var item1 = yield createDataObject('item', { collections: [collection.id] });
var item2 = yield createDataObject('item', { collections: [collection.id] });
it("should delete a collection and trash its descendant items with deleteItems: true", async function () {
var collection = await createDataObject('collection');
var item1 = await createDataObject('item', { collections: [collection.id] });
var item2 = await createDataObject('item', { collections: [collection.id] });
assert.isTrue(collection.hasItem(item1.id));
assert.isTrue(collection.hasItem(item2.id));
yield collection.eraseTx({ deleteItems: true });
await collection.eraseTx({ deleteItems: true });
assert.isTrue((yield Zotero.Items.getAsync(item1.id)).deleted);
assert.isTrue((yield Zotero.Items.getAsync(item2.id)).deleted);
assert.isTrue(((await Zotero.Items.getAsync(item1.id))).deleted);
assert.isTrue(((await Zotero.Items.getAsync(item2.id))).deleted);
});
it("should clear collection from item cache", function* () {
var collection = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [collection.id] });
it("should clear collection from item cache", async function () {
var collection = await createDataObject('collection');
var item = await createDataObject('item', { collections: [collection.id] });
assert.lengthOf(item.getCollections(), 1);
yield collection.eraseTx();
await collection.eraseTx();
assert.lengthOf(item.getCollections(), 0);
});
it("should clear subcollection from descendent item cache", function* () {
var collection = yield createDataObject('collection');
var subcollection = yield createDataObject('collection', { parentID: collection.id });
var item = yield createDataObject('item', { collections: [subcollection.id] });
it("should clear subcollection from descendent item cache", async function () {
var collection = await createDataObject('collection');
var subcollection = await createDataObject('collection', { parentID: collection.id });
var item = await createDataObject('item', { collections: [subcollection.id] });
assert.lengthOf(item.getCollections(), 1);
yield collection.eraseTx();
await collection.eraseTx();
assert.lengthOf(item.getCollections(), 0);
});
it("should clear collection from item cache in deleteItems mode", function* () {
var collection = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [collection.id] });
it("should clear collection from item cache in deleteItems mode", async function () {
var collection = await createDataObject('collection');
var item = await createDataObject('item', { collections: [collection.id] });
assert.lengthOf(item.getCollections(), 1);
yield collection.eraseTx({ deleteItems: true });
await collection.eraseTx({ deleteItems: true });
assert.lengthOf(item.getCollections(), 0);
});
@ -139,109 +139,109 @@ describe("Zotero.Collection", function() {
})
describe("#version", function () {
it("should set object version", function* () {
it("should set object version", async function () {
var version = 100;
var collection = new Zotero.Collection
collection.version = version;
collection.name = "Test";
var id = yield collection.saveTx();
var id = await collection.saveTx();
assert.equal(collection.version, version);
collection = yield Zotero.Collections.getAsync(id);
collection = await Zotero.Collections.getAsync(id);
assert.equal(collection.version, version);
});
})
describe("#parentKey", function () {
it("should set parent collection for new collections", function* () {
it("should set parent collection for new collections", async function () {
var parentCol = new Zotero.Collection
parentCol.name = "Parent";
var parentID = yield parentCol.saveTx();
var parentID = await parentCol.saveTx();
var {libraryID, key: parentKey} = Zotero.Collections.getLibraryAndKeyFromID(parentID);
var col = new Zotero.Collection
col.name = "Child";
col.parentKey = parentKey;
var id = yield col.saveTx();
var id = await col.saveTx();
assert.equal(col.parentKey, parentKey);
col = yield Zotero.Collections.getAsync(id);
col = await Zotero.Collections.getAsync(id);
assert.equal(col.parentKey, parentKey);
});
it("should change parent collection for existing collections", function* () {
it("should change parent collection for existing collections", async function () {
// Create initial parent collection
var parentCol = new Zotero.Collection
parentCol.name = "Parent";
var parentID = yield parentCol.saveTx();
var parentID = await parentCol.saveTx();
var {libraryID, key: parentKey} = Zotero.Collections.getLibraryAndKeyFromID(parentID);
// Create subcollection
var col = new Zotero.Collection
col.name = "Child";
col.parentKey = parentKey;
var id = yield col.saveTx();
var id = await col.saveTx();
// Create new parent collection
var newParentCol = new Zotero.Collection
newParentCol.name = "New Parent";
var newParentID = yield newParentCol.saveTx();
var newParentID = await newParentCol.saveTx();
var {libraryID, key: newParentKey} = Zotero.Collections.getLibraryAndKeyFromID(newParentID);
// Change parent collection
col.parentKey = newParentKey;
yield col.saveTx();
await col.saveTx();
assert.equal(col.parentKey, newParentKey);
col = yield Zotero.Collections.getAsync(id);
col = await Zotero.Collections.getAsync(id);
assert.equal(col.parentKey, newParentKey);
});
it("should not mark collection as unchanged if set to existing value", function* () {
it("should not mark collection as unchanged if set to existing value", async function () {
// Create initial parent collection
var parentCol = new Zotero.Collection
parentCol.name = "Parent";
var parentID = yield parentCol.saveTx();
var parentID = await parentCol.saveTx();
var {libraryID, key: parentKey} = Zotero.Collections.getLibraryAndKeyFromID(parentID);
// Create subcollection
var col = new Zotero.Collection
col.name = "Child";
col.parentKey = parentKey;
var id = yield col.saveTx();
var id = await col.saveTx();
// Set to existing parent
col.parentKey = parentKey;
assert.isFalse(col.hasChanged());
});
it("should not resave a collection with no parent if set to false", function* () {
it("should not resave a collection with no parent if set to false", async function () {
var col = new Zotero.Collection
col.name = "Test";
var id = yield col.saveTx();
var id = await col.saveTx();
col.parentKey = false;
var ret = yield col.saveTx();
var ret = await col.saveTx();
assert.isFalse(ret);
});
})
describe("#hasChildCollections()", function () {
it("should be false if child made top-level", function* () {
var collection1 = yield createDataObject('collection');
var collection2 = yield createDataObject('collection', { parentID: collection1.id });
it("should be false if child made top-level", async function () {
var collection1 = await createDataObject('collection');
var collection2 = await createDataObject('collection', { parentID: collection1.id });
assert.isTrue(collection1.hasChildCollections());
collection2.parentKey = false;
yield collection2.saveTx();
await collection2.saveTx();
assert.isFalse(collection1.hasChildCollections());
})
it("should be false if child moved to another collection", function* () {
var collection1 = yield createDataObject('collection');
var collection2 = yield createDataObject('collection', { parentID: collection1.id });
var collection3 = yield createDataObject('collection');
it("should be false if child moved to another collection", async function () {
var collection1 = await createDataObject('collection');
var collection2 = await createDataObject('collection', { parentID: collection1.id });
var collection3 = await createDataObject('collection');
assert.isTrue(collection1.hasChildCollections());
collection2.parentKey = collection3.key;
yield collection2.saveTx();
await collection2.saveTx();
assert.isFalse(collection1.hasChildCollections());
});
@ -271,23 +271,23 @@ describe("Zotero.Collection", function() {
})
describe("#getChildCollections()", function () {
it("should include child collections", function* () {
var collection1 = yield createDataObject('collection');
var collection2 = yield createDataObject('collection', { parentID: collection1.id });
yield collection1.saveTx();
it("should include child collections", async function () {
var collection1 = await createDataObject('collection');
var collection2 = await createDataObject('collection', { parentID: collection1.id });
await collection1.saveTx();
var childCollections = collection1.getChildCollections();
assert.lengthOf(childCollections, 1);
assert.equal(childCollections[0].id, collection2.id);
})
it("should not include collections that have been removed", function* () {
var collection1 = yield createDataObject('collection');
var collection2 = yield createDataObject('collection', { parentID: collection1.id });
yield collection1.saveTx();
it("should not include collections that have been removed", async function () {
var collection1 = await createDataObject('collection');
var collection2 = await createDataObject('collection', { parentID: collection1.id });
await collection1.saveTx();
collection2.parentID = false;
yield collection2.save()
await collection2.save()
var childCollections = collection1.getChildCollections();
assert.lengthOf(childCollections, 0);
@ -309,12 +309,12 @@ describe("Zotero.Collection", function() {
assert.lengthOf(childCollections, 1);
});
it("should not include collections that have been deleted", function* () {
var collection1 = yield createDataObject('collection');
var collection2 = yield createDataObject('collection', { parentID: collection1.id });
yield collection1.saveTx();
it("should not include collections that have been deleted", async function () {
var collection1 = await createDataObject('collection');
var collection2 = await createDataObject('collection', { parentID: collection1.id });
await collection1.saveTx();
yield collection2.eraseTx()
await collection2.eraseTx()
var childCollections = collection1.getChildCollections();
assert.lengthOf(childCollections, 0);
@ -322,57 +322,57 @@ describe("Zotero.Collection", function() {
})
describe("#getChildItems()", function () {
it("should include child items", function* () {
var collection = yield createDataObject('collection');
it("should include child items", async function () {
var collection = await createDataObject('collection');
var item = createUnsavedDataObject('item');
item.addToCollection(collection.key);
yield item.saveTx();
await item.saveTx();
assert.lengthOf(collection.getChildItems(), 1);
})
it("should not include items in trash by default", function* () {
var collection = yield createDataObject('collection');
it("should not include items in trash by default", async function () {
var collection = await createDataObject('collection');
var item = createUnsavedDataObject('item');
item.deleted = true;
item.addToCollection(collection.key);
yield item.saveTx();
await item.saveTx();
assert.lengthOf(collection.getChildItems(), 0);
})
it("should include items in trash if includeTrashed=true", function* () {
var collection = yield createDataObject('collection');
it("should include items in trash if includeTrashed=true", async function () {
var collection = await createDataObject('collection');
var item = createUnsavedDataObject('item');
item.deleted = true;
item.addToCollection(collection.key);
yield item.saveTx();
await item.saveTx();
assert.lengthOf(collection.getChildItems(false, true), 1);
})
it("should not include removed items", function* () {
var col = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [ col.id ] });
it("should not include removed items", async function () {
var col = await createDataObject('collection');
var item = await createDataObject('item', { collections: [ col.id ] });
assert.lengthOf(col.getChildItems(), 1);
item.setCollections([]);
yield item.saveTx();
await item.saveTx();
Zotero.debug(col.getChildItems());
assert.lengthOf(col.getChildItems(), 0);
});
it("should not include deleted items", function* () {
var col = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [ col.id ] });
it("should not include deleted items", async function () {
var col = await createDataObject('collection');
var item = await createDataObject('item', { collections: [ col.id ] });
assert.lengthOf(col.getChildItems(), 1);
yield item.erase();
await item.erase();
assert.lengthOf(col.getChildItems(), 0);
});
it("should not include items emptied from trash", function* () {
var col = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [ col.id ], deleted: true });
yield item.erase();
it("should not include items emptied from trash", async function () {
var col = await createDataObject('collection');
var item = await createDataObject('item', { collections: [ col.id ], deleted: true });
await item.erase();
assert.lengthOf(col.getChildItems(), 0);
});
})
@ -401,14 +401,14 @@ describe("Zotero.Collection", function() {
});
describe("#toJSON()", function () {
it("should set 'parentCollection' to false when cleared", function* () {
var col1 = yield createDataObject('collection');
var col2 = yield createDataObject('collection', { parentID: col1.id });
it("should set 'parentCollection' to false when cleared", async function () {
var col1 = await createDataObject('collection');
var col2 = await createDataObject('collection', { parentID: col1.id });
// Create initial JSON with parentCollection
var patchBase = col2.toJSON();
// Clear parent collection and regenerate JSON
col2.parentID = false;
yield col2.saveTx();
await col2.saveTx();
var json = col2.toJSON({ patchBase });
assert.isFalse(json.parentCollection);
});
@ -429,7 +429,7 @@ describe("Zotero.Collection", function() {
yield item3.saveTx();
});
it("should return a flat array of collections and items", function* () {
it("should return a flat array of collections and items", async function () {
var desc = collection0.getDescendents();
assert.lengthOf(desc, 5);
assert.sameMembers(
@ -444,7 +444,7 @@ describe("Zotero.Collection", function() {
);
});
it("should return nested arrays of collections and items", function* () {
it("should return nested arrays of collections and items", async function () {
var desc = collection0.getDescendents(true);
assert.lengthOf(desc, 2);
assert.sameMembers(
@ -466,11 +466,11 @@ describe("Zotero.Collection", function() {
);
});
it("should not include deleted items", function* () {
var col = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [col.id] });
it("should not include deleted items", async function () {
var col = await createDataObject('collection');
var item = await createDataObject('item', { collections: [col.id] });
assert.lengthOf(col.getDescendents(), 1);
yield item.eraseTx();
await item.eraseTx();
assert.lengthOf(col.getDescendents(), 0);
});

View file

@ -1,6 +1,6 @@
"use strict";
describe("Zotero.CollectionTree", function() {
describe("Zotero.CollectionTree", function () {
var win, zp, cv, userLibraryID;
before(function* () {
@ -18,48 +18,48 @@ describe("Zotero.CollectionTree", function() {
});
describe("#refresh()", function () {
it("should show Duplicate Items and Unfiled Items by default and shouldn't show Retracted Items", function* () {
it("should show Duplicate Items and Unfiled Items by default and shouldn't show Retracted Items", async function () {
Zotero.Prefs.clear('duplicateLibraries');
Zotero.Prefs.clear('unfiledLibraries');
Zotero.Prefs.clear('retractedLibraries');
yield cv.refresh();
await cv.refresh();
assert.ok(cv.getRowIndexByID("D" + userLibraryID));
assert.ok(cv.getRowIndexByID("U" + userLibraryID));
assert.isFalse(cv.getRowIndexByID("R" + userLibraryID));
});
it("shouldn't show virtual collections if hidden", function* () {
it("shouldn't show virtual collections if hidden", async function () {
Zotero.Prefs.set('duplicateLibraries', `{"${userLibraryID}": false}`);
Zotero.Prefs.set('unfiledLibraries', `{"${userLibraryID}": false}`);
Zotero.Prefs.set('retractedLibraries', `{"${userLibraryID}": false}`);
yield cv.refresh();
await cv.refresh();
assert.isFalse(cv.getRowIndexByID("D" + userLibraryID));
assert.isFalse(cv.getRowIndexByID("U" + userLibraryID));
assert.isFalse(cv.getRowIndexByID("R" + userLibraryID));
});
it("should maintain open state of group", function* () {
var group1 = yield createGroup();
var group2 = yield createGroup();
it("should maintain open state of group", async function () {
var group1 = await createGroup();
var group2 = await createGroup();
var group1Row = cv.getRowIndexByID(group1.treeViewID);
var group2Row = cv.getRowIndexByID(group2.treeViewID);
// Open group 1 and close group 2
if (!cv.isContainerOpen(group1Row)) {
yield cv.toggleOpenState(group1Row);
await cv.toggleOpenState(group1Row);
}
if (cv.isContainerOpen(group2Row)) {
yield cv.toggleOpenState(group2Row);
await cv.toggleOpenState(group2Row);
}
cv._saveOpenStates();
// #_saveOpenStates is debounced
yield Zotero.Promise.delay(500);
await Zotero.Promise.delay(500);
group1Row = cv.getRowIndexByID(group1.treeViewID);
group2Row = cv.getRowIndexByID(group2.treeViewID);
yield cv.refresh();
await cv.refresh();
// Group rows shouldn't have changed
assert.equal(cv.getRowIndexByID(group1.treeViewID), group1Row);
@ -69,25 +69,25 @@ describe("Zotero.CollectionTree", function() {
assert.isFalse(cv.isContainerOpen(group2Row));
});
it("should update associated item tree view", function* () {
var collection = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [collection.id] });
yield cv.reload();
yield cv.selectCollection(collection.id);
yield cv.selectItem(item.id);
it("should update associated item tree view", async function () {
var collection = await createDataObject('collection');
var item = await createDataObject('item', { collections: [collection.id] });
await cv.reload();
await cv.selectCollection(collection.id);
await cv.selectItem(item.id);
});
});
describe("collapse/expand", function () {
it("should close and open My Library repeatedly", function* () {
yield cv.selectLibrary(userLibraryID);
it("should close and open My Library repeatedly", async function () {
await cv.selectLibrary(userLibraryID);
var row = cv.selection.focused;
cv.collapseLibrary(userLibraryID);
assert.equal(cv.selection.focused, row);
assert.isFalse(cv.isContainerOpen(row));
yield cv.expandLibrary(userLibraryID);
await cv.expandLibrary(userLibraryID);
assert.equal(cv.selection.focused, row);
assert.ok(cv.isContainerOpen(row));
@ -95,7 +95,7 @@ describe("Zotero.CollectionTree", function() {
assert.equal(cv.selection.focused, row);
assert.isFalse(cv.isContainerOpen(row));
yield cv.expandLibrary(userLibraryID);
await cv.expandLibrary(userLibraryID);
assert.equal(cv.selection.focused, row);
assert.ok(cv.isContainerOpen(row));
})
@ -120,49 +120,49 @@ describe("Zotero.CollectionTree", function() {
yield select(win, col3);
});
it("should open a library and respect stored container state", function* () {
it("should open a library and respect stored container state", async function () {
// Collapse B
yield cv.toggleOpenState(cv.getRowIndexByID(col2.treeViewID));
await cv.toggleOpenState(cv.getRowIndexByID(col2.treeViewID));
cv._saveOpenStates();
// #_saveOpenStates is debounced
yield Zotero.Promise.delay(500);
await Zotero.Promise.delay(500);
// Close and reopen library
yield cv.toggleOpenState(libraryRow);
yield cv.expandLibrary(userLibraryID);
await cv.toggleOpenState(libraryRow);
await cv.expandLibrary(userLibraryID);
assert.isTrue(cv.isContainerOpen(libraryRow));
assert.isTrue(cv.isContainerOpen(cv.getRowIndexByID(col1.treeViewID)));
assert.isFalse(cv.isContainerOpen(cv.getRowIndexByID(col2.treeViewID)));
});
it("should open a library and all subcollections in recursive mode", function* () {
yield cv.toggleOpenState(cv.getRowIndexByID(col2.treeViewID));
it("should open a library and all subcollections in recursive mode", async function () {
await cv.toggleOpenState(cv.getRowIndexByID(col2.treeViewID));
cv._saveOpenStates();
// #_saveOpenStates is debounced
yield Zotero.Promise.delay(500);
await Zotero.Promise.delay(500);
// Close and reopen library
yield cv.toggleOpenState(libraryRow);
yield cv.expandLibrary(userLibraryID, true);
await cv.toggleOpenState(libraryRow);
await cv.expandLibrary(userLibraryID, true);
assert.isTrue(cv.isContainerOpen(cv.getRowIndexByID(col1.treeViewID)));
assert.isTrue(cv.isContainerOpen(cv.getRowIndexByID(col2.treeViewID)));
});
it("should open a group and show top-level collections", function* () {
var group = yield createGroup();
it("should open a group and show top-level collections", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
var col1 = yield createDataObject('collection', { libraryID });
var col2 = yield createDataObject('collection', { libraryID });
var col3 = yield createDataObject('collection', { libraryID });
var col4 = yield createDataObject('collection', { libraryID, parentID: col1.id });
var col5 = yield createDataObject('collection', { libraryID, parentID: col4.id });
var col1 = await createDataObject('collection', { libraryID });
var col2 = await createDataObject('collection', { libraryID });
var col3 = await createDataObject('collection', { libraryID });
var col4 = await createDataObject('collection', { libraryID, parentID: col1.id });
var col5 = await createDataObject('collection', { libraryID, parentID: col4.id });
// Close group
cv.toggleOpenState(cv.getRowIndexByID(group.treeViewID), false);
yield cv.expandLibrary(libraryID);
await cv.expandLibrary(libraryID);
assert.isNumber(cv.getRowIndexByID(col1.treeViewID));
assert.isNumber(cv.getRowIndexByID(col2.treeViewID));
@ -173,13 +173,13 @@ describe("Zotero.CollectionTree", function() {
});
describe("#expandToCollection()", function () {
it("should expand a collection to a subcollection", function* () {
var collection1 = yield createDataObject('collection');
var collection2 = yield createDataObject('collection', { parentID: collection1.id });
it("should expand a collection to a subcollection", async function () {
var collection1 = await createDataObject('collection');
var collection2 = await createDataObject('collection', { parentID: collection1.id });
var row = cv.getRowIndexByID("C" + collection1.id);
assert.isFalse(cv.isContainerOpen(row));
yield cv.expandToCollection(collection2.id);
await cv.expandToCollection(collection2.id);
cv.forceUpdate();
// Make sure parent row position hasn't changed
@ -190,8 +190,8 @@ describe("Zotero.CollectionTree", function() {
})
describe("#selectByID()", function () {
it("should select the trash", function* () {
yield cv.selectByID("T1");
it("should select the trash", async function () {
await cv.selectByID("T1");
var row = cv.selection.focused;
var treeRow = cv.getRow(row);
assert.ok(treeRow.isTrash());
@ -200,11 +200,11 @@ describe("Zotero.CollectionTree", function() {
})
describe("#selectWait()", function () {
it("shouldn't hang if row is already selected", function* () {
it("shouldn't hang if row is already selected", async function () {
var row = cv.getRowIndexByID("T" + userLibraryID);
yield cv.selectWait(row);
yield Zotero.Promise.delay(50);
yield cv.selectWait(row);
await cv.selectWait(row);
await Zotero.Promise.delay(50);
await cv.selectWait(row);
})
})
@ -312,22 +312,22 @@ describe("Zotero.CollectionTree", function() {
});
describe("#notify()", function () {
it("should select a new collection", function* () {
it("should select a new collection", async function () {
// Create collection
var collection = new Zotero.Collection;
collection.name = "Select new collection";
var id = yield collection.saveTx();
var id = await collection.saveTx();
// New collection should be selected
var selected = cv.getSelectedCollection(true);
assert.equal(selected, id);
});
it("shouldn't select a new collection if skipNotifier is passed", function* () {
it("shouldn't select a new collection if skipNotifier is passed", async function () {
// Create collection with skipNotifier flag
var collection = new Zotero.Collection;
collection.name = "No select on skipNotifier";
var id = yield collection.saveTx({
var id = await collection.saveTx({
skipNotifier: true
});
@ -335,11 +335,11 @@ describe("Zotero.CollectionTree", function() {
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
});
it("shouldn't select a new collection if skipSelect is passed", function* () {
it("shouldn't select a new collection if skipSelect is passed", async function () {
// Create collection with skipSelect flag
var collection = new Zotero.Collection;
collection.name = "No select on skipSelect";
var id = yield collection.saveTx({
var id = await collection.saveTx({
skipSelect: true
});
@ -347,32 +347,32 @@ describe("Zotero.CollectionTree", function() {
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
});
it("shouldn't select a modified collection", function* () {
it("shouldn't select a modified collection", async function () {
// Create collection
var collection = new Zotero.Collection;
collection.name = "No select on modify";
var id = yield collection.saveTx();
var id = await collection.saveTx();
yield selectLibrary(win);
await selectLibrary(win);
collection.name = "No select on modify 2";
yield collection.saveTx();
await collection.saveTx();
// Modified collection should not be selected
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
});
it("should maintain selection on a selected modified collection", function* () {
it("should maintain selection on a selected modified collection", async function () {
// Create collection
var collection = new Zotero.Collection;
collection.name = "Reselect on modify";
var id = yield collection.saveTx();
var id = await collection.saveTx();
var selected = cv.getSelectedCollection(true);
assert.equal(selected, id);
collection.name = "Reselect on modify 2";
yield collection.saveTx();
await collection.saveTx();
// Modified collection should still be selected
selected = cv.getSelectedCollection(true);
@ -441,29 +441,29 @@ describe("Zotero.CollectionTree", function() {
});
}
it("should update the editability of the current view", function* () {
var group = yield createGroup({
it("should update the editability of the current view", async function () {
var group = await createGroup({
editable: false,
filesEditable: false
});
yield cv.selectLibrary(group.libraryID);
yield waitForItemsLoad(win);
await cv.selectLibrary(group.libraryID);
await waitForItemsLoad(win);
assert.isFalse(zp.getCollectionTreeRow().editable);
var cmd = win.document.getElementById('cmd_zotero_newStandaloneNote');
assert.isTrue(cmd.getAttribute('disabled') == 'true');
group.editable = true;
yield group.saveTx();
await group.saveTx();
assert.isTrue(zp.getCollectionTreeRow().editable);
assert.isFalse(cmd.getAttribute('disabled') == 'true');
});
it("should re-sort a modified collection", function* () {
it("should re-sort a modified collection", async function () {
var prefix = Zotero.Utilities.randomString() + " ";
var collectionA = yield createDataObject('collection', { name: prefix + "A" });
var collectionB = yield createDataObject('collection', { name: prefix + "B" });
var collectionA = await createDataObject('collection', { name: prefix + "A" });
var collectionB = await createDataObject('collection', { name: prefix + "B" });
var aRow = cv.getRowIndexByID("C" + collectionA.id);
var aRowOriginal = aRow;
@ -471,7 +471,7 @@ describe("Zotero.CollectionTree", function() {
assert.equal(bRow, aRow + 1);
collectionA.name = prefix + "C";
yield collectionA.saveTx();
await collectionA.saveTx();
var aRow = cv.getRowIndexByID("C" + collectionA.id);
var bRow = cv.getRowIndexByID("C" + collectionB.id);
@ -479,10 +479,10 @@ describe("Zotero.CollectionTree", function() {
assert.equal(aRow, bRow + 1);
})
it("should re-sort a modified search", function* () {
it("should re-sort a modified search", async function () {
var prefix = Zotero.Utilities.randomString() + " ";
var searchA = yield createDataObject('search', { name: prefix + "A" });
var searchB = yield createDataObject('search', { name: prefix + "B" });
var searchA = await createDataObject('search', { name: prefix + "A" });
var searchB = await createDataObject('search', { name: prefix + "B" });
var aRow = cv.getRowIndexByID("S" + searchA.id);
var aRowOriginal = aRow;
@ -490,7 +490,7 @@ describe("Zotero.CollectionTree", function() {
assert.equal(bRow, aRow + 1);
searchA.name = prefix + "C";
yield searchA.saveTx();
await searchA.saveTx();
var aRow = cv.getRowIndexByID("S" + searchA.id);
var bRow = cv.getRowIndexByID("S" + searchB.id);
@ -499,16 +499,16 @@ describe("Zotero.CollectionTree", function() {
})
it("should add collection after parent's subcollection and before non-sibling", function* () {
var c0 = yield createDataObject('collection', { name: "Test" });
it("should add collection after parent's subcollection and before non-sibling", async function () {
var c0 = await createDataObject('collection', { name: "Test" });
var rootRow = cv.getRowIndexByID(c0.treeViewID);
var c1 = yield createDataObject('collection', { name: "1", parentID: c0.id });
var c2 = yield createDataObject('collection', { name: "2", parentID: c0.id });
var c3 = yield createDataObject('collection', { name: "3", parentID: c1.id });
var c4 = yield createDataObject('collection', { name: "4", parentID: c3.id });
var c5 = yield createDataObject('collection', { name: "5", parentID: c1.id });
yield select(win, c4);
var c1 = await createDataObject('collection', { name: "1", parentID: c0.id });
var c2 = await createDataObject('collection', { name: "2", parentID: c0.id });
var c3 = await createDataObject('collection', { name: "3", parentID: c1.id });
var c4 = await createDataObject('collection', { name: "4", parentID: c3.id });
var c5 = await createDataObject('collection', { name: "5", parentID: c1.id });
await select(win, c4);
assert.equal(cv.getRowIndexByID(c1.treeViewID), rootRow + 1);
@ -523,9 +523,9 @@ describe("Zotero.CollectionTree", function() {
});
it("should add multiple collections", function* () {
it("should add multiple collections", async function () {
var col1, col2;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
col1 = createUnsavedDataObject('collection');
col2 = createUnsavedDataObject('collection');
await col1.save();
@ -541,27 +541,27 @@ describe("Zotero.CollectionTree", function() {
});
it("shouldn't refresh the items list when a collection is modified", function* () {
var collection = yield createDataObject('collection');
yield waitForItemsLoad(win);
it("shouldn't refresh the items list when a collection is modified", async function () {
var collection = await createDataObject('collection');
await waitForItemsLoad(win);
var itemsView = zp.itemsView;
collection.name = "New Name";
yield collection.saveTx();
await collection.saveTx();
yield waitForItemsLoad(win);
await waitForItemsLoad(win);
assert.equal(zp.itemsView, itemsView);
})
it("should add a saved search after collections", function* () {
it("should add a saved search after collections", async function () {
var collection = new Zotero.Collection;
collection.name = "Test";
var collectionID = yield collection.saveTx();
var collectionID = await collection.saveTx();
var search = new Zotero.Search;
search.name = "A Test Search";
search.addCondition('title', 'contains', 'test');
var searchID = yield search.saveTx();
var searchID = await search.saveTx();
var collectionRow = cv._rowMap["C" + collectionID];
var searchRow = cv._rowMap["S" + searchID];
@ -583,37 +583,37 @@ describe("Zotero.CollectionTree", function() {
}
})
it("shouldn't select a new group", function* () {
var group = yield createGroup();
it("shouldn't select a new group", async function () {
var group = await createGroup();
// Library should still be selected
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
})
it("should remove a group and all children", function* () {
it("should remove a group and all children", async function () {
// Make sure Group Libraries separator and header exist already,
// since otherwise they'll interfere with the count
yield getGroup();
await getGroup();
var originalRowCount = cv._rows.length;
var group = yield createGroup();
yield createDataObject('collection', { libraryID: group.libraryID });
var c = yield createDataObject('collection', { libraryID: group.libraryID });
var c2 = yield createDataObject('collection', { libraryID: group.libraryID, parentID: c.id });
yield createDataObject('collection', { libraryID: group.libraryID });
yield createDataObject('collection', { libraryID: group.libraryID });
yield select(win, c2);
var group = await createGroup();
await createDataObject('collection', { libraryID: group.libraryID });
var c = await createDataObject('collection', { libraryID: group.libraryID });
var c2 = await createDataObject('collection', { libraryID: group.libraryID, parentID: c.id });
await createDataObject('collection', { libraryID: group.libraryID });
await createDataObject('collection', { libraryID: group.libraryID });
await select(win, c2);
// Group, collections, Duplicates, Unfiled, and trash
assert.equal(cv._rows.length, originalRowCount + 9);
// Select group
yield cv.selectLibrary(group.libraryID);
yield waitForItemsLoad(win);
await cv.selectLibrary(group.libraryID);
await waitForItemsLoad(win);
var spy = sinon.spy(cv, "refresh");
try {
yield group.eraseTx();
await group.eraseTx();
assert.equal(cv._rows.length, originalRowCount);
// Make sure the tree wasn't refreshed
@ -624,14 +624,14 @@ describe("Zotero.CollectionTree", function() {
}
})
it("should select a new feed", function* () {
var feed = yield createFeed();
it("should select a new feed", async function () {
var feed = await createFeed();
// Feed should be selected
assert.equal(cv.getSelectedLibraryID(), feed.id);
});
it("shouldn't select a new feed with skipSelect: true", function* () {
var feed = yield createFeed({
it("shouldn't select a new feed with skipSelect: true", async function () {
var feed = await createFeed({
saveOptions: {
skipSelect: true
}
@ -640,14 +640,14 @@ describe("Zotero.CollectionTree", function() {
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
});
it("should remove deleted feed", function* () {
var feed = yield createFeed();
yield cv.selectLibrary(feed.libraryID);
it("should remove deleted feed", async function () {
var feed = await createFeed();
await cv.selectLibrary(feed.libraryID);
waitForDialog();
var id = feed.treeViewID;
let promise = waitForCollectionTree(win);
yield win.ZoteroPane.deleteSelectedCollection();
yield promise;
await win.ZoteroPane.deleteSelectedCollection();
await promise;
assert.isFalse(cv.getRowIndexByID(id))
})
@ -721,7 +721,7 @@ describe("Zotero.CollectionTree", function() {
* value returned after the drag. Otherwise, an 'add' event will be waited for, and
* an object with 'ids' and 'extraData' will be returned.
*/
var onDrop = Zotero.Promise.coroutine(function* (objectType, targetRow, ids, promise, action = 'copy') {
var onDrop = async function (objectType, targetRow, ids, promise, action = 'copy') {
if (typeof targetRow == 'string') {
var row = cv.getRowIndexByID(targetRow);
var orient = 0;
@ -737,7 +737,7 @@ describe("Zotero.CollectionTree", function() {
if (!promise) {
promise = waitForNotifierEvent("add", objectType);
}
yield cv.onDrop({
await cv.onDrop({
persist: () => 0,
target: {ownerDocument: {defaultView: win}},
dataTransfer: {
@ -753,13 +753,13 @@ describe("Zotero.CollectionTree", function() {
}, row);
// Add observer to wait for add
var result = yield promise;
var result = await promise;
Zotero.DragDrop.currentDragSource = null;
return result;
});
};
var canDrop = Zotero.Promise.coroutine(function* (objectType, targetRowID, ids) {
var canDrop = async function (objectType, targetRowID, ids) {
var row = cv.getRowIndexByID(targetRowID);
Zotero.DragDrop.currentDragSource = objectType == "item"
@ -777,11 +777,11 @@ describe("Zotero.CollectionTree", function() {
};
var canDrop = cv.canDropCheck(row, 0, dt);
if (canDrop) {
canDrop = yield cv.canDropCheckAsync(row, 0, dt);
canDrop = await cv.canDropCheckAsync(row, 0, dt);
}
Zotero.DragDrop.currentDragSource = null;
return canDrop;
});
};
describe("with items", function () {
it("should add an item to a collection", async function () {
@ -813,11 +813,11 @@ describe("Zotero.CollectionTree", function() {
assert.equal(treeRow.ref.id, item.id);
})
it("should move an item from one collection to another", function* () {
var collection1 = yield createDataObject('collection');
yield select(win, collection1);
var collection2 = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [collection1.id] });
it("should move an item from one collection to another", async function () {
var collection1 = await createDataObject('collection');
await select(win, collection1);
var collection2 = await createDataObject('collection');
var item = await createDataObject('item', { collections: [collection1.id] });
// Add observer to wait for collection add
var deferred = Zotero.Promise.defer();
@ -833,15 +833,15 @@ describe("Zotero.CollectionTree", function() {
}, 'collection-item', 'test');
let promise = zp.itemsView.waitForSelect();
yield onDrop('item', 'C' + collection2.id, [item.id], deferred.promise, 'move');
yield promise;
await onDrop('item', 'C' + collection2.id, [item.id], deferred.promise, 'move');
await promise;
Zotero.Notifier.unregisterObserver(observerID);
// Source collection should be empty
assert.equal(zp.itemsView.rowCount, 0);
yield select(win, collection2);
await select(win, collection2);
// Target collection should have item
assert.equal(zp.itemsView.rowCount, 1);
@ -1066,23 +1066,23 @@ describe("Zotero.CollectionTree", function() {
return group.eraseTx();
});
it("should not copy an item or its attachment to a group twice", function* () {
var group = yield getGroup();
it("should not copy an item or its attachment to a group twice", async function () {
var group = await getGroup();
var itemTitle = Zotero.Utilities.randomString();
var item = yield createDataObject('item', false, { skipSelect: true });
var item = await createDataObject('item', false, { skipSelect: true });
var file = getTestDataDirectory();
file.append('test.png');
var attachment = yield Zotero.Attachments.importFromFile({
var attachment = await Zotero.Attachments.importFromFile({
file: file,
parentItemID: item.id
});
var attachmentTitle = Zotero.Utilities.randomString();
attachment.setField('title', attachmentTitle);
yield attachment.saveTx();
await attachment.saveTx();
yield onDrop('item', 'L' + group.libraryID, [item.id]);
assert.isFalse(yield canDrop('item', 'L' + group.libraryID, [item.id]));
await onDrop('item', 'L' + group.libraryID, [item.id]);
assert.isFalse(await canDrop('item', 'L' + group.libraryID, [item.id]));
})
it("should copy an item from a read-only group to an editable group", async function () {
@ -1136,11 +1136,11 @@ describe("Zotero.CollectionTree", function() {
describe("with collections", function () {
it("should make a subcollection top-level", function* () {
var collection1 = yield createDataObject('collection', { name: "A" }, { skipSelect: true });
var collection2 = yield createDataObject('collection', { name: "C" }, { skipSelect: true });
var collection3 = yield createDataObject('collection', { name: "D" }, { skipSelect: true });
var collection4 = yield createDataObject('collection', { name: "B", parentKey: collection2.key });
it("should make a subcollection top-level", async function () {
var collection1 = await createDataObject('collection', { name: "A" }, { skipSelect: true });
var collection2 = await createDataObject('collection', { name: "C" }, { skipSelect: true });
var collection3 = await createDataObject('collection', { name: "D" }, { skipSelect: true });
var collection4 = await createDataObject('collection', { name: "B", parentKey: collection2.key });
var colIndex1 = cv.getRowIndexByID('C' + collection1.id);
var colIndex2 = cv.getRowIndexByID('C' + collection2.id);
@ -1159,7 +1159,7 @@ describe("Zotero.CollectionTree", function() {
}
}, 'collection', 'test');
yield onDrop(
await onDrop(
'collection',
{
row: 0,
@ -1413,7 +1413,7 @@ describe("Zotero.CollectionTree", function() {
await new Promise(resolve => httpd.stop(resolve));
});
it("should add a translated feed item retrieved from a URL", function* () {
it("should add a translated feed item retrieved from a URL", async function () {
// Serve the feed entry webpage via localhost
const urlPath = "/journalArticle-single.html";
const url = `http://localhost:${httpdPort}` + urlPath;
@ -1424,27 +1424,27 @@ describe("Zotero.CollectionTree", function() {
))
);
var feed = yield createFeed();
var collection = yield createDataObject('collection', false, { skipSelect: true });
var feedItem = yield createDataObject('feedItem', {libraryID: feed.libraryID}, { skipSelect: true });
var feed = await createFeed();
var collection = await createDataObject('collection', false, { skipSelect: true });
var feedItem = await createDataObject('feedItem', {libraryID: feed.libraryID}, { skipSelect: true });
feedItem.setField('url', url);
yield feedItem.saveTx();
await feedItem.saveTx();
var translateFn = sinon.spy(feedItem, 'translate');
// Add observer to wait for collection add
var deferred = Zotero.Promise.defer();
var itemIds;
var ids = (yield onDrop('item', 'C' + collection.id, [feedItem.id])).ids;
var ids = ((await onDrop('item', 'C' + collection.id, [feedItem.id]))).ids;
// Check that the translated item was the one that was created after drag
var item;
yield translateFn.returnValues[0].then(function(i) {
await translateFn.returnValues[0].then(function (i) {
item = i;
assert.equal(item.id, ids[0]);
});
yield select(win, collection);
await select(win, collection);
var itemsView = win.ZoteroPane.itemsView;
assert.equal(itemsView.rowCount, 1);
@ -1571,7 +1571,7 @@ describe("Zotero.CollectionTree", function() {
});
for (let type of ['collection', 'search', 'feed']) {
// eslint-disable-next-line no-loop-func
it(`should show only ${type} matching the filter`, async function () {
await cv.setFilter(type);
let displayedRowNames = cv._rows.filter(row => row.type == type).map(row => row.getName());
@ -1634,7 +1634,7 @@ describe("Zotero.CollectionTree", function() {
});
for (let type of ['collection', 'search']) {
// eslint-disable-next-line no-loop-func
it(`should only hide ${type} if it's renamed to not match the filter`, async function () {
await cv.setFilter(type);
let objectToSelect = type == 'collection' ? collection5 : search2;
@ -1651,7 +1651,7 @@ describe("Zotero.CollectionTree", function() {
}
for (let type of ['collection', 'search']) {
// eslint-disable-next-line no-loop-func
it(`should only add ${type} if its name matches the filter`, async function () {
await cv.setFilter(type);
let newCollection = await createDataObject(type, { name: `new_${type}`, libraryID: userLibraryID });

View file

@ -1,31 +1,31 @@
describe("Zotero.Collections", function () {
describe("#getByLibrary()", function () {
it("should get all root collections in a library", function* () {
var group = yield createGroup();
it("should get all root collections in a library", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
var col1 = yield createDataObject('collection', { libraryID });
var col2 = yield createDataObject('collection', { libraryID });
var col3 = yield createDataObject('collection', { libraryID, parentID: col2.id });
var col1 = await createDataObject('collection', { libraryID });
var col2 = await createDataObject('collection', { libraryID });
var col3 = await createDataObject('collection', { libraryID, parentID: col2.id });
var cols = Zotero.Collections.getByLibrary(libraryID);
assert.lengthOf(cols, 2);
assert.sameMembers(cols.map(col => col.id), [col1.id, col2.id]);
})
it("should get all collections in a library in recursive mode", function* () {
var group = yield createGroup();
it("should get all collections in a library in recursive mode", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
// Create collection in another library
yield createDataObject('collection');
await createDataObject('collection');
var col1 = yield createDataObject('collection', { libraryID, name: "C" });
var col2 = yield createDataObject('collection', { libraryID, name: "A" });
var col3 = yield createDataObject('collection', { libraryID, name: "D", parentID: col2.id });
var col4 = yield createDataObject('collection', { libraryID, name: "B", parentID: col2.id });
var col5 = yield createDataObject('collection', { libraryID, name: "E", parentID: col2.id });
var col6 = yield createDataObject('collection', { libraryID, name: "G", parentID: col3.id });
var col7 = yield createDataObject('collection', { libraryID, name: "F", parentID: col3.id });
var col1 = await createDataObject('collection', { libraryID, name: "C" });
var col2 = await createDataObject('collection', { libraryID, name: "A" });
var col3 = await createDataObject('collection', { libraryID, name: "D", parentID: col2.id });
var col4 = await createDataObject('collection', { libraryID, name: "B", parentID: col2.id });
var col5 = await createDataObject('collection', { libraryID, name: "E", parentID: col2.id });
var col6 = await createDataObject('collection', { libraryID, name: "G", parentID: col3.id });
var col7 = await createDataObject('collection', { libraryID, name: "F", parentID: col3.id });
var cols = Zotero.Collections.getByLibrary(libraryID, true);
assert.lengthOf(cols, 7);
var ids = cols.map(col => col.id);
@ -69,21 +69,21 @@ describe("Zotero.Collections", function () {
})
describe("#getByParent()", function () {
it("should get all direct subcollections of a library", function* () {
var col1 = yield createDataObject('collection');
var col2 = yield createDataObject('collection');
var col3 = yield createDataObject('collection', { parentID: col2.id });
it("should get all direct subcollections of a library", async function () {
var col1 = await createDataObject('collection');
var col2 = await createDataObject('collection');
var col3 = await createDataObject('collection', { parentID: col2.id });
assert.lengthOf(Zotero.Collections.getByParent(col1.id), 0);
var cols = Zotero.Collections.getByParent(col2.id);
assert.lengthOf(cols, 1);
assert.sameMembers(cols.map(col => col.id), [col3.id]);
})
it("should get all collections underneath a collection in recursive mode", function* () {
var col1 = yield createDataObject('collection');
var col2 = yield createDataObject('collection');
var col3 = yield createDataObject('collection', { parentID: col2.id });
var col4 = yield createDataObject('collection', { parentID: col3.id });
it("should get all collections underneath a collection in recursive mode", async function () {
var col1 = await createDataObject('collection');
var col2 = await createDataObject('collection');
var col3 = await createDataObject('collection', { parentID: col2.id });
var col4 = await createDataObject('collection', { parentID: col3.id });
assert.lengthOf(Zotero.Collections.getByParent(col1.id), 0);
var cols = Zotero.Collections.getByParent(col2.id, true);
assert.lengthOf(cols, 2);
@ -91,10 +91,10 @@ describe("Zotero.Collections", function () {
})
})
describe("#getAsync()", function() {
it("should return a collection item for a collection ID", function* () {
describe("#getAsync()", function () {
it("should return a collection item for a collection ID", async function () {
let collection = new Zotero.Collection({ name: 'foo' });
collection = yield Zotero.Collections.getAsync(yield collection.saveTx());
collection = await Zotero.Collections.getAsync(await collection.saveTx());
assert.notOk(collection.isFeed);
assert.instanceOf(collection, Zotero.Collection);

View file

@ -7,7 +7,7 @@ describe("ConcurrentCaller", function () {
//logger = Zotero.debug;
describe("#start()", function () {
it("should run functions as slots open and wait for them to complete", function* () {
it("should run functions as slots open and wait for them to complete", async function () {
var numConcurrent = 2;
var running = 0;
var finished = 0;
@ -15,7 +15,7 @@ describe("ConcurrentCaller", function () {
var ids = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
var funcs = ids.map(function (id) {
return Zotero.Promise.coroutine(function* () {
return async function () {
if (logger) {
Zotero.debug("Running " + id);
}
@ -26,7 +26,7 @@ describe("ConcurrentCaller", function () {
}
var min = 10;
var max = 25;
yield Zotero.Promise.delay(
await Zotero.Promise.delay(
Math.floor(Math.random() * (max - min + 1)) + min
);
if (running > numConcurrent) {
@ -39,14 +39,14 @@ describe("ConcurrentCaller", function () {
Zotero.debug("Finished " + id);
}
return id;
});
};
})
var caller = new ConcurrentCaller({
numConcurrent,
logger
});
var results = yield caller.start(funcs);
var results = await caller.start(funcs);
assert.equal(results.length, ids.length);
assert.equal(running, 0);
@ -54,7 +54,7 @@ describe("ConcurrentCaller", function () {
assert.isFalse(failed);
})
it("should add functions to existing queue and resolve when all are complete (waiting for earlier set)", function* () {
it("should add functions to existing queue and resolve when all are complete (waiting for earlier set)", async function () {
var numConcurrent = 2;
var running = 0;
var finished = 0;
@ -63,7 +63,7 @@ describe("ConcurrentCaller", function () {
var ids1 = {"1": 5, "2": 10, "3": 7};
var ids2 = {"4": 50, "5": 50};
var makeFunc = function (id, delay) {
return Zotero.Promise.coroutine(function* () {
return async function () {
if (logger) {
Zotero.debug("Running " + id);
}
@ -72,7 +72,7 @@ describe("ConcurrentCaller", function () {
failed = true;
throw new Error("Too many concurrent tasks");
}
yield Zotero.Promise.delay(delay);
await Zotero.Promise.delay(delay);
if (running > numConcurrent) {
failed = true;
throw new Error("Too many concurrent tasks");
@ -83,7 +83,7 @@ describe("ConcurrentCaller", function () {
Zotero.debug("Finished " + id);
}
return id;
});
};
};
var keys1 = Object.keys(ids1);
var keys2 = Object.keys(ids2);
@ -95,11 +95,11 @@ describe("ConcurrentCaller", function () {
logger
});
var promise1 = caller.start(funcs1);
yield Zotero.Promise.delay(1);
await Zotero.Promise.delay(1);
var promise2 = caller.start(funcs2);
// Wait for first set
var results1 = yield promise1;
var results1 = await promise1;
// Second set shouldn't be done yet
assert.isFalse(promise2.isFulfilled());
@ -109,7 +109,7 @@ describe("ConcurrentCaller", function () {
assert.isFalse(failed);
})
it("should add functions to existing queue and resolve when all are complete (waiting for later set)", function* () {
it("should add functions to existing queue and resolve when all are complete (waiting for later set)", async function () {
var numConcurrent = 2;
var running = 0;
var finished = 0;
@ -118,7 +118,7 @@ describe("ConcurrentCaller", function () {
var ids1 = {"1": 100, "2": 45, "3": 200};
var ids2 = {"4": 1, "5": 1};
var makeFunc = function (id, delay) {
return Zotero.Promise.coroutine(function* () {
return async function () {
if (logger) {
Zotero.debug("Running " + id);
}
@ -127,7 +127,7 @@ describe("ConcurrentCaller", function () {
failed = true;
throw new Error("Too many concurrent tasks");
}
yield Zotero.Promise.delay(delay);
await Zotero.Promise.delay(delay);
if (running > numConcurrent) {
failed = true;
throw new Error("Too many concurrent tasks");
@ -138,7 +138,7 @@ describe("ConcurrentCaller", function () {
Zotero.debug("Finished " + id);
}
return id;
});
};
};
var keys1 = Object.keys(ids1);
var keys2 = Object.keys(ids2);
@ -150,11 +150,11 @@ describe("ConcurrentCaller", function () {
logger
});
var promise1 = caller.start(funcs1);
yield Zotero.Promise.delay(10);
await Zotero.Promise.delay(10);
var promise2 = caller.start(funcs2);
// Wait for second set
var results2 = yield promise2;
var results2 = await promise2;
// The second set should finish before the first
assert.isFalse(promise1.isFulfilled());
@ -166,20 +166,20 @@ describe("ConcurrentCaller", function () {
assert.isFalse(failed);
})
it("should return a rejected promise if a single passed function fails", function* () {
it("should return a rejected promise if a single passed function fails", async function () {
var numConcurrent = 2;
var caller = new ConcurrentCaller({
numConcurrent,
logger
});
var e = yield getPromiseError(caller.start(function () {
var e = await getPromiseError(caller.start(function () {
throw new Error("Fail");
}));
assert.ok(e);
})
it("should stop on error if stopOnError is set", function* () {
it("should stop on error if stopOnError is set", async function () {
var numConcurrent = 2;
var running = 0;
var finished = 0;
@ -188,7 +188,7 @@ describe("ConcurrentCaller", function () {
var ids1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'];
var ids2 = ['n', 'o', 'p', 'q'];
var makeFunc = function (id) {
return Zotero.Promise.coroutine(function* () {
return async function () {
if (logger) {
Zotero.debug("Running " + id);
}
@ -199,7 +199,7 @@ describe("ConcurrentCaller", function () {
}
var min = 10;
var max = 25;
yield Zotero.Promise.delay(
await Zotero.Promise.delay(
Math.floor(Math.random() * (max - min + 1)) + min
);
if (id == 'g') {
@ -223,7 +223,7 @@ describe("ConcurrentCaller", function () {
Zotero.debug("Finished " + id);
}
return id;
});
};
};
var funcs1 = ids1.map(makeFunc)
var funcs2 = ids2.map(makeFunc)
@ -236,7 +236,7 @@ describe("ConcurrentCaller", function () {
var promise1 = caller.start(funcs1);
var promise2 = caller.start(funcs2);
var results1 = yield promise1;
var results1 = await promise1;
assert.isTrue(promise2.isFulfilled());
assert.equal(running, 0);
@ -254,7 +254,7 @@ describe("ConcurrentCaller", function () {
})
it("should not stop on error if stopOnError isn't set", function* () {
it("should not stop on error if stopOnError isn't set", async function () {
var numConcurrent = 2;
var running = 0;
var finished = 0;
@ -263,7 +263,7 @@ describe("ConcurrentCaller", function () {
var ids1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'];
var ids2 = ['n', 'o', 'p', 'q'];
var makeFunc = function (id) {
return Zotero.Promise.coroutine(function* () {
return async function () {
if (logger) {
Zotero.debug("Running " + id);
}
@ -274,7 +274,7 @@ describe("ConcurrentCaller", function () {
}
var min = 10;
var max = 25;
yield Zotero.Promise.delay(
await Zotero.Promise.delay(
Math.floor(Math.random() * (max - min + 1)) + min
);
if (id == 'g') {
@ -298,7 +298,7 @@ describe("ConcurrentCaller", function () {
Zotero.debug("Finished " + id);
}
return id;
});
};
};
var funcs1 = ids1.map(makeFunc)
var funcs2 = ids2.map(makeFunc)
@ -310,7 +310,7 @@ describe("ConcurrentCaller", function () {
var promise1 = caller.start(funcs1);
var promise2 = caller.start(funcs2);
var results2 = yield promise2;
var results2 = await promise2;
assert.isTrue(promise1.isFulfilled());
assert.isTrue(promise2.isFulfilled());
@ -330,7 +330,7 @@ describe("ConcurrentCaller", function () {
})
describe("#wait()", function () {
it("should return when all tasks are done", function* () {
it("should return when all tasks are done", async function () {
var numConcurrent = 2;
var running = 0;
var finished = 0;
@ -339,7 +339,7 @@ describe("ConcurrentCaller", function () {
var ids1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'];
var ids2 = ['n', 'o', 'p', 'q'];
var makeFunc = function (id) {
return Zotero.Promise.coroutine(function* () {
return async function () {
if (logger) {
Zotero.debug("Running " + id);
}
@ -350,7 +350,7 @@ describe("ConcurrentCaller", function () {
}
var min = 10;
var max = 25;
yield Zotero.Promise.delay(
await Zotero.Promise.delay(
Math.floor(Math.random() * (max - min + 1)) + min
);
if (running > numConcurrent) {
@ -363,7 +363,7 @@ describe("ConcurrentCaller", function () {
Zotero.debug("Finished " + id);
}
return id;
});
};
};
var funcs1 = ids1.map(makeFunc)
var funcs2 = ids2.map(makeFunc)
@ -373,10 +373,10 @@ describe("ConcurrentCaller", function () {
logger
});
var promise1 = caller.start(funcs1);
yield Zotero.Promise.delay(10);
await Zotero.Promise.delay(10);
var promise2 = caller.start(funcs2);
yield caller.wait();
await caller.wait();
assert.isTrue(promise1.isFulfilled());
assert.isTrue(promise2.isFulfilled());

View file

@ -1,14 +1,14 @@
"use strict";
describe("Zotero.Creators", function() {
describe("Zotero.Creators", function () {
describe("#getIDFromData()", function () {
it("should create creator and cache data", function* () {
it("should create creator and cache data", async function () {
var data1 = {
firstName: "First",
lastName: "Last"
};
var creatorID;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
creatorID = await Zotero.Creators.getIDFromData(data1, true);
});
assert.typeOf(creatorID, 'number');
@ -20,7 +20,7 @@ describe("Zotero.Creators", function() {
});
describe("#cleanData()", function () {
it("should allow firstName to be null for fieldMode 1", function* () {
it("should allow firstName to be null for fieldMode 1", async function () {
var data = Zotero.Creators.cleanData({
firstName: null,
lastName: "Test",

View file

@ -92,8 +92,8 @@ describe("Zotero.DataDirectory", function () {
}
};
var populateDataDirectory = Zotero.Promise.coroutine(function* (dir, srcDir, automatic = false) {
yield OS.File.makeDir(dir, { unixMode: 0o755 });
var populateDataDirectory = async function (dir, srcDir, automatic = false) {
await OS.File.makeDir(dir, { unixMode: 0o755 });
let storageDir = OS.Path.join(dir, 'storage');
let storageDir1 = OS.Path.join(storageDir, 'AAAAAAAA');
let storageDir2 = OS.Path.join(storageDir, 'BBBBBBBB');
@ -101,59 +101,59 @@ describe("Zotero.DataDirectory", function () {
let migrationMarker = OS.Path.join(dir, Zotero.DataDirectory.MIGRATION_MARKER);
// Database
yield Zotero.File.putContentsAsync(OS.Path.join(dir, dbFilename), str1);
await Zotero.File.putContentsAsync(OS.Path.join(dir, dbFilename), str1);
// Database backup
yield Zotero.File.putContentsAsync(OS.Path.join(dir, dbFilename + '.bak'), str2);
await Zotero.File.putContentsAsync(OS.Path.join(dir, dbFilename + '.bak'), str2);
// 'storage' directory
yield OS.File.makeDir(storageDir, { unixMode: 0o755 });
await OS.File.makeDir(storageDir, { unixMode: 0o755 });
// 'storage' folders
yield OS.File.makeDir(storageDir1, { unixMode: 0o755 });
yield Zotero.File.putContentsAsync(OS.Path.join(storageDir1, storageFile1), str2);
yield OS.File.makeDir(storageDir2, { unixMode: 0o755 });
yield Zotero.File.putContentsAsync(OS.Path.join(storageDir2, storageFile2), str3);
await OS.File.makeDir(storageDir1, { unixMode: 0o755 });
await Zotero.File.putContentsAsync(OS.Path.join(storageDir1, storageFile1), str2);
await OS.File.makeDir(storageDir2, { unixMode: 0o755 });
await Zotero.File.putContentsAsync(OS.Path.join(storageDir2, storageFile2), str3);
// 'translators' and some translators
yield OS.File.makeDir(translatorsDir, { unixMode: 0o755 });
yield Zotero.File.putContentsAsync(OS.Path.join(translatorsDir, translatorName1), str4);
yield Zotero.File.putContentsAsync(OS.Path.join(translatorsDir, translatorName2), str5);
await OS.File.makeDir(translatorsDir, { unixMode: 0o755 });
await Zotero.File.putContentsAsync(OS.Path.join(translatorsDir, translatorName1), str4);
await Zotero.File.putContentsAsync(OS.Path.join(translatorsDir, translatorName2), str5);
// Migration marker
yield Zotero.File.putContentsAsync(
await Zotero.File.putContentsAsync(
migrationMarker,
JSON.stringify({
sourceDir: srcDir || dir,
automatic
})
);
});
};
var checkMigration = Zotero.Promise.coroutine(function* (options = {}) {
var checkMigration = async function (options = {}) {
if (!options.skipOldDir) {
assert.isFalse(yield OS.File.exists(oldDir));
assert.isFalse(await OS.File.exists(oldDir));
}
yield assert.eventually.equal(Zotero.File.getContentsAsync(newDBFile), str1);
yield assert.eventually.equal(Zotero.File.getContentsAsync(newDBFile + '.bak'), str2);
await assert.eventually.equal(Zotero.File.getContentsAsync(newDBFile), str1);
await assert.eventually.equal(Zotero.File.getContentsAsync(newDBFile + '.bak'), str2);
if (!options.skipStorageFile1) {
yield assert.eventually.equal(
await assert.eventually.equal(
Zotero.File.getContentsAsync(OS.Path.join(newStorageDir1, storageFile1)), str2
);
}
yield assert.eventually.equal(
await assert.eventually.equal(
Zotero.File.getContentsAsync(OS.Path.join(newStorageDir2, storageFile2)), str3
);
yield assert.eventually.equal(
await assert.eventually.equal(
Zotero.File.getContentsAsync(OS.Path.join(newTranslatorsDir, translatorName1)), str4
);
yield assert.eventually.equal(
await assert.eventually.equal(
Zotero.File.getContentsAsync(OS.Path.join(newTranslatorsDir, translatorName2)), str5
);
if (!options.skipNewMarker) {
assert.isFalse(yield OS.File.exists(newMigrationMarker));
assert.isFalse(await OS.File.exists(newMigrationMarker));
}
if (!options.skipSetDataDirectory) {
assert.ok(stubs.setDataDir.calledOnce);
assert.ok(stubs.setDataDir.calledWith(newDir));
}
});
};
describe("#checkForMigration()", function () {
@ -174,24 +174,24 @@ describe("Zotero.DataDirectory", function () {
tests.push([desc, fn]);
}
it("should skip automatic migration if target directory exists and is non-empty", function* () {
it("should skip automatic migration if target directory exists and is non-empty", async function () {
resetCommandMode();
resetFunctionMode();
yield populateDataDirectory(oldDir);
yield OS.File.remove(oldMigrationMarker);
yield OS.File.makeDir(newDir, { unixMode: 0o755 });
yield Zotero.File.putContentsAsync(OS.Path.join(newDir, 'a'), '');
await populateDataDirectory(oldDir);
await OS.File.remove(oldMigrationMarker);
await OS.File.makeDir(newDir, { unixMode: 0o755 });
await Zotero.File.putContentsAsync(OS.Path.join(newDir, 'a'), '');
yield assert.eventually.isFalse(Zotero.DataDirectory.checkForMigration(oldDir, newDir));
await assert.eventually.isFalse(Zotero.DataDirectory.checkForMigration(oldDir, newDir));
});
it("should skip automatic migration and show prompt if target directory is on a different drive", function* () {
it("should skip automatic migration and show prompt if target directory is on a different drive", async function () {
resetCommandMode();
resetFunctionMode();
yield populateDataDirectory(oldDir);
yield OS.File.remove(oldMigrationMarker);
await populateDataDirectory(oldDir);
await OS.File.remove(oldMigrationMarker);
stubs.isNewDirOnDifferentDrive.resolves(true);
@ -202,8 +202,8 @@ describe("Zotero.DataDirectory", function () {
);
}, 'cancel');
yield assert.eventually.isNotOk(Zotero.DataDirectory.checkForMigration(oldDir, newDir));
yield promise;
await assert.eventually.isNotOk(Zotero.DataDirectory.checkForMigration(oldDir, newDir));
await promise;
stubs.isNewDirOnDifferentDrive.resolves(false);
});
@ -215,13 +215,13 @@ describe("Zotero.DataDirectory", function () {
let origFunc = OS.File.move;
let fileMoveStub = sinon.stub(OS.File, "move").callsFake(function () {
if (OS.Path.basename(arguments[0]) == storageFile1) {
return Zotero.Promise.reject(new Error("Error"));
return Promise.reject(new Error("Error"));
}
else {
return origFunc(...arguments);
}
});
let stub1 = sinon.stub(Zotero.File, "reveal").returns(Zotero.Promise.resolve());
let stub1 = sinon.stub(Zotero.File, "reveal").returns(Promise.resolve());
let stub2 = sinon.stub(Zotero.Utilities.Internal, "quitZotero");
var promise2;
@ -230,7 +230,6 @@ describe("Zotero.DataDirectory", function () {
promise2 = waitForDialog(null, 'extra1');
// Make sure we're displaying the right message for this mode (automatic or manual)
Components.utils.import("resource://zotero/config.js");
assert.include(
dialog.document.documentElement.textContent,
Zotero.getString(
@ -261,18 +260,17 @@ describe("Zotero.DataDirectory", function () {
let origFunc = OS.File.move;
let stub1 = sinon.stub(OS.File, "move").callsFake(function () {
if (OS.Path.basename(arguments[0]) == dbFilename) {
return Zotero.Promise.reject(new Error("Error"));
return Promise.reject(new Error("Error"));
}
else {
return origFunc(...arguments);
}
});
let stub2 = sinon.stub(Zotero.File, "reveal").returns(Zotero.Promise.resolve());
let stub2 = sinon.stub(Zotero.File, "reveal").returns(Promise.resolve());
let stub3 = sinon.stub(Zotero.Utilities.Internal, "quitZotero");
var promise = waitForDialog(function (dialog) {
// Make sure we're displaying the right message for this mode (automatic or manual)
Components.utils.import("resource://zotero/config.js");
assert.include(
dialog.document.documentElement.textContent,
Zotero.getString(
@ -306,10 +304,10 @@ describe("Zotero.DataDirectory", function () {
});
});
it("should remove marker if old directory doesn't exist", function* () {
yield populateDataDirectory(newDir, oldDir);
yield Zotero.DataDirectory.checkForMigration(newDir, newDir);
yield checkMigration({
it("should remove marker if old directory doesn't exist", async function () {
await populateDataDirectory(newDir, oldDir);
await Zotero.DataDirectory.checkForMigration(newDir, newDir);
await checkMigration({
skipSetDataDirectory: true
});
});
@ -385,33 +383,33 @@ describe("Zotero.DataDirectory", function () {
resetFunctionMode();
});
it("should handle partial failure", function* () {
yield populateDataDirectory(oldDir);
it("should handle partial failure", async function () {
await populateDataDirectory(oldDir);
let origFunc = OS.File.move;
let stub1 = sinon.stub(OS.File, "move").callsFake(function () {
if (OS.Path.basename(arguments[0]) == storageFile1) {
return Zotero.Promise.reject(new Error("Error"));
return Promise.reject(new Error("Error"));
}
else {
return origFunc(...arguments);
}
});
yield Zotero.DataDirectory.migrate(oldDir, newDir);
await Zotero.DataDirectory.migrate(oldDir, newDir);
stub1.restore();
yield checkMigration({
await checkMigration({
skipOldDir: true,
skipStorageFile1: true,
skipNewMarker: true
});
assert.isTrue(yield OS.File.exists(OS.Path.join(oldStorageDir1, storageFile1)));
assert.isFalse(yield OS.File.exists(OS.Path.join(oldStorageDir2, storageFile2)));
assert.isFalse(yield OS.File.exists(oldTranslatorsDir));
assert.isTrue(yield OS.File.exists(newMigrationMarker));
assert.isTrue(await OS.File.exists(OS.Path.join(oldStorageDir1, storageFile1)));
assert.isFalse(await OS.File.exists(OS.Path.join(oldStorageDir2, storageFile2)));
assert.isFalse(await OS.File.exists(oldTranslatorsDir));
assert.isTrue(await OS.File.exists(newMigrationMarker));
});
});
});

View file

@ -1,31 +1,31 @@
"use strict";
describe("Zotero.DataObject", function() {
describe("Zotero.DataObject", function () {
var types = ['collection', 'item', 'search'];
describe("#library", function () {
it("should return a Zotero.Library", function* () {
var item = yield createDataObject('item');
it("should return a Zotero.Library", async function () {
var item = await createDataObject('item');
assert.equal(item.library, Zotero.Libraries.userLibrary);
});
});
describe("#libraryID", function () {
it("should return a libraryID", function* () {
var item = yield createDataObject('item');
it("should return a libraryID", async function () {
var item = await createDataObject('item');
assert.isNumber(item.libraryID);
assert.equal(item.libraryID, Zotero.Libraries.userLibraryID);
});
});
describe("#key", function () {
it("shouldn't update .loaded on get if unset", function* () {
it("shouldn't update .loaded on get if unset", async function () {
for (let type of types) {
let param;
if (type == 'item') {
param = 'book';
}
let obj = new Zotero[Zotero.Utilities.capitalize(type)](param);
let obj = new (Zotero[Zotero.Utilities.capitalize(type)])(param);
obj.libraryID = Zotero.Libraries.userLibraryID;
assert.isNull(obj.key, 'key is null for ' + type);
assert.isFalse(obj._loaded.primaryData, 'primary data not loaded for ' + type);
@ -35,40 +35,40 @@ describe("Zotero.DataObject", function() {
})
describe("#version", function () {
it("should be set to 0 after creating object", function* () {
it("should be set to 0 after creating object", async function () {
for (let type of types) {
let obj = yield createDataObject(type);
let obj = await createDataObject(type);
assert.equal(obj.version, 0);
yield obj.eraseTx();
await obj.eraseTx();
}
})
it("should be set after creating object", function* () {
it("should be set after creating object", async function () {
for (let type of types) {
let obj = yield createDataObject(type, { version: 1234 });
let obj = await createDataObject(type, { version: 1234 });
assert.equal(obj.version, 1234, type + " version mismatch");
yield obj.eraseTx();
await obj.eraseTx();
}
})
})
describe("#synced", function () {
it("should be set to false after creating object", function* () {
it("should be set to false after creating object", async function () {
for (let type of types) {
var obj = createUnsavedDataObject(type);
var id = yield obj.saveTx();
var id = await obj.saveTx();
assert.isFalse(obj.synced);
yield obj.eraseTx();
await obj.eraseTx();
}
});
it("should be set to false after modifying object", function* () {
it("should be set to false after modifying object", async function () {
for (let type of types) {
var obj = createUnsavedDataObject(type);
var id = yield obj.saveTx();
var id = await obj.saveTx();
obj.synced = true;
yield obj.saveTx();
await obj.saveTx();
if (type == 'item') {
obj.setField('title', Zotero.Utilities.randomString());
@ -76,30 +76,30 @@ describe("Zotero.DataObject", function() {
else {
obj.name = Zotero.Utilities.randomString();
}
yield obj.saveTx();
await obj.saveTx();
assert.isFalse(obj.synced);
yield obj.eraseTx();
await obj.eraseTx();
}
});
it("should be changed to true explicitly with no other changes", function* () {
it("should be changed to true explicitly with no other changes", async function () {
for (let type of types) {
var obj = createUnsavedDataObject(type);
var id = yield obj.saveTx();
var id = await obj.saveTx();
obj.synced = true;
yield obj.saveTx();
await obj.saveTx();
assert.isTrue(obj.synced);
yield obj.eraseTx();
await obj.eraseTx();
}
});
it("should be changed to true explicitly with other field changes", function* () {
it("should be changed to true explicitly with other field changes", async function () {
for (let type of types) {
var obj = createUnsavedDataObject(type);
var id = yield obj.saveTx();
var id = await obj.saveTx();
if (type == 'item') {
obj.setField('title', Zotero.Utilities.randomString());
@ -108,18 +108,18 @@ describe("Zotero.DataObject", function() {
obj.name = Zotero.Utilities.randomString();
}
obj.synced = true;
yield obj.saveTx();
await obj.saveTx();
assert.isTrue(obj.synced);
yield obj.eraseTx();
await obj.eraseTx();
}
});
it("should remain at true if set explicitly", function* () {
it("should remain at true if set explicitly", async function () {
for (let type of types) {
var obj = createUnsavedDataObject(type);
obj.synced = true;
var id = yield obj.saveTx();
var id = await obj.saveTx();
assert.isTrue(obj.synced);
if (type == 'item') {
@ -129,20 +129,20 @@ describe("Zotero.DataObject", function() {
obj.name = Zotero.Utilities.randomString();
}
obj.synced = true;
yield obj.saveTx();
await obj.saveTx();
assert.isTrue(obj.synced);
yield obj.eraseTx();
await obj.eraseTx();
}
});
it("should be unchanged if skipSyncedUpdate passed", function* () {
it("should be unchanged if skipSyncedUpdate passed", async function () {
for (let type of types) {
var obj = createUnsavedDataObject(type);
var id = yield obj.saveTx();
var id = await obj.saveTx();
obj.synced = true;
yield obj.saveTx();
await obj.saveTx();
if (type == 'item') {
obj.setField('title', Zotero.Utilities.randomString());
@ -150,12 +150,12 @@ describe("Zotero.DataObject", function() {
else {
obj.name = Zotero.Utilities.randomString();
}
yield obj.saveTx({
await obj.saveTx({
skipSyncedUpdate: true
});
assert.ok(obj.synced);
yield obj.eraseTx();
await obj.eraseTx();
}
});
})
@ -190,11 +190,11 @@ describe("Zotero.DataObject", function() {
});
describe("#loadPrimaryData()", function () {
it("should load unloaded primary data if partially set", function* () {
it("should load unloaded primary data if partially set", async function () {
var objs = {};
for (let type of types) {
let obj = createUnsavedDataObject(type);
yield obj.save({
await obj.save({
skipCache: true
});
objs[type] = {
@ -204,10 +204,10 @@ describe("Zotero.DataObject", function() {
}
for (let type of types) {
let obj = new Zotero[Zotero.Utilities.capitalize(type)];
let obj = new (Zotero[Zotero.Utilities.capitalize(type)]);
obj.libraryID = Zotero.Libraries.userLibraryID;
obj.key = objs[type].key;
yield obj.loadPrimaryData();
await obj.loadPrimaryData();
assert.equal(obj.version, objs[type].version);
}
});
@ -223,36 +223,36 @@ describe("Zotero.DataObject", function() {
})
describe("#loadAllData()", function () {
it("should load data on a regular item", function* () {
it("should load data on a regular item", async function () {
var item = new Zotero.Item('book');
var id = yield item.saveTx();
yield item.loadAllData();
var id = await item.saveTx();
await item.loadAllData();
assert.throws(item.getNote.bind(item), 'getNote() can only be called on notes and attachments');
})
it("should load data on an attachment item", function* () {
it("should load data on an attachment item", async function () {
var item = new Zotero.Item('attachment');
var id = yield item.saveTx();
yield item.loadAllData();
var id = await item.saveTx();
await item.loadAllData();
assert.equal(item.note, '');
})
it("should load data on a note item", function* () {
it("should load data on a note item", async function () {
var item = new Zotero.Item('note');
var id = yield item.saveTx();
yield item.loadAllData();
var id = await item.saveTx();
await item.loadAllData();
assert.equal(item.note, '');
})
})
describe("#hasChanged()", function () {
it("should return false if 'synced' was set but unchanged and nothing else changed", function* () {
it("should return false if 'synced' was set but unchanged and nothing else changed", async function () {
for (let type of types) {
// True
var obj = createUnsavedDataObject(type);
obj.synced = true;
var id = yield obj.saveTx();
var id = await obj.saveTx();
assert.isTrue(obj.synced);
obj.synced = true;
@ -261,18 +261,18 @@ describe("Zotero.DataObject", function() {
// False
var obj = createUnsavedDataObject(type);
obj.synced = false;
var id = yield obj.saveTx();
var id = await obj.saveTx();
assert.isFalse(obj.synced);
obj.synced = false;
assert.isFalse(obj.hasChanged(), type + " shouldn't be changed");
}
})
it("should return true if 'synced' was set but unchanged and another primary field changed", function* () {
it("should return true if 'synced' was set but unchanged and another primary field changed", async function () {
for (let type of types) {
let obj = createUnsavedDataObject(type);
obj.synced = true;
yield obj.saveTx();
await obj.saveTx();
obj.synced = true;
obj.version = 1234;
@ -283,28 +283,28 @@ describe("Zotero.DataObject", function() {
describe("#save()", function () {
it("should add new identifiers to cache", function* () {
it("should add new identifiers to cache", async function () {
for (let type of types) {
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
let obj = createUnsavedDataObject(type);
let id = yield obj.saveTx();
let id = await obj.saveTx();
let { libraryID, key } = objectsClass.getLibraryAndKeyFromID(id);
assert.typeOf(key, 'string');
assert.equal(objectsClass.getIDFromLibraryAndKey(libraryID, key), id);
}
})
it("should reset changed state on objects", function* () {
it("should reset changed state on objects", async function () {
for (let type of types) {
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
let obj = createUnsavedDataObject(type);
yield obj.saveTx();
await obj.saveTx();
assert.isFalse(obj.hasChanged());
}
})
it("should handle additional tag change in the middle of a save", function* () {
var item = yield createDataObject('item');
it("should handle additional tag change in the middle of a save", async function () {
var item = await createDataObject('item');
item.setTags(['a']);
var deferred = Zotero.Promise.defer();
@ -322,9 +322,9 @@ describe("Zotero.DataObject", function() {
origFunc(...arguments);
});
yield Zotero.Promise.all([item.saveTx(), deferred.promise]);
await Promise.all([item.saveTx(), deferred.promise]);
assert.sameMembers(item.getTags().map(o => o.tag), ['a', 'b']);
var tags = yield Zotero.DB.columnQueryAsync(
var tags = await Zotero.DB.columnQueryAsync(
"SELECT name FROM tags JOIN itemTags USING (tagID) WHERE itemID=?", item.id
);
assert.sameMembers(tags, ['a', 'b']);
@ -339,24 +339,24 @@ describe("Zotero.DataObject", function() {
});
});
it("should disallow saving to read-only libraries", function* () {
it("should disallow saving to read-only libraries", async function () {
let item = createUnsavedDataObject('item', { libraryID: group.libraryID });
var e = yield getPromiseError(item.saveTx());
var e = await getPromiseError(item.saveTx());
assert.ok(e);
assert.include(e.message, "Cannot edit item");
});
it("should allow saving if skipEditCheck is passed", function* () {
it("should allow saving if skipEditCheck is passed", async function () {
let item = createUnsavedDataObject('item', { libraryID: group.libraryID });
var e = yield getPromiseError(item.saveTx({
var e = await getPromiseError(item.saveTx({
skipEditCheck: true
}));
assert.isFalse(e);
});
it("should allow saving if skipAll is passed", function* () {
it("should allow saving if skipAll is passed", async function () {
let item = createUnsavedDataObject('item', { libraryID: group.libraryID });
var e = yield getPromiseError(item.saveTx({
var e = await getPromiseError(item.saveTx({
skipAll: true
}));
assert.isFalse(e);
@ -365,14 +365,14 @@ describe("Zotero.DataObject", function() {
})
describe("#erase()", function () {
it("shouldn't trigger notifier if skipNotifier is passed", function* () {
it("shouldn't trigger notifier if skipNotifier is passed", async function () {
let observerIDs = [];
let promises = [];
for (let type of types) {
let obj = yield createDataObject(type);
let obj = await createDataObject(type);
// For items, test automatic child item deletion
if (type == 'item') {
yield createDataObject(type, { itemType: 'note', parentID: obj.id });
await createDataObject(type, { itemType: 'note', parentID: obj.id });
}
let deferred = Zotero.Promise.defer();
@ -388,11 +388,11 @@ describe("Zotero.DataObject", function() {
type,
'test'
));
yield obj.eraseTx({
await obj.eraseTx({
skipNotifier: true
});
}
yield Zotero.Promise.all(promises)
await Promise.all(promises)
// Give notifier time to trigger
.timeout(100).catch(Zotero.Promise.TimeoutError, (e) => {})
@ -401,15 +401,15 @@ describe("Zotero.DataObject", function() {
}
})
it("should delete object versions from sync cache", function* () {
it("should delete object versions from sync cache", async function () {
for (let type of types) {
let obj = yield createDataObject(type);
let obj = await createDataObject(type);
let libraryID = obj.libraryID;
let key = obj.key;
let json = obj.toJSON();
yield Zotero.Sync.Data.Local.saveCacheObjects(type, libraryID, [json]);
yield obj.eraseTx();
let versions = yield Zotero.Sync.Data.Local.getCacheObjectVersions(
await Zotero.Sync.Data.Local.saveCacheObjects(type, libraryID, [json]);
await obj.eraseTx();
let versions = await Zotero.Sync.Data.Local.getCacheObjectVersions(
type, libraryID, key
);
assert.lengthOf(versions, 0);
@ -417,61 +417,61 @@ describe("Zotero.DataObject", function() {
})
})
describe("#updateVersion()", function() {
it("should update the object version", function* () {
describe("#updateVersion()", function () {
it("should update the object version", async function () {
for (let type of types) {
let obj = yield createDataObject(type);
let obj = await createDataObject(type);
assert.equal(obj.version, 0);
yield obj.updateVersion(1234);
await obj.updateVersion(1234);
assert.equal(obj.version, 1234);
assert.isFalse(obj.hasChanged());
obj.synced = true;
assert.ok(obj.hasChanged());
yield obj.updateVersion(1235);
await obj.updateVersion(1235);
assert.equal(obj.version, 1235);
assert.ok(obj.hasChanged());
yield obj.eraseTx();
await obj.eraseTx();
}
})
})
describe("#updateSynced()", function() {
it("should update the object sync status", function* () {
describe("#updateSynced()", function () {
it("should update the object sync status", async function () {
for (let type of types) {
let obj = yield createDataObject(type);
let obj = await createDataObject(type);
assert.isFalse(obj.synced);
yield obj.updateSynced(false);
await obj.updateSynced(false);
assert.isFalse(obj.synced);
assert.isFalse(obj.hasChanged());
yield obj.updateSynced(true);
await obj.updateSynced(true);
assert.ok(obj.synced);
assert.isFalse(obj.hasChanged());
obj.version = 1234;
assert.ok(obj.hasChanged());
yield obj.updateSynced(false);
await obj.updateSynced(false);
assert.isFalse(obj.synced);
assert.ok(obj.hasChanged());
yield obj.eraseTx();
await obj.eraseTx();
}
})
it("should clear changed status", function* () {
it("should clear changed status", async function () {
var item = createUnsavedDataObject('item');
item.synced = true;
yield item.saveTx();
await item.saveTx();
// Only synced changed
item.synced = false;
assert.isTrue(item.hasChanged());
assert.isTrue(item._changed.primaryData.synced);
yield item.updateSynced(true);
await item.updateSynced(true);
assert.isFalse(item.hasChanged());
// Should clear primary data change object
assert.isUndefined(item._changed.primaryData);
@ -481,7 +481,7 @@ describe("Zotero.DataObject", function() {
item.synced = false;
assert.isTrue(item.hasChanged());
assert.isTrue(item._changed.primaryData.synced);
yield item.updateSynced(true);
await item.updateSynced(true);
assert.isTrue(item.hasChanged());
// Should clear only 'synced' change status
assert.isUndefined(item._changed.primaryData.synced);
@ -498,13 +498,13 @@ describe("Zotero.DataObject", function() {
}
describe("#addRelation()", function () {
it("should add a relation to an object", function* () {
it("should add a relation to an object", async function () {
for (let type of types) {
let predicate = 'owl:sameAs';
let object = makeObjectURI(type);
let obj = createUnsavedDataObject(type);
obj.addRelation(predicate, object);
yield obj.saveTx();
await obj.saveTx();
var relations = obj.getRelations();
assert.property(relations, predicate);
assert.include(relations[predicate], object);
@ -513,16 +513,16 @@ describe("Zotero.DataObject", function() {
})
describe("#removeRelation()", function () {
it("should remove a relation from an object", function* () {
it("should remove a relation from an object", async function () {
for (let type of types) {
let predicate = 'owl:sameAs';
let object = makeObjectURI(type);
let obj = createUnsavedDataObject(type);
obj.addRelation(predicate, object);
yield obj.saveTx();
await obj.saveTx();
obj.removeRelation(predicate, object);
yield obj.saveTx();
await obj.saveTx();
assert.lengthOf(Object.keys(obj.getRelations()), 0);
}
@ -530,20 +530,20 @@ describe("Zotero.DataObject", function() {
})
describe("#hasRelation()", function () {
it("should return true if an object has a given relation", function* () {
it("should return true if an object has a given relation", async function () {
for (let type of types) {
let predicate = 'owl:sameAs';
let object = makeObjectURI(type);
let obj = createUnsavedDataObject(type);
obj.addRelation(predicate, object);
yield obj.saveTx();
await obj.saveTx();
assert.ok(obj.hasRelation(predicate, object));
}
})
})
describe("#setRelations()", function () {
it("shouldn't allow invalid 'relations' predicates", function* () {
it("shouldn't allow invalid 'relations' predicates", async function () {
var item = new Zotero.Item("book");
assert.throws(() => {
item.setRelations({
@ -554,14 +554,14 @@ describe("Zotero.DataObject", function() {
});
describe("#_getLinkedObject()", function () {
it("should return a linked object in another library", function* () {
var group = yield getGroup();
var item1 = yield createDataObject('item');
var item2 = yield createDataObject('item', { libraryID: group.libraryID });
it("should return a linked object in another library", async function () {
var group = await getGroup();
var item1 = await createDataObject('item');
var item2 = await createDataObject('item', { libraryID: group.libraryID });
var item2URI = Zotero.URI.getItemURI(item2);
yield item2.addLinkedItem(item1);
var linkedItem = yield item1.getLinkedItem(item2.libraryID);
await item2.addLinkedItem(item1);
var linkedItem = await item1.getLinkedItem(item2.libraryID);
assert.equal(linkedItem.id, item2.id);
})
@ -578,38 +578,38 @@ describe("Zotero.DataObject", function() {
assert.isFalse(linkedItem);
})
it("shouldn't return reverse linked objects by default", function* () {
var group = yield getGroup();
var item1 = yield createDataObject('item');
it("shouldn't return reverse linked objects by default", async function () {
var group = await getGroup();
var item1 = await createDataObject('item');
var item1URI = Zotero.URI.getItemURI(item1);
var item2 = yield createDataObject('item', { libraryID: group.libraryID });
var item2 = await createDataObject('item', { libraryID: group.libraryID });
yield item2.addLinkedItem(item1);
var linkedItem = yield item2.getLinkedItem(item1.libraryID);
await item2.addLinkedItem(item1);
var linkedItem = await item2.getLinkedItem(item1.libraryID);
assert.isFalse(linkedItem);
})
it("should return reverse linked objects with bidirectional flag", function* () {
var group = yield getGroup();
var item1 = yield createDataObject('item');
it("should return reverse linked objects with bidirectional flag", async function () {
var group = await getGroup();
var item1 = await createDataObject('item');
var item1URI = Zotero.URI.getItemURI(item1);
var item2 = yield createDataObject('item', { libraryID: group.libraryID });
var item2 = await createDataObject('item', { libraryID: group.libraryID });
yield item2.addLinkedItem(item1);
var linkedItem = yield item2.getLinkedItem(item1.libraryID, true);
await item2.addLinkedItem(item1);
var linkedItem = await item2.getLinkedItem(item1.libraryID, true);
assert.equal(linkedItem.id, item1.id);
})
})
describe("#_addLinkedObject()", function () {
it("should add an owl:sameAs relation", function* () {
var group = yield getGroup();
var item1 = yield createDataObject('item');
it("should add an owl:sameAs relation", async function () {
var group = await getGroup();
var item1 = await createDataObject('item');
var dateModified = item1.getField('dateModified');
var item2 = yield createDataObject('item', { libraryID: group.libraryID });
var item2 = await createDataObject('item', { libraryID: group.libraryID });
var item2URI = Zotero.URI.getItemURI(item2);
yield item2.addLinkedItem(item1);
await item2.addLinkedItem(item1);
var preds = item1.getRelationsByPredicate(Zotero.Relations.linkedObjectPredicate);
assert.include(preds, item2URI);

View file

@ -1,8 +1,8 @@
"use strict";
describe("Zotero.DataObjectUtilities", function() {
describe("Zotero.DataObjectUtilities", function () {
describe("#patch()", function () {
it("should omit 'collections' if it doesn't exist", function* () {
it("should omit 'collections' if it doesn't exist", async function () {
var patchBase = {
collections: ['AAAAAAAA']
};
@ -11,7 +11,7 @@ describe("Zotero.DataObjectUtilities", function() {
assert.notProperty(obj, 'collections');
})
it("should include modified 'conditions'", function* () {
it("should include modified 'conditions'", async function () {
var patchBase = {
name: "Search",
conditions: [
@ -105,9 +105,9 @@ describe("Zotero.DataObjectUtilities", function() {
// Fields
//
describe("fields", function () {
it("should not show empty items as different", function* () {
it("should not show empty items as different", async function () {
var id1, id2, json1, json2;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
var item = new Zotero.Item('book');
id1 = await item.save();
json1 = item.toJSON();
@ -120,7 +120,7 @@ describe("Zotero.DataObjectUtilities", function() {
var changes = Zotero.DataObjectUtilities.diff(json1, json2);
assert.lengthOf(changes, 0);
yield Zotero.Items.erase([id1, id2]);
await Zotero.Items.erase([id1, id2]);
})
it("should not show empty strings as different", function () {
@ -190,7 +190,7 @@ describe("Zotero.DataObjectUtilities", function() {
})
describe("notes", function () {
it("should ignore sanitization changes", function* () {
it("should ignore sanitization changes", async function () {
var json1 = {
note: "<p>\u00a0</p>"
};

View file

@ -4,7 +4,7 @@ describe("Zotero.DataObjects", function () {
var types = ['collection', 'item', 'search'];
describe("#get()", function () {
it("should return false for nonexistent objects", function* () {
it("should return false for nonexistent objects", async function () {
assert.isFalse(Zotero.Items.get(3464363));
});
});
@ -19,10 +19,10 @@ describe("Zotero.DataObjects", function () {
});
describe("#getLibraryAndKeyFromID()", function () {
it("should return a libraryID and key within a transaction", function* () {
it("should return a libraryID and key within a transaction", async function () {
for (let type of types) {
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
let obj = createUnsavedDataObject(type);
await obj.save();
@ -37,12 +37,12 @@ describe("Zotero.DataObjects", function () {
}
});
it("should return false after a save failure", function* () {
it("should return false after a save failure", async function () {
for (let type of types) {
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
var obj;
try {
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
obj = createUnsavedDataObject(type);
await obj.save();
throw 'Aborting transaction -- ignore';
@ -60,12 +60,12 @@ describe("Zotero.DataObjects", function () {
})
describe("#exists()", function () {
it("should return false after object is deleted", function* () {
it("should return false after object is deleted", async function () {
for (let type of types) {
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
let obj = yield createDataObject(type);
let obj = await createDataObject(type);
let id = obj.id;
yield obj.eraseTx();
await obj.eraseTx();
assert.isFalse(objectsClass.exists(id), type + " does not exist");
}
})
@ -193,8 +193,8 @@ describe("Zotero.DataObjects", function () {
describe("#_setIdentifier", function () {
it("should not allow an id change", function* () {
var item = yield createDataObject('item');
it("should not allow an id change", async function () {
var item = await createDataObject('item');
try {
item.id = item.id + 1;
}
@ -205,8 +205,8 @@ describe("Zotero.DataObjects", function () {
assert.fail("ID change allowed");
})
it("should not allow a key change", function* () {
var item = yield createDataObject('item');
it("should not allow a key change", async function () {
var item = await createDataObject('item');
try {
item.key = Zotero.DataObjectUtilities.generateKey();
}
@ -217,7 +217,7 @@ describe("Zotero.DataObjects", function () {
assert.fail("Key change allowed");
})
it("should not allow key to be set if id is set", function* () {
it("should not allow key to be set if id is set", async function () {
var item = createUnsavedDataObject('item');
item.id = Zotero.Utilities.rand(100000, 1000000);
try {
@ -231,7 +231,7 @@ describe("Zotero.DataObjects", function () {
assert.fail("ID change allowed");
})
it("should not allow id to be set if key is set", function* () {
it("should not allow id to be set if key is set", async function () {
var item = createUnsavedDataObject('item');
item.libraryID = Zotero.Libraries.userLibraryID;
item.key = Zotero.DataObjectUtilities.generateKey();
@ -245,7 +245,7 @@ describe("Zotero.DataObjects", function () {
assert.fail("Key change allowed");
})
it("should not allow key to be set if library isn't set", function* () {
it("should not allow key to be set if library isn't set", async function () {
var item = createUnsavedDataObject('item');
try {
item.key = Zotero.DataObjectUtilities.generateKey();

View file

@ -1,4 +1,4 @@
describe("Zotero.Date", function() {
describe("Zotero.Date", function () {
describe("#getMonths()", function () {
var origLocale;
var englishShort = [
@ -50,7 +50,7 @@ describe("Zotero.Date", function() {
assert.sameMembers(months, englishShort);
});
it("should resolve to English from unknown locale", function* () {
it("should resolve to English from unknown locale", async function () {
Zotero.locale = 'zz';
Zotero.Date.init();
let months = Zotero.Date.getMonths().short;
@ -58,7 +58,7 @@ describe("Zotero.Date", function() {
assert.sameMembers(months, englishShort);
});
it("shouldn't repeat English with unknown locale", function* () {
it("shouldn't repeat English with unknown locale", async function () {
Zotero.locale = 'zz';
Zotero.Date.init();
let months = Zotero.Date.getMonths(true).short;
@ -99,7 +99,7 @@ describe("Zotero.Date", function() {
assert.sameMembers(months, frenchLong.concat(englishLong));
});
it("should resolve from two-letter locale", function* () {
it("should resolve from two-letter locale", async function () {
Zotero.locale = 'fr';
Zotero.Date.init();
let months = Zotero.Date.getMonths().short;
@ -107,7 +107,7 @@ describe("Zotero.Date", function() {
assert.sameMembers(months, frenchShort);
});
it("should resolve from unknown four-letter locale with common prefix", function* () {
it("should resolve from unknown four-letter locale with common prefix", async function () {
Zotero.locale = 'fr-ZZ';
Zotero.Date.init();
let months = Zotero.Date.getMonths().short;
@ -118,7 +118,7 @@ describe("Zotero.Date", function() {
});
describe("#sqlToDate()", function () {
it("should convert an SQL local date into a JS Date object", function* () {
it("should convert an SQL local date into a JS Date object", async function () {
var d1 = new Date();
var sqlDate = d1.getFullYear()
+ '-'
@ -139,7 +139,7 @@ describe("Zotero.Date", function() {
);
})
it("should convert an SQL UTC date into a JS Date object", function* () {
it("should convert an SQL UTC date into a JS Date object", async function () {
var date = "2016-02-27 22:00:00";
date = Zotero.Date.sqlToDate(date, true);
assert.equal(date.getTime(), 1456610400000);
@ -282,7 +282,7 @@ describe("Zotero.Date", function() {
assert.equal(o.order, 'd');
});
it("should work in translator sandbox", function* () {
it("should work in translator sandbox", async function () {
var item = createUnsavedDataObject('item');
item.libraryID = Zotero.Libraries.userLibraryID;
item.setField('date', '2017-01-17');
@ -296,13 +296,13 @@ describe("Zotero.Date", function() {
assert.isTrue(worked);
assert.include(obj.string, "{2017}");
});
yield translation.translate();
await translation.translate();
assert.ok(called);
});
});
describe("#isHTTPDate()", function() {
it("should determine whether a date is an RFC 2822 compliant date", function() {
describe("#isHTTPDate()", function () {
it("should determine whether a date is an RFC 2822 compliant date", function () {
assert.ok(Zotero.Date.isHTTPDate("Mon, 13 Jun 2016 02:09:08 +4000"));
assert.ok(Zotero.Date.isHTTPDate("13 Jun 2016 02:09:08 +4000"));
assert.ok(Zotero.Date.isHTTPDate("13 Jun 2016 02:09 +4000"));

View file

@ -1,4 +1,4 @@
describe("Zotero.DB", function() {
describe("Zotero.DB", function () {
var tmpTable = "tmpDBTest";
before(function* () {
@ -32,44 +32,44 @@ describe("Zotero.DB", function() {
}
})
it("should throw an error if no parameters are passed for a query with placeholders", function* () {
var e = yield getPromiseError(Zotero.DB.queryAsync("SELECT itemID FROM items WHERE itemID=?"));
it("should throw an error if no parameters are passed for a query with placeholders", async function () {
var e = await getPromiseError(Zotero.DB.queryAsync("SELECT itemID FROM items WHERE itemID=?"));
assert.ok(e);
assert.include(e.message, "for query containing placeholders");
})
it("should throw an error if too few parameters are passed", function* () {
var e = yield getPromiseError(Zotero.DB.queryAsync("SELECT itemID FROM items WHERE itemID=? OR itemID=?", [1]));
it("should throw an error if too few parameters are passed", async function () {
var e = await getPromiseError(Zotero.DB.queryAsync("SELECT itemID FROM items WHERE itemID=? OR itemID=?", [1]));
assert.ok(e);
assert.include(e.message, "Incorrect number of parameters provided for query");
})
it("should throw an error if too many parameters are passed", function* () {
var e = yield getPromiseError(Zotero.DB.queryAsync("SELECT itemID FROM items WHERE itemID=?", [1, 2]));
it("should throw an error if too many parameters are passed", async function () {
var e = await getPromiseError(Zotero.DB.queryAsync("SELECT itemID FROM items WHERE itemID=?", [1, 2]));
assert.ok(e);
assert.include(e.message, "Incorrect number of parameters provided for query");
})
it("should throw an error if too many parameters are passed for numbered placeholders", function* () {
var e = yield getPromiseError(Zotero.DB.queryAsync("SELECT itemID FROM items WHERE itemID=?1 OR itemID=?1", [1, 2]));
it("should throw an error if too many parameters are passed for numbered placeholders", async function () {
var e = await getPromiseError(Zotero.DB.queryAsync("SELECT itemID FROM items WHERE itemID=?1 OR itemID=?1", [1, 2]));
assert.ok(e);
assert.include(e.message, "Incorrect number of parameters provided for query");
})
it("should accept a single placeholder given as a value", function* () {
var rows = yield Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=?", 2);
it("should accept a single placeholder given as a value", async function () {
var rows = await Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=?", 2);
assert.lengthOf(rows, 1);
assert.equal(rows[0].a, 1);
})
it("should accept a single placeholder given as an array", function* () {
var rows = yield Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=?", [2]);
it("should accept a single placeholder given as an array", async function () {
var rows = await Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=?", [2]);
assert.lengthOf(rows, 1);
assert.equal(rows[0].a, 1);
})
it("should accept multiple placeholders", function* () {
var rows = yield Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=? OR b=?", [2, 4]);
it("should accept multiple placeholders", async function () {
var rows = await Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=? OR b=?", [2, 4]);
assert.lengthOf(rows, 2);
assert.equal(rows[0].a, 1);
assert.equal(rows[1].a, 3);
@ -82,64 +82,64 @@ describe("Zotero.DB", function() {
assert.equal(rows[1].a, 3);
});
it("should accept a single placeholder within parentheses", function* () {
var rows = yield Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b IN (?)", 2);
it("should accept a single placeholder within parentheses", async function () {
var rows = await Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b IN (?)", 2);
assert.lengthOf(rows, 1);
assert.equal(rows[0].a, 1);
})
it("should accept multiple placeholders within parentheses", function* () {
var rows = yield Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b IN (?, ?)", [2, 4]);
it("should accept multiple placeholders within parentheses", async function () {
var rows = await Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b IN (?, ?)", [2, 4]);
assert.lengthOf(rows, 2);
assert.equal(rows[0].a, 1);
assert.equal(rows[1].a, 3);
})
it("should replace =? with IS NULL if NULL is passed as a value", function* () {
var rows = yield Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=?", null);
it("should replace =? with IS NULL if NULL is passed as a value", async function () {
var rows = await Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=?", null);
assert.lengthOf(rows, 1);
assert.equal(rows[0].a, 5);
})
it("should replace =? with IS NULL if NULL is passed in an array", function* () {
var rows = yield Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=?", [null]);
it("should replace =? with IS NULL if NULL is passed in an array", async function () {
var rows = await Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=?", [null]);
assert.lengthOf(rows, 1);
assert.equal(rows[0].a, 5);
})
it("should replace ? with NULL for placeholders within parentheses in INSERT statements", function* () {
yield Zotero.DB.queryAsync("CREATE TEMPORARY TABLE tmp_srqwnfpwpinss (a, b)");
it("should replace ? with NULL for placeholders within parentheses in INSERT statements", async function () {
await Zotero.DB.queryAsync("CREATE TEMPORARY TABLE tmp_srqwnfpwpinss (a, b)");
// Replace ", ?"
yield Zotero.DB.queryAsync("INSERT INTO tmp_srqwnfpwpinss (a, b) VALUES (?, ?)", [1, null]);
await Zotero.DB.queryAsync("INSERT INTO tmp_srqwnfpwpinss (a, b) VALUES (?, ?)", [1, null]);
assert.equal(
(yield Zotero.DB.valueQueryAsync("SELECT a FROM tmp_srqwnfpwpinss WHERE b IS NULL")),
((await Zotero.DB.valueQueryAsync("SELECT a FROM tmp_srqwnfpwpinss WHERE b IS NULL"))),
1
);
// Replace "(?"
yield Zotero.DB.queryAsync("DELETE FROM tmp_srqwnfpwpinss");
yield Zotero.DB.queryAsync("INSERT INTO tmp_srqwnfpwpinss (a, b) VALUES (?, ?)", [null, 2]);
await Zotero.DB.queryAsync("DELETE FROM tmp_srqwnfpwpinss");
await Zotero.DB.queryAsync("INSERT INTO tmp_srqwnfpwpinss (a, b) VALUES (?, ?)", [null, 2]);
assert.equal(
(yield Zotero.DB.valueQueryAsync("SELECT b FROM tmp_srqwnfpwpinss WHERE a IS NULL")),
((await Zotero.DB.valueQueryAsync("SELECT b FROM tmp_srqwnfpwpinss WHERE a IS NULL"))),
2
);
yield Zotero.DB.queryAsync("DROP TABLE tmp_srqwnfpwpinss");
await Zotero.DB.queryAsync("DROP TABLE tmp_srqwnfpwpinss");
})
it("should throw an error if NULL is passed for placeholder within parentheses in a SELECT statement", function* () {
var e = yield getPromiseError(Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b IN (?)", null));
it("should throw an error if NULL is passed for placeholder within parentheses in a SELECT statement", async function () {
var e = await getPromiseError(Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b IN (?)", null));
assert.ok(e);
assert.include(e.message, "NULL cannot be used for parenthesized placeholders in SELECT queries");
})
it("should handle numbered parameters", function* () {
var rows = yield Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=?1 "
it("should handle numbered parameters", async function () {
var rows = await Zotero.DB.queryAsync("SELECT a FROM " + tmpTable + " WHERE b=?1 "
+ "UNION SELECT b FROM " + tmpTable + " WHERE b=?1", 2);
assert.lengthOf(rows, 2);
assert.equal(rows[0].a, 1);
assert.equal(rows[1].a, 2);
})
it("should throw an error if onRow throws an error", function* () {
it("should throw an error if onRow throws an error", async function () {
var i = 0;
var e = Zotero.DB.queryAsync(
"SELECT * FROM " + tmpTable,
@ -153,15 +153,15 @@ describe("Zotero.DB", function() {
}
}
);
e = yield getPromiseError(e)
e = await getPromiseError(e)
assert.ok(e);
assert.equal(e.message, "Failed");
});
it("should stop gracefully if onRow calls cancel()", function* () {
it("should stop gracefully if onRow calls cancel()", async function () {
var i = 0;
var rows = [];
yield Zotero.DB.queryAsync(
await Zotero.DB.queryAsync(
"SELECT * FROM " + tmpTable,
false,
{
@ -181,7 +181,7 @@ describe("Zotero.DB", function() {
describe("#executeTransaction()", function () {
it("should serialize concurrent transactions", Zotero.Promise.coroutine(function* () {
it("should serialize concurrent transactions", async function () {
var resolve1, resolve2, reject1, reject2;
var promise1 = new Promise(function (resolve, reject) {
resolve1 = resolve;
@ -212,10 +212,10 @@ describe("Zotero.DB", function() {
.then(resolve2)
.catch(reject2);
yield Zotero.Promise.all([promise1, promise2]);
}));
await Promise.all([promise1, promise2]);
});
it("should serialize queued transactions", function* () {
it("should serialize queued transactions", async function () {
var resolve1, resolve2, reject1, reject2, resolve3, reject3;
var promise1 = new Promise(function (resolve, reject) {
resolve1 = resolve;
@ -263,13 +263,13 @@ describe("Zotero.DB", function() {
.then(resolve3)
.catch(reject3);
yield Zotero.Promise.all([promise1, promise2, promise3]);
await Promise.all([promise1, promise2, promise3]);
})
it("should roll back on error", function* () {
yield Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (1)");
it("should roll back on error", async function () {
await Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (1)");
try {
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
await Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (2)");
throw 'Aborting transaction -- ignore';
});
@ -277,19 +277,19 @@ describe("Zotero.DB", function() {
catch (e) {
if (typeof e != 'string' || !e.startsWith('Aborting transaction')) throw e;
}
var count = yield Zotero.DB.valueQueryAsync("SELECT COUNT(*) FROM " + tmpTable + "");
var count = await Zotero.DB.valueQueryAsync("SELECT COUNT(*) FROM " + tmpTable + "");
assert.equal(count, 1);
var conn = yield Zotero.DB._getConnectionAsync();
var conn = await Zotero.DB._getConnectionAsync();
assert.isFalse(conn.transactionInProgress);
yield Zotero.DB.queryAsync("DROP TABLE " + tmpTable);
await Zotero.DB.queryAsync("DROP TABLE " + tmpTable);
});
it("should run onRollback callbacks", function* () {
it("should run onRollback callbacks", async function () {
var callbackRan = false;
try {
yield Zotero.DB.executeTransaction(
await Zotero.DB.executeTransaction(
async function () {
await Zotero.DB.queryAsync("INSERT INTO " + tmpTable + " VALUES (1)");
throw 'Aborting transaction -- ignore';
@ -306,7 +306,7 @@ describe("Zotero.DB", function() {
}
assert.ok(callbackRan);
yield Zotero.DB.queryAsync("DROP TABLE " + tmpTable);
await Zotero.DB.queryAsync("DROP TABLE " + tmpTable);
});
it("should time out on nested transactions", async function () {
@ -327,11 +327,11 @@ describe("Zotero.DB", function() {
assert.equal(e.name, "TimeoutError");
});
it("should run onRollback callbacks for timed-out nested transactions", function* () {
it("should run onRollback callbacks for timed-out nested transactions", async function () {
var callback1Ran = false;
var callback2Ran = false;
try {
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(
async function () {},
{

View file

@ -43,13 +43,13 @@ describe("Duplicate Items", function () {
}
describe("Merging", function () {
it("should merge two items in duplicates view", function* () {
var item1 = yield createDataObject('item', { setTitle: true });
it("should merge two items in duplicates view", async function () {
var item1 = await createDataObject('item', { setTitle: true });
var item2 = item1.clone();
yield item2.saveTx();
await item2.saveTx();
var uri2 = Zotero.URI.getItemURI(item2);
yield merge(item1.id);
await merge(item1.id);
// Items should be gone
var iv = zp.itemsView;
@ -62,16 +62,16 @@ describe("Duplicate Items", function () {
assert.equal(rels[pred], uri2);
});
it("should combine collections from all items", function* () {
var collection1 = yield createDataObject('collection');
var collection2 = yield createDataObject('collection');
it("should combine collections from all items", async function () {
var collection1 = await createDataObject('collection');
var collection2 = await createDataObject('collection');
var item1 = yield createDataObject('item', { setTitle: true, collections: [collection1.id] });
var item1 = await createDataObject('item', { setTitle: true, collections: [collection1.id] });
var item2 = item1.clone();
item2.setCollections([collection2.id]);
yield item2.saveTx();
await item2.saveTx();
yield merge(item1.id);
await merge(item1.id);
// Items should be gone
var iv = zp.itemsView;

View file

@ -5,66 +5,66 @@ describe("Zotero.FeedItem", function () {
yield feed.saveTx();
libraryID = feed.libraryID;
});
after(function() {
after(function () {
return clearFeeds();
});
it("should be an instance of Zotero.Item", function() {
it("should be an instance of Zotero.Item", function () {
assert.instanceOf(new Zotero.FeedItem(), Zotero.Item);
});
describe("#libraryID", function() {
it("should reference a feed", function() {
describe("#libraryID", function () {
it("should reference a feed", function () {
let feedItem = new Zotero.FeedItem();
assert.doesNotThrow(function() {feedItem.libraryID = feed.libraryID});
assert.throws(function() {feedItem.libraryID = Zotero.Libraries.userLibraryID}, /^libraryID must reference a feed$/);
assert.doesNotThrow(function () {feedItem.libraryID = feed.libraryID});
assert.throws(function () {feedItem.libraryID = Zotero.Libraries.userLibraryID}, /^libraryID must reference a feed$/);
});
});
describe("#constructor()", function* () {
it("should accept required fields as arguments", function* () {
it("should accept required fields as arguments", async function () {
let guid = Zotero.randomString();
let feedItem = new Zotero.FeedItem();
yield assert.isRejected(feedItem.saveTx());
await assert.isRejected(feedItem.saveTx());
feedItem = new Zotero.FeedItem('book', { guid });
feedItem.libraryID = libraryID;
yield assert.isFulfilled(feedItem.saveTx());
await assert.isFulfilled(feedItem.saveTx());
assert.equal(feedItem.itemTypeID, Zotero.ItemTypes.getID('book'));
assert.equal(feedItem.guid, guid);
assert.equal(feedItem.libraryID, libraryID);
});
});
describe("#isFeedItem", function() {
it("should be true", function() {
describe("#isFeedItem", function () {
it("should be true", function () {
let feedItem = new Zotero.FeedItem();
assert.isTrue(feedItem.isFeedItem);
});
it("should be falsy for regular item", function() {
it("should be falsy for regular item", function () {
let item = new Zotero.Item();
assert.notOk(item.isFeedItem);
})
});
describe("#guid", function() {
it("should not be settable to a non-string value", function() {
describe("#guid", function () {
it("should not be settable to a non-string value", function () {
let feedItem = new Zotero.FeedItem();
assert.throws(() => feedItem.guid = 1);
});
it("should be settable to any string", function() {
it("should be settable to any string", function () {
let feedItem = new Zotero.FeedItem();
feedItem.guid = 'foo';
assert.equal(feedItem.guid, 'foo');
});
it("should not be possible to change guid after saving item", function* () {
let feedItem = yield createDataObject('feedItem', { libraryID });
it("should not be possible to change guid after saving item", async function () {
let feedItem = await createDataObject('feedItem', { libraryID });
assert.throws(() => feedItem.guid = 'bar');
});
});
describe("#isRead", function() {
it("should be false by default", function* () {
let feedItem = yield createDataObject('feedItem', { libraryID });
describe("#isRead", function () {
it("should be false by default", async function () {
let feedItem = await createDataObject('feedItem', { libraryID });
assert.isFalse(feedItem.isRead);
});
it("should be settable and persist after saving", function* () {
it("should be settable and persist after saving", async function () {
this.timeout(5000);
let feedItem = new Zotero.FeedItem('book', { guid: Zotero.randomString() });
feedItem.libraryID = feed.libraryID;
@ -82,16 +82,16 @@ describe("Zotero.FeedItem", function () {
expectedTimestamp = Date.now();
feedItem.isRead = true;
yield Zotero.Promise.delay(2001);
yield feedItem.saveTx();
await Zotero.Promise.delay(2001);
await feedItem.saveTx();
readTime = yield Zotero.DB.valueQueryAsync('SELECT readTime FROM feedItems WHERE itemID=?', feedItem.id);
readTime = await Zotero.DB.valueQueryAsync('SELECT readTime FROM feedItems WHERE itemID=?', feedItem.id);
readTime = Zotero.Date.sqlToDate(readTime, true).getTime();
assert.closeTo(readTime, expectedTimestamp, 2000, 'read timestamp is correct in the DB');
});
});
describe("#fromJSON()", function() {
it("should attempt to parse non ISO-8601 dates", function* () {
describe("#fromJSON()", function () {
it("should attempt to parse non ISO-8601 dates", async function () {
Zotero.locale = 'en-US';
Zotero.Date.init();
var data = [
@ -125,39 +125,39 @@ describe("Zotero.FeedItem", function () {
}
})
});
describe("#save()", function() {
it("should require feed being set", function* () {
describe("#save()", function () {
it("should require feed being set", async function () {
let feedItem = new Zotero.FeedItem('book', { guid: Zotero.randomString() });
// Defaults to user library ID
yield assert.isRejected(feedItem.saveTx(), /^Cannot add /);
await assert.isRejected(feedItem.saveTx(), /^Cannot add /);
});
it("should require GUID being set", function* () {
it("should require GUID being set", async function () {
let feedItem = new Zotero.FeedItem('book');
feedItem.libraryID = feed.libraryID;
yield assert.isRejected(feedItem.saveTx(), /^GUID must be set before saving FeedItem$/);
await assert.isRejected(feedItem.saveTx(), /^GUID must be set before saving FeedItem$/);
});
it("should require a unique GUID", function* () {
it("should require a unique GUID", async function () {
let guid = Zotero.randomString();
let feedItem1 = yield createDataObject('feedItem', { libraryID, guid });
let feedItem1 = await createDataObject('feedItem', { libraryID, guid });
let feedItem2 = createUnsavedDataObject('feedItem', { libraryID, guid });
yield assert.isRejected(feedItem2.saveTx());
await assert.isRejected(feedItem2.saveTx());
// But we should be able to save it after deleting the original feed
yield feedItem1.eraseTx();
yield assert.isFulfilled(feedItem2.saveTx());
await feedItem1.eraseTx();
await assert.isFulfilled(feedItem2.saveTx());
});
it("should require item type being set", function* () {
it("should require item type being set", async function () {
let feedItem = new Zotero.FeedItem(null, { guid: Zotero.randomString() });
feedItem.libraryID = feed.libraryID;
yield assert.isRejected(feedItem.saveTx(), /^Item type must be set before saving$/);
await assert.isRejected(feedItem.saveTx(), /^Item type must be set before saving$/);
});
it("should save feed item", function* () {
it("should save feed item", async function () {
let guid = Zotero.randomString();
let feedItem = createUnsavedDataObject('feedItem', { libraryID, guid });
yield assert.isFulfilled(feedItem.saveTx());
await assert.isFulfilled(feedItem.saveTx());
feedItem = yield Zotero.FeedItems.getAsync(feedItem.id);
feedItem = await Zotero.FeedItems.getAsync(feedItem.id);
assert.ok(feedItem);
assert.equal(feedItem.guid, guid);
});
@ -182,51 +182,51 @@ describe("Zotero.FeedItem", function () {
assert.deepEqual(feedItemsJSON, allTypesAndFields);
});
it("should allow saving after editing data", function* () {
let feedItem = yield createDataObject('feedItem', { libraryID });
it("should allow saving after editing data", async function () {
let feedItem = await createDataObject('feedItem', { libraryID });
feedItem.setField('title', 'bar');
yield assert.isFulfilled(feedItem.saveTx());
await assert.isFulfilled(feedItem.saveTx());
assert.equal(feedItem.getField('title'), 'bar');
});
});
describe("#erase()", function() {
it("should erase an existing feed item", function* () {
let feedItem = yield createDataObject('feedItem', { libraryID });
describe("#erase()", function () {
it("should erase an existing feed item", async function () {
let feedItem = await createDataObject('feedItem', { libraryID });
yield feedItem.eraseTx();
assert.isFalse(yield Zotero.FeedItems.getAsync(feedItem.id));
await feedItem.eraseTx();
assert.isFalse(await Zotero.FeedItems.getAsync(feedItem.id));
//yield assert.isRejected(feedItem.EraseTx(), "does not allow erasing twice");
});
});
describe("#toggleRead()", function() {
it('should toggle state', function* () {
let item = yield createDataObject('feedItem', { libraryID });
describe("#toggleRead()", function () {
it('should toggle state', async function () {
let item = await createDataObject('feedItem', { libraryID });
item.isRead = false;
yield item.saveTx();
await item.saveTx();
yield item.toggleRead();
await item.toggleRead();
assert.isTrue(item.isRead, "item is toggled to read state");
});
it('should save if specified state is different from current', function* (){
let item = yield createDataObject('feedItem', { libraryID });
it('should save if specified state is different from current', async function () {
let item = await createDataObject('feedItem', { libraryID });
item.isRead = false;
yield item.saveTx();
await item.saveTx();
sinon.spy(item, 'save');
yield item.toggleRead(true);
await item.toggleRead(true);
assert.isTrue(item.save.called, "item was saved on toggle read");
item.save.resetHistory();
yield item.toggleRead(true);
await item.toggleRead(true);
assert.isFalse(item.save.called, "item was not saved on toggle read to same state");
});
});
describe('#translate()', function() {
describe('#translate()', function () {
var win;
before(function* () {
@ -242,41 +242,41 @@ describe("Zotero.FeedItem", function () {
win.close()
});
it('should translate and save items', function* () {
var feedItem = yield createDataObject('feedItem', {libraryID});
it('should translate and save items', async function () {
var feedItem = await createDataObject('feedItem', {libraryID});
var url = getTestDataUrl('metadata/journalArticle-single.html');
feedItem.setField('url', url);
yield feedItem.saveTx();
await feedItem.saveTx();
yield feedItem.translate();
await feedItem.translate();
assert.equal(feedItem.getField('title'), 'Scarcity or Abundance? Preserving the Past in a Digital Era');
});
it('should translate and save items to corresponding library and collection', function* () {
let group = yield createGroup();
let collection = yield createDataObject('collection', {libraryID: group.libraryID});
it('should translate and save items to corresponding library and collection', async function () {
let group = await createGroup();
let collection = await createDataObject('collection', {libraryID: group.libraryID});
var feedItem = yield createDataObject('feedItem', {libraryID});
var feedItem = await createDataObject('feedItem', {libraryID});
var url = getTestDataUrl('metadata/journalArticle-single.html');
feedItem.setField('url', url);
yield feedItem.saveTx();
await feedItem.saveTx();
yield feedItem.translate(group.libraryID, collection.id);
await feedItem.translate(group.libraryID, collection.id);
let item = collection.getChildItems(false, false)[0];
assert.equal(item.getField('title'), 'Scarcity or Abundance? Preserving the Past in a Digital Era');
});
it('should clone the item to corresponding library and collection if no translators available', function* () {
let group = yield createGroup();
let collection = yield createDataObject('collection', {libraryID: group.libraryID});
it('should clone the item to corresponding library and collection if no translators available', async function () {
let group = await createGroup();
let collection = await createDataObject('collection', {libraryID: group.libraryID});
var feedItem = yield createDataObject('feedItem', {libraryID, title: 'test'});
var feedItem = await createDataObject('feedItem', {libraryID, title: 'test'});
var url = getTestDataUrl('test.html');
feedItem.setField('url', url);
yield feedItem.saveTx();
await feedItem.saveTx();
yield feedItem.translate(group.libraryID, collection.id);
await feedItem.translate(group.libraryID, collection.id);
let item = collection.getChildItems(false, false)[0];

View file

@ -3,11 +3,11 @@ describe("Zotero.FeedItems", function () {
before(function* () {
feed = yield createFeed({ name: 'foo', url: 'http://' + Zotero.randomString() + '.com' });
});
after(function() {
after(function () {
return clearFeeds();
});
describe("#getMarkedAsRead", function() {
describe("#getMarkedAsRead", function () {
var items = [];
var result;
@ -27,18 +27,18 @@ describe("Zotero.FeedItems", function () {
result = (await Zotero.FeedItems.getMarkedAsRead(feed.libraryID)).map(x => x.id);
});
it('should get all marked as read items', function() {
it('should get all marked as read items', function () {
assert.include(result, items[0].id);
assert.include(result, items[2].id);
});
it('should not include items that were not marked', function() {
it('should not include items that were not marked', function () {
assert.notInclude(result, items[1].id);
assert.notInclude(result, items[3].id);
});
});
describe("#markAsReadByGUID", function() {
describe("#markAsReadByGUID", function () {
var items = [];
var result;
before(function* () {
@ -51,47 +51,47 @@ describe("Zotero.FeedItems", function () {
}
yield Zotero.FeedItems.markAsReadByGUID([items[0].guid, items[2].guid]);
});
it('should mark as read only specified guids', function() {
it('should mark as read only specified guids', function () {
assert.isTrue(items[0].isRead);
assert.isTrue(items[2].isRead);
});
it('should leave other items marked unread', function() {
it('should leave other items marked unread', function () {
assert.isFalse(items[1].isRead);
assert.isFalse(items[3].isRead);
});
});
describe("#getIDFromGUID()", function() {
it("should return false for non-existent GUID", function* () {
let id = yield Zotero.FeedItems.getIDFromGUID(Zotero.randomString());
describe("#getIDFromGUID()", function () {
it("should return false for non-existent GUID", async function () {
let id = await Zotero.FeedItems.getIDFromGUID(Zotero.randomString());
assert.isFalse(id);
});
it("should return feed item id from GUID", function* () {
let feedItem = yield createDataObject('feedItem', { libraryID: feed.libraryID });
yield feedItem.saveTx();
it("should return feed item id from GUID", async function () {
let feedItem = await createDataObject('feedItem', { libraryID: feed.libraryID });
await feedItem.saveTx();
let id2 = yield Zotero.FeedItems.getIDFromGUID(feedItem.guid);
let id2 = await Zotero.FeedItems.getIDFromGUID(feedItem.guid);
assert.equal(id2, feedItem.id);
});
});
describe("#getAsyncByGUID()", function() {
it("should return feed item from GUID", function* () {
describe("#getAsyncByGUID()", function () {
it("should return feed item from GUID", async function () {
let guid = Zotero.randomString();
let feedItem = yield createDataObject('feedItem', { guid, libraryID: feed.libraryID });
yield feedItem.saveTx();
let feedItem = await createDataObject('feedItem', { guid, libraryID: feed.libraryID });
await feedItem.saveTx();
let feedItem2 = yield Zotero.FeedItems.getAsyncByGUID(guid);
let feedItem2 = await Zotero.FeedItems.getAsyncByGUID(guid);
assert.equal(feedItem2.id, feedItem.id);
});
it("should return false for non-existent GUID", function* () {
let feedItem = yield Zotero.FeedItems.getAsyncByGUID(Zotero.randomString());
it("should return false for non-existent GUID", async function () {
let feedItem = await Zotero.FeedItems.getAsyncByGUID(Zotero.randomString());
assert.isFalse(feedItem);
});
});
describe("#toggleReadByID()", function() {
describe("#toggleReadByID()", function () {
var save, feed, items, ids;
before(function() {
before(function () {
save = sinon.spy(Zotero.FeedItem.prototype, 'save');
});
@ -114,34 +114,34 @@ describe("Zotero.FeedItems", function () {
yield clearFeeds();
});
after(function() {
after(function () {
save.restore();
});
it('should toggle all items read if at least one unread', function* () {
it('should toggle all items read if at least one unread', async function () {
items[0].isRead = false;
yield items[0].saveTx();
await items[0].saveTx();
yield Zotero.FeedItems.toggleReadByID(ids);
await Zotero.FeedItems.toggleReadByID(ids);
for(let i = 0; i < 10; i++) {
assert.isTrue(save.thisValues[i].isRead, "#toggleRead called with true");
}
});
it('should toggle all items unread if all read', function* () {
yield Zotero.FeedItems.toggleReadByID(ids);
it('should toggle all items unread if all read', async function () {
await Zotero.FeedItems.toggleReadByID(ids);
for(let i = 0; i < 10; i++) {
assert.isFalse(save.thisValues[i].isRead, "#toggleRead called with false");
}
});
it('should toggle all items unread if unread state specified', function* () {
it('should toggle all items unread if unread state specified', async function () {
items[0].isRead = false;
yield items[0].saveTx();
await items[0].saveTx();
yield Zotero.FeedItems.toggleReadByID(ids, false);
await Zotero.FeedItems.toggleReadByID(ids, false);
for(let i = 0; i < 10; i++) {
assert.isFalse(save.thisValues[i].isRead, "#toggleRead called with true");

View file

@ -38,12 +38,12 @@ describe("Zotero.FeedReader", function () {
var win;
before(async function() {
before(async function () {
// Browser window is needed as parent window to load the feed reader scripts.
win = await loadZoteroWindow();
});
after(async function() {
after(async function () {
if (win) {
win.close();
}
@ -51,77 +51,77 @@ describe("Zotero.FeedReader", function () {
});
describe('FeedReader()', function () {
it('should throw if url not provided', function() {
it('should throw if url not provided', function () {
assert.throw(() => new Zotero.FeedReader())
});
it('should throw if url invalid', function() {
it('should throw if url invalid', function () {
assert.throw(() => new Zotero.FeedReader('invalid url'))
});
});
describe('#process()', function() {
it('should reject if the provided url is not a valid feed', function* () {
describe('#process()', function () {
it('should reject if the provided url is not a valid feed', async function () {
let fr = new Zotero.FeedReader(htmlUrl);
let e = yield getPromiseError(fr.process());
let e = await getPromiseError(fr.process());
assert.ok(e);
e = yield getPromiseError(fr._feedItems[fr._feedItems.length-1].promise);
e = await getPromiseError(fr._feedItems[fr._feedItems.length-1].promise);
assert.ok(e);
});
it('should set #feedProperties on FeedReader object', function* () {
it('should set #feedProperties on FeedReader object', async function () {
let fr = new Zotero.FeedReader(rssFeedURL);
assert.throw(() => fr.feedProperties);
yield fr.process();
await fr.process();
assert.ok(fr.feedProperties);
});
});
describe('#terminate()', function() {
it('should reject last feed item and feed processing promise if feed not processed yet', function* () {
describe('#terminate()', function () {
it('should reject last feed item and feed processing promise if feed not processed yet', async function () {
let fr = new Zotero.FeedReader(rssFeedURL);
fr.terminate("test");
let e = yield getPromiseError(fr.process());
let e = await getPromiseError(fr.process());
assert.ok(e);
e = yield getPromiseError(fr._feedItems[fr._feedItems.length-1].promise);
e = await getPromiseError(fr._feedItems[fr._feedItems.length-1].promise);
assert.ok(e);
});
it('should reject last feed item if feed processed', function* () {
it('should reject last feed item if feed processed', async function () {
let fr = new Zotero.FeedReader(rssFeedURL);
yield fr.process();
await fr.process();
fr.terminate("test");
let e = yield getPromiseError(fr._feedItems[fr._feedItems.length-1].promise);
let e = await getPromiseError(fr._feedItems[fr._feedItems.length-1].promise);
assert.ok(e);
});
});
describe('#feedProperties', function() {
describe('#feedProperties', function () {
it('should throw if accessed before feed is processed', function () {
let fr = new Zotero.FeedReader(rssFeedURL);
assert.throw(() => fr.feedProperties);
});
it('should have correct values for a sparse feed', function* () {
it('should have correct values for a sparse feed', async function () {
let fr = new Zotero.FeedReader(rssFeedURL);
yield fr.process();
await fr.process();
assert.deepEqual(fr.feedProperties, rssFeedInfo);
});
it('should have correct values for a detailed feed', function* () {
it('should have correct values for a detailed feed', async function () {
let fr = new Zotero.FeedReader(detailedRSSFeedURL);
yield fr.process();
await fr.process();
assert.deepEqual(fr.feedProperties, detailedRSSFeedInfo);
});
});
describe('#ItemIterator()', function() {
it('should throw if called before feed is resolved', function() {
describe('#ItemIterator()', function () {
it('should throw if called before feed is resolved', function () {
let fr = new Zotero.FeedReader(rssFeedURL);
assert.throw(() => new fr.ItemIterator);
});
it('should parse items correctly for a sparse RSS feed', function* () {
it('should parse items correctly for a sparse RSS feed', async function () {
let expected = { guid: 'http://liftoff.msfc.nasa.gov/2003/06/03.html#item573',
title: 'Star City',
abstractNote: 'How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia\'s <a xmlns="http://www.w3.org/1999/xhtml" href="http://howe.iki.rssi.ru/GCTC/gctc_e.htm">Star City</a>.',
@ -134,13 +134,13 @@ describe("Zotero.FeedReader", function () {
};
let fr = new Zotero.FeedReader(rssFeedURL);
yield fr.process();
await fr.process();
let itemIterator = new fr.ItemIterator();
let item = yield itemIterator.next().value;
let item = await itemIterator.next().value;
assert.deepEqual(item, expected);
});
it('should parse items correctly for a detailed RSS feed', function* () {
it('should parse items correctly for a detailed RSS feed', async function () {
let expected = {
guid: 'http://www.example.com/item1',
title: 'Title 1',
@ -166,13 +166,13 @@ describe("Zotero.FeedReader", function () {
};
let fr = new Zotero.FeedReader(detailedRSSFeedURL);
yield fr.process();
await fr.process();
let itemIterator = new fr.ItemIterator();
let item = yield itemIterator.next().value;
let item = await itemIterator.next().value;
assert.deepEqual(item, expected);
});
it('should parse items correctly for an RSS feed with journal article metadata', function* () {
it('should parse items correctly for an RSS feed with journal article metadata', async function () {
let expected = {
guid: 'https://www.mdpi.com/2311-5521/9/6/120',
title: 'Environmental Hydraulics, Turbulence, and Sediment Transport, Second Edition',
@ -198,13 +198,13 @@ describe("Zotero.FeedReader", function () {
};
let fr = new Zotero.FeedReader(articleMetadataRSSFeedURL);
yield fr.process();
await fr.process();
let itemIterator = new fr.ItemIterator();
let item = yield itemIterator.next().value;
let item = await itemIterator.next().value;
assert.deepEqual(item, expected);
});
it("should parse item from an Atom feed", function* () {
it("should parse item from an Atom feed", async function () {
let expected = {
guid: 'http://www.example.com/item1',
title: 'Title 1',
@ -222,19 +222,19 @@ describe("Zotero.FeedReader", function () {
};
let fr = new Zotero.FeedReader(atomFeedURL);
yield fr.process();
await fr.process();
let itemIterator = new fr.ItemIterator();
let item = yield itemIterator.next().value;
let item = await itemIterator.next().value;
assert.deepEqual(item, expected);
});
it('should resolve last item with null', function* () {
it('should resolve last item with null', async function () {
let fr = new Zotero.FeedReader(rssFeedURL);
yield fr.process();
await fr.process();
let itemIterator = new fr.ItemIterator();
let item;
while(item = yield itemIterator.next().value);
while(item = await itemIterator.next().value);
assert.isNull(item);
});
@ -244,7 +244,7 @@ describe("Zotero.FeedReader", function () {
const itemIterator = new fr.ItemIterator();
let item;
for (let i = 0; i < 2; i++) {
// eslint-disable-next-line no-await-in-loop
item = await itemIterator.next().value;
}
@ -270,7 +270,7 @@ describe("Zotero.FeedReader", function () {
const itemIterator = new fr.ItemIterator();
let item;
for (let i = 0; i < 2; i++) {
// eslint-disable-next-line no-await-in-loop
item = await itemIterator.next().value;
}

View file

@ -1,83 +1,83 @@
describe("Zotero.Feed", function() {
describe("Zotero.Feed", function () {
// Clean up after after tests
after(function* () {
yield clearFeeds();
});
it("should be an instance of Zotero.Library", function() {
it("should be an instance of Zotero.Library", function () {
let feed = new Zotero.Feed();
assert.instanceOf(feed, Zotero.Library);
});
describe("#constructor()", function() {
it("should accept required fields as arguments", function* () {
describe("#constructor()", function () {
it("should accept required fields as arguments", async function () {
let feed = new Zotero.Feed();
yield assert.isRejected(feed.saveTx(), /^Feed name not set$/);
await assert.isRejected(feed.saveTx(), /^Feed name not set$/);
feed = new Zotero.Feed({
name: 'Test ' + Zotero.randomString(),
url: 'http://www.' + Zotero.randomString() + '.com'
});
yield assert.isFulfilled(feed.saveTx());
await assert.isFulfilled(feed.saveTx());
});
});
describe("#isFeed", function() {
it("should be true", function() {
describe("#isFeed", function () {
it("should be true", function () {
let feed = new Zotero.Feed();
assert.isTrue(feed.isFeed);
});
it("should be falsy for regular Library", function() {
it("should be falsy for regular Library", function () {
let library = new Zotero.Library();
assert.notOk(library.isFeed);
});
});
describe("#editable", function() {
it("should always be not editable", function* () {
let feed = yield createFeed();
describe("#editable", function () {
it("should always be not editable", async function () {
let feed = await createFeed();
assert.isFalse(feed.editable);
feed.editable = true;
assert.isFalse(feed.editable);
yield feed.saveTx();
await feed.saveTx();
assert.isFalse(feed.editable);
});
it("should allow adding items without editCheck override", function* () {
let feed = yield createFeed();
it("should allow adding items without editCheck override", async function () {
let feed = await createFeed();
let feedItem = new Zotero.FeedItem('book', { guid: Zotero.randomString() });
feedItem.libraryID = feed.libraryID;
yield assert.isFulfilled(feedItem.saveTx());
await assert.isFulfilled(feedItem.saveTx());
});
});
describe("#libraryTypeID", function () {
it("should be undefind", function* () {
let feed = yield createFeed();
it("should be undefind", async function () {
let feed = await createFeed();
assert.isUndefined(feed.libraryTypeID);
});
});
describe("#url", function() {
it("should throw if trying to set an invalid URL", function *() {
describe("#url", function () {
it("should throw if trying to set an invalid URL", async function () {
let feed = new Zotero.Feed({ name: 'Test ' + Zotero.randomString() });
assert.throws(function() {feed.url = 'foo'}, /^Invalid feed URL /);
assert.throws(function() {feed.url = 'ftp://example.com'}, /^Invalid feed URL /);
assert.throws(function () {feed.url = 'foo'}, /^Invalid feed URL /);
assert.throws(function () {feed.url = 'ftp://example.com'}, /^Invalid feed URL /);
});
});
describe("#save()", function() {
it("should save a new feed to the feed library", function* () {
describe("#save()", function () {
it("should save a new feed to the feed library", async function () {
let props = {
name: 'Test ' + Zotero.randomString(),
url: 'http://' + Zotero.randomString() + '.com/'
};
let feed = yield createFeed(props);
let feed = await createFeed(props);
assert.equal(feed.name, props.name, "name is correct");
assert.equal(feed.url.toLowerCase(), props.url.toLowerCase(), "url is correct");
});
it("should save a feed with all fields set", function* () {
it("should save a feed with all fields set", async function () {
let props = {
name: 'Test ' + Zotero.randomString(),
url: 'http://' + Zotero.randomString() + '.com/',
@ -86,7 +86,7 @@ describe("Zotero.Feed", function() {
cleanupUnreadAfter: 30
};
let feed = yield createFeed(props);
let feed = await createFeed(props);
assert.equal(feed.name, props.name, "name is correct");
assert.equal(feed.url.toLowerCase(), props.url.toLowerCase(), "url is correct");
@ -98,127 +98,127 @@ describe("Zotero.Feed", function() {
assert.isNull(feed.lastUpdate, "lastUpdate is null");
assert.isNull(feed.lastCheckError, "lastCheckError is null");
});
it("should throw if name or url are missing", function *() {
it("should throw if name or url are missing", async function () {
let feed = new Zotero.Feed();
yield assert.isRejected(feed.saveTx(), /^Feed name not set$/);
await assert.isRejected(feed.saveTx(), /^Feed name not set$/);
feed.name = 'Test ' + Zotero.randomString();
yield assert.isRejected(feed.saveTx(), /^Feed URL not set$/);
await assert.isRejected(feed.saveTx(), /^Feed URL not set$/);
feed = new Zotero.Feed();
feed.url = 'http://' + Zotero.randomString() + '.com';
yield assert.isRejected(feed.saveTx(), /^Feed name not set$/);
await assert.isRejected(feed.saveTx(), /^Feed name not set$/);
});
it("should not allow saving a feed with the same url", function *() {
it("should not allow saving a feed with the same url", async function () {
let url = 'http://' + Zotero.randomString() + '.com';
let feed1 = yield createFeed({ url });
let feed1 = await createFeed({ url });
let feed2 = new Zotero.Feed({ name: 'Test ' + Zotero.randomString(), url });
yield assert.isRejected(feed2.saveTx(), /^Feed for URL already exists: /);
await assert.isRejected(feed2.saveTx(), /^Feed for URL already exists: /);
// Perform check with normalized URL
feed2.url = url + '/';
yield assert.isRejected(feed2.saveTx(), /^Feed for URL already exists: /);
await assert.isRejected(feed2.saveTx(), /^Feed for URL already exists: /);
feed2.url = url.toUpperCase();
yield assert.isRejected(feed2.saveTx(), /^Feed for URL already exists: /);
await assert.isRejected(feed2.saveTx(), /^Feed for URL already exists: /);
});
it("should allow saving a feed with the same name", function *() {
it("should allow saving a feed with the same name", async function () {
let name = 'Test ' + Zotero.randomString();
let feed1 = yield createFeed({ name });
let feed1 = await createFeed({ name });
let feed2 = new Zotero.Feed({ name , url: 'http://' + Zotero.randomString() + '.com' });
yield assert.isFulfilled(feed2.saveTx(), "allow saving feed with an existing name");
await assert.isFulfilled(feed2.saveTx(), "allow saving feed with an existing name");
assert.equal(feed1.name, feed2.name, "feed names remain the same");
});
it("should save field to DB after editing", function* () {
let feed = yield createFeed();
it("should save field to DB after editing", async function () {
let feed = await createFeed();
feed.name = 'bar';
yield feed.saveTx();
await feed.saveTx();
let dbVal = yield Zotero.DB.valueQueryAsync('SELECT name FROM feeds WHERE libraryID=?', feed.libraryID);
let dbVal = await Zotero.DB.valueQueryAsync('SELECT name FROM feeds WHERE libraryID=?', feed.libraryID);
assert.equal(feed.name, 'bar');
assert.equal(dbVal, feed.name);
});
it("should add a new synced setting after creation", function* () {
it("should add a new synced setting after creation", async function () {
let url = 'http://' + Zotero.Utilities.randomString(10, 'abcde') + '.com/feed.rss';
let syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
assert.notOk(syncedFeeds[url]);
yield createFeed({url});
await createFeed({url});
syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
assert.ok(syncedFeeds[url]);
});
it("should remove previous feed and add a new one if url changed", function* () {
let feed = yield createFeed();
it("should remove previous feed and add a new one if url changed", async function () {
let feed = await createFeed();
let syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
assert.ok(syncedFeeds[feed.url]);
let oldUrl = feed.url;
feed.url = 'http://' + Zotero.Utilities.randomString(10, 'abcde') + '.com/feed.rss';
yield feed.saveTx();
await feed.saveTx();
syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
assert.notOk(syncedFeeds[oldUrl]);
assert.ok(syncedFeeds[feed.url]);
});
it('should update syncedSettings if `name`, `url`, `refreshInterval` or `cleanupUnreadAfter` was modified', function* () {
let feed = yield createFeed();
it('should update syncedSettings if `name`, `url`, `refreshInterval` or `cleanupUnreadAfter` was modified', async function () {
let feed = await createFeed();
let syncedSetting = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
yield Zotero.SyncedSettings.set(Zotero.Libraries.userLibraryID, 'feeds', syncedSetting, 0, true);
await Zotero.SyncedSettings.set(Zotero.Libraries.userLibraryID, 'feeds', syncedSetting, 0, true);
feed.name = "New name";
yield feed.saveTx();
await feed.saveTx();
assert.isFalse(Zotero.SyncedSettings.getMetadata(Zotero.Libraries.userLibraryID, 'feeds').synced)
});
it('should not update syncedSettings if `name`, `url`, `refreshInterval` or `cleanupUnreadAfter` were not modified', function* () {
let feed = yield createFeed();
it('should not update syncedSettings if `name`, `url`, `refreshInterval` or `cleanupUnreadAfter` were not modified', async function () {
let feed = await createFeed();
let syncedSetting = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
yield Zotero.SyncedSettings.set(Zotero.Libraries.userLibraryID, 'feeds', syncedSetting, 0, true);
await Zotero.SyncedSettings.set(Zotero.Libraries.userLibraryID, 'feeds', syncedSetting, 0, true);
feed._set('_feedLastCheck', Zotero.Date.dateToSQL(new Date(), true));
yield feed.saveTx();
await feed.saveTx();
assert.isTrue(Zotero.SyncedSettings.getMetadata(Zotero.Libraries.userLibraryID, 'feeds').synced)
});
});
describe("#erase()", function() {
it("should erase a saved feed", function* () {
let feed = yield createFeed();
describe("#erase()", function () {
it("should erase a saved feed", async function () {
let feed = await createFeed();
let id = feed.libraryID;
let url = feed.url;
yield feed.eraseTx();
await feed.eraseTx();
assert.isFalse(Zotero.Libraries.exists(id));
assert.isFalse(Zotero.Feeds.existsByURL(url));
let dbValue = yield Zotero.DB.valueQueryAsync('SELECT COUNT(*) FROM feeds WHERE libraryID=?', id);
let dbValue = await Zotero.DB.valueQueryAsync('SELECT COUNT(*) FROM feeds WHERE libraryID=?', id);
assert.equal(dbValue, '0');
});
it("should clear feedItems from cache", function* () {
let feed = yield createFeed();
it("should clear feedItems from cache", async function () {
let feed = await createFeed();
let feedItem = yield createDataObject('feedItem', { libraryID: feed.libraryID });
assert.ok(yield Zotero.FeedItems.getAsync(feedItem.id));
let feedItem = await createDataObject('feedItem', { libraryID: feed.libraryID });
assert.ok(await Zotero.FeedItems.getAsync(feedItem.id));
yield feed.eraseTx();
await feed.eraseTx();
assert.notOk(yield Zotero.FeedItems.getAsync(feedItem.id));
assert.notOk(await Zotero.FeedItems.getAsync(feedItem.id));
});
it("should remove synced settings", function* () {
it("should remove synced settings", async function () {
let url = 'http://' + Zotero.Utilities.randomString(10, 'abcde') + '.com/feed.rss';
let feed = yield createFeed({url});
let feed = await createFeed({url});
let syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
assert.ok(syncedFeeds[feed.url]);
yield feed.eraseTx();
await feed.eraseTx();
syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
assert.notOk(syncedFeeds[url]);
@ -226,11 +226,11 @@ describe("Zotero.Feed", function() {
});
});
describe("#storeSyncedSettings", function() {
it("should store settings for feed in compact format", function* () {
describe("#storeSyncedSettings", function () {
it("should store settings for feed in compact format", async function () {
let url = 'http://' + Zotero.Utilities.randomString().toLowerCase() + '.com/feed.rss';
let settings = [Zotero.Utilities.randomString(), 1, 30, 1];
let feed = yield createFeed({
let feed = await createFeed({
url,
name: settings[0],
cleanupReadAfter: settings[1],
@ -243,7 +243,7 @@ describe("Zotero.Feed", function() {
});
});
describe("#clearExpiredItems()", function() {
describe("#clearExpiredItems()", function () {
var feed, readExpiredFI, unreadExpiredFI, readFeedItem, feedItem, readStillInFeed, feedItemIDs;
before(function* (){
@ -289,31 +289,31 @@ describe("Zotero.Feed", function() {
feedItemIDs = yield Zotero.FeedItems.getAll(feed.libraryID).map((row) => row.id);
});
it('should clear expired items', function() {
it('should clear expired items', function () {
assert.notInclude(feedItemIDs, readExpiredFI.id, "feed no longer contains expired read feed item");
assert.notInclude(feedItemIDs, unreadExpiredFI.id, "feed no longer contains expired feed item");
});
it('should not clear read items that have not expired yet', function() {
it('should not clear read items that have not expired yet', function () {
assert.include(feedItemIDs, readFeedItem.id, "feed still contains new feed item");
});
it('should not clear read items that are still in rss', function() {
it('should not clear read items that are still in rss', function () {
assert.include(feedItemIDs, readStillInFeed.id, "feed still contains read still in rss feed item");
});
it('should not clear unread items', function() {
it('should not clear unread items', function () {
assert.include(feedItemIDs, feedItem.id, "feed still contains new feed item");
});
});
describe('#updateFeed()', function() {
describe('#updateFeed()', function () {
var feed, scheduleNextFeedCheck;
var feedUrl = getTestDataUrl("feed.rss");
var modifiedFeedUrl = getTestDataUrl("feedModified.rss");
var win;
before(async function() {
before(async function () {
// Browser window is needed as parent window to load the feed reader scripts.
win = await loadZoteroWindow();
scheduleNextFeedCheck = sinon.stub(Zotero.Feeds, 'scheduleNextFeedCheck').resolves();
@ -330,103 +330,103 @@ describe("Zotero.Feed", function() {
yield clearFeeds();
});
after(function() {
after(function () {
if (win) {
win.close();
}
scheduleNextFeedCheck.restore();
});
it('should schedule next feed check', function* () {
let feed = yield createFeed();
it('should schedule next feed check', async function () {
let feed = await createFeed();
feed._feedUrl = feedUrl;
yield feed.updateFeed();
await feed.updateFeed();
assert.equal(scheduleNextFeedCheck.called, true);
});
it('should add new feed items', function* () {
let feedItems = yield Zotero.FeedItems.getAll(feed.id, true);
it('should add new feed items', async function () {
let feedItems = await Zotero.FeedItems.getAll(feed.id, true);
assert.equal(feedItems.length, 3);
});
it('should set lastCheck and lastUpdated values', function* () {
yield clearFeeds();
let feed = yield createFeed();
it('should set lastCheck and lastUpdated values', async function () {
await clearFeeds();
let feed = await createFeed();
feed._feedUrl = feedUrl;
assert.notOk(feed.lastCheck);
assert.notOk(feed.lastUpdate);
yield feed.updateFeed();
await feed.updateFeed();
assert.isTrue(feed.lastCheck > Zotero.Date.dateToSQL(new Date(Date.now() - 1000*60), true), 'feed.lastCheck updated');
assert.isTrue(feed.lastUpdate > Zotero.Date.dateToSQL(new Date(Date.now() - 1000*60), true), 'feed.lastUpdate updated');
});
it('should update modified items, preserving isRead', function* () {
let feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
it('should update modified items, preserving isRead', async function () {
let feedItem = await Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
feedItem.isRead = true;
yield feedItem.saveTx();
feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
await feedItem.saveTx();
feedItem = await Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
assert.isTrue(feedItem.isRead);
let oldDateModified = feedItem.getField('date');
feed._feedUrl = modifiedFeedUrl;
yield feed.updateFeed();
await feed.updateFeed();
feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
feedItem = await Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
assert.notEqual(oldDateModified, feedItem.getField('date'));
assert.isTrue(feedItem.isRead);
});
it('should skip items that are not modified', function* () {
it('should skip items that are not modified', async function () {
let save = sinon.spy(Zotero.FeedItem.prototype, 'save');
feed._feedUrl = modifiedFeedUrl;
yield feed.updateFeed();
await feed.updateFeed();
assert.equal(save.thisValues[0].guid, "http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
save.restore();
});
it('should update unread count', function* () {
it('should update unread count', async function () {
assert.equal(feed.unreadCount, 3);
let feedItems = yield Zotero.FeedItems.getAll(feed.id);
let feedItems = await Zotero.FeedItems.getAll(feed.id);
for (let feedItem of feedItems) {
feedItem.isRead = true;
yield feedItem.saveTx();
await feedItem.saveTx();
}
feed._feedUrl = modifiedFeedUrl;
yield feed.updateFeed();
await feed.updateFeed();
assert.equal(feed.unreadCount, 1);
});
it('should add a link to enclosed pdfs from <enclosure/> elements', function* () {
let feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
let pdf = yield Zotero.Items.getAsync(feedItem.getAttachments()[0]);
it('should add a link to enclosed pdfs from <enclosure/> elements', async function () {
let feedItem = await Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
let pdf = await Zotero.Items.getAsync(feedItem.getAttachments()[0]);
assert.equal(pdf.getField('url'), "http://www.example.com/example.pdf");
});
});
describe("Adding items", function() {
describe("Adding items", function () {
let feed;
before(function* () {
feed = yield createFeed();
})
it("should not allow adding collections", function* () {
it("should not allow adding collections", async function () {
let collection = new Zotero.Collection({ name: 'test', libraryID: feed.libraryID });
yield assert.isRejected(collection.saveTx({ skipEditCheck: true }), /^Cannot add /);
await assert.isRejected(collection.saveTx({ skipEditCheck: true }), /^Cannot add /);
});
it("should not allow adding saved search", function* () {
it("should not allow adding saved search", async function () {
let search = new Zotero.Search({ name: 'test', libraryID: feed.libraryID });
yield assert.isRejected(search.saveTx({ skipEditCheck: true }), /^Cannot add /);
await assert.isRejected(search.saveTx({ skipEditCheck: true }), /^Cannot add /);
});
it("should allow adding feed item", function* () {
it("should allow adding feed item", async function () {
let feedItem = new Zotero.FeedItem('book', { guid: Zotero.randomString() });
feedItem.libraryID = feed.libraryID;
yield assert.isFulfilled(feedItem.saveTx());
await assert.isFulfilled(feedItem.saveTx());
});
});
})

View file

@ -4,7 +4,7 @@ describe("Zotero.Feeds", function () {
yield clearFeeds();
});
describe('#importFromOPML', function() {
describe('#importFromOPML', function () {
var opmlUrl = getTestDataUrl("feeds.opml");
var opmlString;
@ -17,11 +17,11 @@ describe("Zotero.Feeds", function () {
yield clearFeeds();
});
after(function() {
after(function () {
Zotero.Feeds.updateFeeds.restore();
});
it('imports feeds correctly', function* (){
it('imports feeds correctly', async function () {
let shouldExist = {
"http://example.com/feed1.rss": "A title 1",
"http://example.com/feed2.rss": "A title 2",
@ -29,7 +29,7 @@ describe("Zotero.Feeds", function () {
"http://example.com/feed4.rss": "A title 4",
"http://example.com/feed5.rss": Zotero.getString('pane.collections.untitled')
};
yield Zotero.Feeds.importFromOPML(opmlString);
await Zotero.Feeds.importFromOPML(opmlString);
let feeds = Zotero.Feeds.getAll();
for (let feed of feeds) {
assert.equal(shouldExist[feed.url], feed.name, "Feed exists and title matches");
@ -38,13 +38,13 @@ describe("Zotero.Feeds", function () {
assert.equal(Object.keys(shouldExist).length, 0, "All feeds from opml have been created");
});
it("doesn't fail if some feeds already exist", function* (){
yield createFeed({url: "http://example.com/feed1.rss"});
yield Zotero.Feeds.importFromOPML(opmlString)
it("doesn't fail if some feeds already exist", async function () {
await createFeed({url: "http://example.com/feed1.rss"});
await Zotero.Feeds.importFromOPML(opmlString)
});
});
describe("#restoreFromJSON", function() {
describe("#restoreFromJSON", function () {
var json, expiredFeedURL, existingFeedURL;
beforeEach(function* () {
@ -68,11 +68,11 @@ describe("Zotero.Feeds", function () {
expiredFeedURL = (yield createFeed()).url;
});
it("restores correctly when merge is true", function* () {
it("restores correctly when merge is true", async function () {
let feeds = Zotero.Feeds.getAll();
assert.equal(feeds.length, 2);
yield Zotero.Feeds.restoreFromJSON(json, true);
await Zotero.Feeds.restoreFromJSON(json, true);
feeds = Zotero.Feeds.getAll();
for (let url in json) {
@ -87,11 +87,11 @@ describe("Zotero.Feeds", function () {
assert.ok(existingFeed, "does not remove feeds in database and JSON");
});
it("restores correctly when merge is false", function* () {
it("restores correctly when merge is false", async function () {
let feeds = Zotero.Feeds.getAll();
assert.equal(feeds.length, 2);
yield Zotero.Feeds.restoreFromJSON(json);
await Zotero.Feeds.restoreFromJSON(json);
feeds = Zotero.Feeds.getAll();
for (let url in json) {
@ -107,36 +107,36 @@ describe("Zotero.Feeds", function () {
});
});
describe("#haveFeeds()", function() {
it("should return false for a DB without feeds", function* () {
yield clearFeeds();
describe("#haveFeeds()", function () {
it("should return false for a DB without feeds", async function () {
await clearFeeds();
assert.isFalse(Zotero.Feeds.haveFeeds(), 'no feeds in empty DB');
let group = yield createGroup();
let group = await createGroup();
assert.isFalse(Zotero.Feeds.haveFeeds(), 'no feeds in DB with groups');
});
it("should return true for a DB containing feeds", function* () {
let feed = yield createFeed();
it("should return true for a DB containing feeds", async function () {
let feed = await createFeed();
assert.isTrue(Zotero.Feeds.haveFeeds());
});
});
describe("#getAll()", function() {
it("should return an empty array for a DB without feeds", function* () {
yield clearFeeds();
describe("#getAll()", function () {
it("should return an empty array for a DB without feeds", async function () {
await clearFeeds();
let feeds = Zotero.Feeds.getAll();
assert.lengthOf(feeds, 0, 'no feeds in an empty DB');
let group = yield createGroup();
let group = await createGroup();
feeds = Zotero.Feeds.getAll();
assert.lengthOf(feeds, 0, 'no feeds in DB with group libraries');
});
it("should return an array of feeds", function* () {
yield clearFeeds();
let feed1 = yield createFeed();
let feed2 = yield createFeed();
it("should return an array of feeds", async function () {
await clearFeeds();
let feed1 = await createFeed();
let feed2 = await createFeed();
let feeds = Zotero.Feeds.getAll();
assert.lengthOf(feeds, 2);
@ -144,23 +144,23 @@ describe("Zotero.Feeds", function () {
});
});
describe('#getByURL', function() {
it("should return a feed by url", function* () {
describe('#getByURL', function () {
it("should return a feed by url", async function () {
let url = 'http://' + Zotero.Utilities.randomString(10, 'abcdefg') + '.com/feed.rss';
yield createFeed({url});
await createFeed({url});
let feed = Zotero.Feeds.getByURL(url);
assert.ok(feed);
assert.equal(feed.url, url);
});
it("should return undefined if feed does not exist", function* () {
it("should return undefined if feed does not exist", async function () {
var feed;
assert.doesNotThrow(function() {
assert.doesNotThrow(function () {
feed = Zotero.Feeds.getByURL('doesnotexist');
});
assert.isUndefined(feed);
});
});
describe('#updateFeeds', function() {
describe('#updateFeeds', function () {
var freshFeed, recentFeed, oldFeed;
var _updateFeed;
@ -190,12 +190,12 @@ describe("Zotero.Feeds", function () {
assert.isTrue(_updateFeed.called);
});
after(function() {
after(function () {
Zotero.Feeds.scheduleNextFeedCheck.restore();
_updateFeed.restore();
});
it('should update feeds that have never been updated', function() {
it('should update feeds that have never been updated', function () {
for (var feed of _updateFeed.thisValues) {
if (feed.id == freshFeed.id) {
break;
@ -203,7 +203,7 @@ describe("Zotero.Feeds", function () {
}
assert.isTrue(feed._updateFeed.called);
});
it('should update feeds that need updating since last check', function() {
it('should update feeds that need updating since last check', function () {
for (var feed of _updateFeed.thisValues) {
if (feed.id == oldFeed.id) {
break;
@ -211,7 +211,7 @@ describe("Zotero.Feeds", function () {
}
assert.isTrue(feed._updateFeed.called);
});
it("should not update feeds that don't need updating", function() {
it("should not update feeds that don't need updating", function () {
for (var feed of _updateFeed.thisValues) {
if (feed.id != recentFeed.id) {
break;
@ -221,17 +221,17 @@ describe("Zotero.Feeds", function () {
}
});
});
describe('#scheduleNextFeedCheck()', function() {
it('schedules next feed check', function* () {
describe('#scheduleNextFeedCheck()', function () {
it('schedules next feed check', async function () {
sinon.spy(Zotero.Feeds, 'scheduleNextFeedCheck');
sinon.spy(Zotero.Promise, 'delay');
yield clearFeeds();
let feed = yield createFeed({refreshInterval: 1});
await clearFeeds();
let feed = await createFeed({refreshInterval: 1});
feed._set('_feedLastCheck', Zotero.Date.dateToSQL(new Date(), true));
yield feed.saveTx();
await feed.saveTx();
yield Zotero.Feeds.scheduleNextFeedCheck();
await Zotero.Feeds.scheduleNextFeedCheck();
// Allow a propagation delay of 5000ms
assert.isTrue(Zotero.Promise.delay.args[0][0] - 1000*60*60 <= 5000);

View file

@ -1,4 +1,4 @@
describe("Zotero_File_Interface", function() {
describe("Zotero_File_Interface", function () {
let win;
before(function* () {
win = yield loadZoteroPane();
@ -62,22 +62,22 @@ describe("Zotero_File_Interface", function() {
});
it('should import an item and snapshot from Zotero RDF', function* () {
var tmpDir = yield getTempDirectory();
it('should import an item and snapshot from Zotero RDF', async function () {
var tmpDir = await getTempDirectory();
var rdfFile = OS.Path.join(tmpDir, 'test.rdf');
yield OS.File.copy(OS.Path.join(getTestDataDirectory().path, 'book_and_snapshot.rdf'), rdfFile);
yield OS.File.makeDir(OS.Path.join(tmpDir, 'files'));
yield OS.File.makeDir(OS.Path.join(tmpDir, 'files', '2'));
yield OS.File.copy(
await OS.File.copy(OS.Path.join(getTestDataDirectory().path, 'book_and_snapshot.rdf'), rdfFile);
await OS.File.makeDir(OS.Path.join(tmpDir, 'files'));
await OS.File.makeDir(OS.Path.join(tmpDir, 'files', '2'));
await OS.File.copy(
OS.Path.join(getTestDataDirectory().path, 'test.html'),
OS.Path.join(tmpDir, 'files', '2', 'test.html')
);
var promise = waitForItemEvent('add');
yield win.Zotero_File_Interface.importFile({
await win.Zotero_File_Interface.importFile({
file: rdfFile
});
var ids = yield promise;
var ids = await promise;
// Notifications are batched
assert.lengthOf(ids, 2);
@ -92,19 +92,19 @@ describe("Zotero_File_Interface", function() {
assert.equal(attachment.attachmentCharset, 'utf-8');
// Check indexing
var matches = yield Zotero.Fulltext.findTextInItems([attachment.id], 'test');
var matches = await Zotero.Fulltext.findTextInItems([attachment.id], 'test');
assert.lengthOf(matches, 1);
assert.propertyVal(matches[0], 'id', attachment.id);
});
it('should import a MODS file', function* () {
it('should import a MODS file', async function () {
var modsFile = OS.Path.join(getTestDataDirectory().path, "mods.xml");
var promise = waitForItemEvent('add');
yield win.Zotero_File_Interface.importFile({
await win.Zotero_File_Interface.importFile({
file: modsFile
});
var ids = yield promise;
var ids = await promise;
assert.lengthOf(ids, 1);
var item = Zotero.Items.get(ids[0]);
@ -163,7 +163,7 @@ describe("Zotero_File_Interface", function() {
//
// Non-"Copy as HTML" mode
//
it("should copy HTML and text citations to the clipboard", function* () {
it("should copy HTML and text citations to the clipboard", async function () {
win.Zotero_File_Interface.copyItemsToClipboard(
[item1, item2],
'http://www.zotero.org/styles/apa',
@ -181,7 +181,7 @@ describe("Zotero_File_Interface", function() {
assert.equal(str, '(A, 2016; B, 2016)');
});
it("should copy HTML and text bibliography to the clipboard", function* () {
it("should copy HTML and text bibliography to the clipboard", async function () {
win.Zotero_File_Interface.copyItemsToClipboard(
[item1, item2],
'http://www.zotero.org/styles/apa',
@ -201,7 +201,7 @@ describe("Zotero_File_Interface", function() {
//
// "Copy as HTML" mode
//
it("should copy HTML and HTML source citations to the clipboard", function* () {
it("should copy HTML and HTML source citations to the clipboard", async function () {
win.Zotero_File_Interface.copyItemsToClipboard(
[item1, item2],
'http://www.zotero.org/styles/apa',
@ -218,7 +218,7 @@ describe("Zotero_File_Interface", function() {
assert.equal(str, '(<i>A</i>, 2016; <i>B</i>, 2016)');
});
it("should copy HTML and HTML source bibliography to the clipboard", function* () {
it("should copy HTML and HTML source bibliography to the clipboard", async function () {
win.Zotero_File_Interface.copyItemsToClipboard(
[item1, item2],
'http://www.zotero.org/styles/apa',

View file

@ -1,20 +1,20 @@
describe("Zotero.File", function () {
describe("#getContentsAsync()", function () {
it("should handle an empty file", function* () {
it("should handle an empty file", async function () {
var path = OS.Path.join(getTestDataDirectory().path, "empty");
assert.equal((yield Zotero.File.getContentsAsync(path)), "");
assert.equal(((await Zotero.File.getContentsAsync(path))), "");
})
it("should handle an extended character", function* () {
var contents = yield Zotero.File.getContentsAsync(
it("should handle an extended character", async function () {
var contents = await Zotero.File.getContentsAsync(
OS.Path.join(getTestDataDirectory().path, "charsets", "utf8.txt")
);
assert.lengthOf(contents, 3);
assert.equal(contents, "A\u72acB");
})
it("should handle an extended Windows-1252 character", function* () {
var contents = yield Zotero.File.getContentsAsync(
it("should handle an extended Windows-1252 character", async function () {
var contents = await Zotero.File.getContentsAsync(
OS.Path.join(getTestDataDirectory().path, "charsets", "windows1252.txt"),
"windows-1252"
);
@ -22,8 +22,8 @@ describe("Zotero.File", function () {
assert.equal(contents, "\u201C\u00E9\u201D");
})
it("should handle a GBK character", function* () {
var contents = yield Zotero.File.getContentsAsync(
it("should handle a GBK character", async function () {
var contents = await Zotero.File.getContentsAsync(
OS.Path.join(getTestDataDirectory().path, "charsets", "gbk.txt"),
"gbk"
);
@ -31,16 +31,16 @@ describe("Zotero.File", function () {
assert.equal(contents, "这是一个测试文件。");
})
it("should handle an invalid character", function* () {
var contents = yield Zotero.File.getContentsAsync(
it("should handle an invalid character", async function () {
var contents = await Zotero.File.getContentsAsync(
OS.Path.join(getTestDataDirectory().path, "charsets", "invalid.txt")
);
assert.lengthOf(contents, 3);
assert.equal(contents, "A" + Zotero.File.REPLACEMENT_CHARACTER + "B");
})
it("should respect maxLength", function* () {
var contents = yield Zotero.File.getContentsAsync(
it("should respect maxLength", async function () {
var contents = await Zotero.File.getContentsAsync(
OS.Path.join(getTestDataDirectory().path, "test.txt"),
false,
6
@ -49,8 +49,8 @@ describe("Zotero.File", function () {
assert.equal(contents, "Zotero");
});
it("should get a file from a file: URI", function* () {
var contents = yield Zotero.File.getContentsAsync(
it("should get a file from a file: URI", async function () {
var contents = await Zotero.File.getContentsAsync(
OS.Path.toFileURI(OS.Path.join(getTestDataDirectory().path, "test.txt"))
);
assert.isTrue(contents.startsWith('Zotero'));
@ -60,8 +60,8 @@ describe("Zotero.File", function () {
describe("#getBinaryContentsAsync()", function () {
var magicPNG = ["89", "50", "4e", "47", "0d", "0a", "1a", "0a"].map(x => parseInt(x, 16));
it("should return a binary string", function* () {
var contents = yield Zotero.File.getBinaryContentsAsync(
it("should return a binary string", async function () {
var contents = await Zotero.File.getBinaryContentsAsync(
OS.Path.join(getTestDataDirectory().path, "test.png")
);
assert.isAbove(contents.length, magicPNG.length);
@ -81,8 +81,8 @@ describe("Zotero.File", function () {
}
});
it("should respect maxLength", function* () {
var contents = yield Zotero.File.getBinaryContentsAsync(
it("should respect maxLength", async function () {
var contents = await Zotero.File.getBinaryContentsAsync(
OS.Path.join(getTestDataDirectory().path, "test.png"),
magicPNG.length
);
@ -119,16 +119,16 @@ describe("Zotero.File", function () {
assert.equal(destContents.substr(0, 4), '%PDF');
});
it("should save via .tmp file", function* () {
var tmpDir = yield getTempDirectory();
it("should save via .tmp file", async function () {
var tmpDir = await getTempDirectory();
var destFile = OS.Path.join(tmpDir, 'test.txt')
var tmpFile = destFile + ".tmp";
yield Zotero.File.putContentsAsync(tmpFile, 'A');
assert.isTrue(yield OS.File.exists(tmpFile));
yield Zotero.File.putContentsAsync(destFile, 'B');
assert.isFalse(yield OS.File.exists(tmpFile));
await Zotero.File.putContentsAsync(tmpFile, 'A');
assert.isTrue(await OS.File.exists(tmpFile));
await Zotero.File.putContentsAsync(destFile, 'B');
assert.isFalse(await OS.File.exists(tmpFile));
// Make sure .tmp file was deleted
assert.isFalse(yield OS.File.exists(tmpFile + '.tmp'));
assert.isFalse(await OS.File.exists(tmpFile + '.tmp'));
});
});
@ -181,26 +181,26 @@ describe("Zotero.File", function () {
describe("#getClosestDirectory()", function () {
it("should return directory for file that exists", function* () {
var tmpDir = yield getTempDirectory();
var closest = yield Zotero.File.getClosestDirectory(tmpDir);
it("should return directory for file that exists", async function () {
var tmpDir = await getTempDirectory();
var closest = await Zotero.File.getClosestDirectory(tmpDir);
assert.equal(closest, tmpDir);
});
it("should return parent directory for missing file", function* () {
var tmpDir = yield getTempDirectory();
var closest = yield Zotero.File.getClosestDirectory(OS.Path.join(tmpDir, 'a'));
it("should return parent directory for missing file", async function () {
var tmpDir = await getTempDirectory();
var closest = await Zotero.File.getClosestDirectory(OS.Path.join(tmpDir, 'a'));
assert.equal(closest, tmpDir);
});
it("should find an existing directory three levels up from a missing file", function* () {
var tmpDir = yield getTempDirectory();
var closest = yield Zotero.File.getClosestDirectory(OS.Path.join(tmpDir, 'a', 'b', 'c'));
it("should find an existing directory three levels up from a missing file", async function () {
var tmpDir = await getTempDirectory();
var closest = await Zotero.File.getClosestDirectory(OS.Path.join(tmpDir, 'a', 'b', 'c'));
assert.equal(closest, tmpDir);
});
it("should return false for a path that doesn't exist at all", function* () {
assert.isFalse(yield Zotero.File.getClosestDirectory('/a/b/c'));
it("should return false for a path that doesn't exist at all", async function () {
assert.isFalse(await Zotero.File.getClosestDirectory('/a/b/c'));
});
});
@ -221,30 +221,30 @@ describe("Zotero.File", function () {
describe("#copyDirectory()", function () {
it("should copy all files within a directory", function* () {
it("should copy all files within a directory", async function () {
var tmpDir = Zotero.getTempDirectory().path;
var tmpCopyDir = OS.Path.join(tmpDir, "copyDirectory")
var source = OS.Path.join(tmpCopyDir, "1");
var target = OS.Path.join(tmpCopyDir, "2");
yield OS.File.makeDir(source, {
await OS.File.makeDir(source, {
from: tmpDir
});
yield Zotero.File.putContentsAsync(OS.Path.join(source, "A"), "Test 1");
yield Zotero.File.putContentsAsync(OS.Path.join(source, "B"), "Test 2");
await Zotero.File.putContentsAsync(OS.Path.join(source, "A"), "Test 1");
await Zotero.File.putContentsAsync(OS.Path.join(source, "B"), "Test 2");
yield OS.File.removeDir(target, {
await OS.File.removeDir(target, {
ignoreAbsent: true
});
yield Zotero.File.copyDirectory(source, target);
await Zotero.File.copyDirectory(source, target);
assert.equal(
(yield Zotero.File.getContentsAsync(OS.Path.join(target, "A"))),
((await Zotero.File.getContentsAsync(OS.Path.join(target, "A")))),
"Test 1"
);
assert.equal(
(yield Zotero.File.getContentsAsync(OS.Path.join(target, "B"))),
((await Zotero.File.getContentsAsync(OS.Path.join(target, "B")))),
"Test 2"
);
})
@ -336,19 +336,19 @@ describe("Zotero.File", function () {
});
describe("#zipDirectory()", function () {
it("should compress a directory recursively", function* () {
it("should compress a directory recursively", async function () {
var tmpPath = Zotero.getTempDirectory().path;
var path = OS.Path.join(tmpPath, Zotero.Utilities.randomString());
yield OS.File.makeDir(path, { unixMode: 0o755 });
yield Zotero.File.putContentsAsync(OS.Path.join(path, '.zotero-ft-cache'), '');
yield Zotero.File.putContentsAsync(OS.Path.join(path, 'a.txt'), 'A');
await OS.File.makeDir(path, { unixMode: 0o755 });
await Zotero.File.putContentsAsync(OS.Path.join(path, '.zotero-ft-cache'), '');
await Zotero.File.putContentsAsync(OS.Path.join(path, 'a.txt'), 'A');
// Create subdirectory
var subPath = OS.Path.join(path, 'sub');
yield OS.File.makeDir(subPath, { unixMode: 0o755 });
yield Zotero.File.putContentsAsync(OS.Path.join(subPath, 'b.txt'), 'B');
await OS.File.makeDir(subPath, { unixMode: 0o755 });
await Zotero.File.putContentsAsync(OS.Path.join(subPath, 'b.txt'), 'B');
var zipFile = OS.Path.join(tmpPath, 'test.zip');
yield Zotero.File.zipDirectory(path, zipFile);
await Zotero.File.zipDirectory(path, zipFile);
var zr = Components.classes["@mozilla.org/libjar/zip-reader;1"]
.createInstance(Components.interfaces.nsIZipReader);
@ -442,7 +442,7 @@ describe("Zotero.File", function () {
describe("#checkFileAccessError()", function () {
it("should catch OS.File access-denied errors", function* () {
it("should catch OS.File access-denied errors", async function () {
// We can't modify a real OS.File.Error, but we also don't do an instanceof check in
// checkFileAccessError, so just set the expected properties.
var e = {

View file

@ -1,6 +1,8 @@
/* global Zotero_Import_Folder: false */
describe('Zotero_Import_Folder', function () {
const { Zotero_Import_Folder } = ChromeUtils.importESModule("chrome://zotero/content/import/folderImport.mjs");
var tmpDir;
const uc = name => 'Zotero_Import_Folder_' + name;
@ -39,8 +41,6 @@ describe('Zotero_Import_Folder', function () {
OS.Path.join(getTestDataDirectory().path, 'test.txt'),
OS.Path.join(tmpDir, uc('dir2'), 'test.txt')
);
Components.utils.import('chrome://zotero/content/import/folderImport.js');
});
describe('#import', () => {

View file

@ -10,54 +10,54 @@ describe("Zotero.FullText", function () {
});
describe("#indexItems()", function () {
it("should index a text file by default", function* () {
var item = yield importFileAttachment('test.txt');
it("should index a text file by default", async function () {
var item = await importFileAttachment('test.txt');
assert.equal(
(yield Zotero.Fulltext.getIndexedState(item)),
((await Zotero.Fulltext.getIndexedState(item))),
Zotero.Fulltext.INDEX_STATE_INDEXED
);
})
it("should skip indexing of a text file if fulltext.textMaxLength is 0", function* () {
it("should skip indexing of a text file if fulltext.textMaxLength is 0", async function () {
Zotero.Prefs.set('fulltext.textMaxLength', 0);
var item = yield importFileAttachment('test.txt');
var item = await importFileAttachment('test.txt');
assert.equal(
(yield Zotero.Fulltext.getIndexedState(item)),
((await Zotero.Fulltext.getIndexedState(item))),
Zotero.Fulltext.INDEX_STATE_UNINDEXED
);
})
it("should index a PDF by default", function* () {
var item = yield importFileAttachment('test.pdf');
it("should index a PDF by default", async function () {
var item = await importFileAttachment('test.pdf');
assert.equal(
(yield Zotero.Fulltext.getIndexedState(item)),
((await Zotero.Fulltext.getIndexedState(item))),
Zotero.Fulltext.INDEX_STATE_INDEXED
);
})
it("should skip indexing of a PDF if fulltext.textMaxLength is 0", function* () {
it("should skip indexing of a PDF if fulltext.textMaxLength is 0", async function () {
Zotero.Prefs.set('fulltext.textMaxLength', 0);
var item = yield importFileAttachment('test.pdf');
var item = await importFileAttachment('test.pdf');
assert.equal(
(yield Zotero.Fulltext.getIndexedState(item)),
((await Zotero.Fulltext.getIndexedState(item))),
Zotero.Fulltext.INDEX_STATE_UNINDEXED
);
})
it("should skip indexing of a PDF if fulltext.pdfMaxPages is 0", function* () {
it("should skip indexing of a PDF if fulltext.pdfMaxPages is 0", async function () {
Zotero.Prefs.set('fulltext.pdfMaxPages', 0);
var item = yield importFileAttachment('test.pdf');
var item = await importFileAttachment('test.pdf');
assert.equal(
(yield Zotero.Fulltext.getIndexedState(item)),
((await Zotero.Fulltext.getIndexedState(item))),
Zotero.Fulltext.INDEX_STATE_UNINDEXED
);
})
it("should skip indexing of an EPUB if fulltext.textMaxLength is 0", function* () {
it("should skip indexing of an EPUB if fulltext.textMaxLength is 0", async function () {
Zotero.Prefs.set('fulltext.textMaxLength', 0);
var item = yield importFileAttachment('recognizeEPUB_test_content.epub');
var item = await importFileAttachment('recognizeEPUB_test_content.epub');
assert.equal(
(yield Zotero.Fulltext.getIndexedState(item)),
((await Zotero.Fulltext.getIndexedState(item))),
Zotero.Fulltext.INDEX_STATE_UNINDEXED
);
});
@ -87,29 +87,29 @@ describe("Zotero.FullText", function () {
});
describe("#indexPDF()", function () {
it("should create cache files for linked attachments in storage directory", function* () {
it("should create cache files for linked attachments in storage directory", async function () {
var filename = 'test.pdf';
var file = OS.Path.join(getTestDataDirectory().path, filename);
var tempDir = yield getTempDirectory();
var tempDir = await getTempDirectory();
var linkedFile = OS.Path.join(tempDir, filename);
yield OS.File.copy(file, linkedFile);
await OS.File.copy(file, linkedFile);
var item = yield Zotero.Attachments.linkFromFile({ file: linkedFile });
var item = await Zotero.Attachments.linkFromFile({ file: linkedFile });
var storageDir = Zotero.Attachments.getStorageDirectory(item).path;
assert.isTrue(yield OS.File.exists(storageDir));
assert.isTrue(yield OS.File.exists(OS.Path.join(storageDir, '.zotero-ft-cache')));
assert.isFalse(yield OS.File.exists(OS.Path.join(storageDir, filename)));
assert.isTrue(await OS.File.exists(storageDir));
assert.isTrue(await OS.File.exists(OS.Path.join(storageDir, '.zotero-ft-cache')));
assert.isFalse(await OS.File.exists(OS.Path.join(storageDir, filename)));
});
});
});
describe("#getUnsyncedContent()", function () {
it("should get content that hasn't been uploaded", function* () {
it("should get content that hasn't been uploaded", async function () {
var toSync = [];
var group = yield getGroup();
var group = await getGroup();
var add = Zotero.Promise.coroutine(function* (options = {}) {
let item = yield createDataObject('item', { libraryID: options.libraryID });
var add = async function (options = {}) {
let item = await createDataObject('item', { libraryID: options.libraryID });
let attachment = new Zotero.Item('attachment');
if (options.libraryID) {
attachment.libraryID = options.libraryID;
@ -122,12 +122,12 @@ describe("Zotero.FullText", function () {
if (options.synced) {
attachment.synced = true;
}
yield attachment.saveTx();
yield Zotero.Attachments.createDirectoryForItem(attachment);
await attachment.saveTx();
await Zotero.Attachments.createDirectoryForItem(attachment);
let path = attachment.getFilePath();
let content = new Array(10).fill("").map(x => Zotero.Utilities.randomString()).join(" ");
yield Zotero.File.putContentsAsync(path, content);
await Zotero.File.putContentsAsync(path, content);
if (!options.skip) {
toSync.push({
@ -137,17 +137,17 @@ describe("Zotero.FullText", function () {
indexedPages: 0
});
}
});
yield add({ synced: true });
yield add({ synced: true });
};
await add({ synced: true });
await add({ synced: true });
// Unsynced attachment shouldn't uploaded
yield add({ skip: true });
await add({ skip: true });
// Attachment in another library shouldn't be uploaded
yield add({ libraryID: group.libraryID, synced: true, skip: true });
await add({ libraryID: group.libraryID, synced: true, skip: true });
// PDF attachment
var pdfAttachment = yield importFileAttachment('test.pdf');
var pdfAttachment = await importFileAttachment('test.pdf');
pdfAttachment.synced = true;
yield pdfAttachment.saveTx();
await pdfAttachment.saveTx();
toSync.push({
item: pdfAttachment,
content: "Zotero [zoh-TAIR-oh] is a free, easy-to-use tool to help you collect, "
@ -156,9 +156,9 @@ describe("Zotero.FullText", function () {
indexedPages: 1
});
yield Zotero.Fulltext.indexItems(toSync.map(x => x.item.id));
await Zotero.Fulltext.indexItems(toSync.map(x => x.item.id));
var data = yield Zotero.FullText.getUnsyncedContent(Zotero.Libraries.userLibraryID);
var data = await Zotero.FullText.getUnsyncedContent(Zotero.Libraries.userLibraryID);
assert.lengthOf(data, 3);
let contents = toSync.map(x => x.content);
@ -170,25 +170,25 @@ describe("Zotero.FullText", function () {
}
});
it("should mark PDF attachment content as missing if cache file doesn't exist", function* () {
var item = yield importFileAttachment('test.pdf');
it("should mark PDF attachment content as missing if cache file doesn't exist", async function () {
var item = await importFileAttachment('test.pdf');
item.synced = true;
yield item.saveTx();
await item.saveTx();
yield Zotero.Fulltext.indexItems([item.id]);
yield OS.File.remove(Zotero.Fulltext.getItemCacheFile(item).path);
await Zotero.Fulltext.indexItems([item.id]);
await OS.File.remove(Zotero.Fulltext.getItemCacheFile(item).path);
var sql = "SELECT synced FROM fulltextItems WHERE itemID=?";
var synced = yield Zotero.DB.valueQueryAsync(sql, item.id);
var synced = await Zotero.DB.valueQueryAsync(sql, item.id);
assert.equal(synced, Zotero.Fulltext.SYNC_STATE_UNSYNCED);
var indexed = yield Zotero.Fulltext.getIndexedState(item);
var indexed = await Zotero.Fulltext.getIndexedState(item);
assert.equal(indexed, Zotero.Fulltext.INDEX_STATE_INDEXED);
yield Zotero.Fulltext.getUnsyncedContent(item.libraryID);
await Zotero.Fulltext.getUnsyncedContent(item.libraryID);
synced = yield Zotero.DB.valueQueryAsync(sql, item.id);
synced = await Zotero.DB.valueQueryAsync(sql, item.id);
assert.equal(synced, Zotero.Fulltext.SYNC_STATE_MISSING);
indexed = yield Zotero.Fulltext.getIndexedState(item);
indexed = await Zotero.Fulltext.getIndexedState(item);
assert.equal(indexed, Zotero.Fulltext.INDEX_STATE_UNINDEXED);
});
})

View file

@ -1,10 +1,10 @@
"use strict";
describe("Zotero.Group", function () {
describe("#constructor()", function() {
it("should accept required parameters", function* () {
describe("#constructor()", function () {
it("should accept required parameters", async function () {
let group = new Zotero.Group();
yield assert.isRejected(group.saveTx()); // fails without required parameters
await assert.isRejected(group.saveTx()); // fails without required parameters
let groupID = Zotero.Utilities.rand(10000, 1000000);
let groupName = "Test " + Zotero.Utilities.randomString();
@ -17,7 +17,7 @@ describe("Zotero.Group", function () {
editable: true,
filesEditable: true
});
yield assert.isFulfilled(group.saveTx(), "saves given required parameters");
await assert.isFulfilled(group.saveTx(), "saves given required parameters");
assert.isTrue(Zotero.Libraries.exists(group.libraryID));
assert.equal(group, Zotero.Groups.get(group.groupID));
@ -28,8 +28,8 @@ describe("Zotero.Group", function () {
});
});
describe("#version", function() {
it("should be settable to increasing values", function() {
describe("#version", function () {
it("should be settable to increasing values", function () {
let library = new Zotero.Group();
assert.throws(() => library.version = -1);
assert.throws(() => library.version = "a");
@ -37,7 +37,7 @@ describe("Zotero.Group", function () {
assert.doesNotThrow(() => library.version = 0);
assert.doesNotThrow(() => library.version = 5);
});
it("should not be possible to decrement", function() {
it("should not be possible to decrement", function () {
let library = new Zotero.Group();
library.version = 5;
assert.throws(() => library.version = 0);
@ -45,15 +45,15 @@ describe("Zotero.Group", function () {
});
describe("#erase()", function () {
it("should unregister group", function* () {
var group = yield createGroup();
it("should unregister group", async function () {
var group = await createGroup();
var id = group.id;
yield group.eraseTx();
await group.eraseTx();
assert.isFalse(Zotero.Groups.exists(id));
})
it("should provide libraryID in extraData", function* () {
var group = yield createGroup();
it("should provide libraryID in extraData", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
var deferred = Zotero.Promise.defer();
@ -63,8 +63,8 @@ describe("Zotero.Group", function () {
}
}, ['group'], "test");
try {
yield group.eraseTx();
let extraData = yield deferred.promise;
await group.eraseTx();
let extraData = await deferred.promise;
assert.equal(extraData.libraryID, libraryID);
}
finally {
@ -74,7 +74,7 @@ describe("Zotero.Group", function () {
})
describe("#fromJSON()", function () {
it("should set permissions for owner", function* () {
it("should set permissions for owner", async function () {
var group = new Zotero.Group;
group.fromJSON({
owner: 1,
@ -103,7 +103,7 @@ describe("Zotero.Group", function () {
assert.isFalse(group.filesEditable);
})
it("should set permissions for admin", function* () {
it("should set permissions for admin", async function () {
var group = new Zotero.Group;
group.fromJSON({
owner: 1,
@ -135,7 +135,7 @@ describe("Zotero.Group", function () {
assert.isFalse(group.filesEditable);
})
it("should set permissions for member", function* () {
it("should set permissions for member", async function () {
var group = new Zotero.Group;
group.fromJSON({
owner: 1,
@ -181,7 +181,7 @@ describe("Zotero.Group", function () {
assert.isFalse(group.filesEditable);
})
it("should set permissions for non-member", function* () {
it("should set permissions for non-member", async function () {
var group = new Zotero.Group;
group.fromJSON({
owner: 1,

View file

@ -1,13 +1,13 @@
describe("Zotero.Groups", function () {
describe("#get()", function () {
it("should retrieve a newly created group", function* () {
it("should retrieve a newly created group", async function () {
try {
var group = yield createGroup();
var group = await createGroup();
assert.equal(Zotero.Groups.get(group.id), group)
}
finally {
if (group) {
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
return group.erase();
})
}
@ -16,15 +16,15 @@ describe("Zotero.Groups", function () {
})
describe("#save()", function () {
it("should trigger notifier event for inherited properties", function* () {
var group = yield createGroup({
it("should trigger notifier event for inherited properties", async function () {
var group = await createGroup({
editable: false
});
group.editable = true;
var promise = waitForNotifierEvent('modify', 'group');
yield group.saveTx();
var data = yield promise;
await group.saveTx();
var data = await promise;
assert.lengthOf(data.ids, 1);
assert.sameMembers(data.ids, [group.id]);
});

View file

@ -157,7 +157,7 @@ describe("Zotero.HTTP", function () {
var delayStub;
beforeEach(function () {
delayStub = sinon.stub(Zotero.Promise, "delay").returns(Zotero.Promise.resolve());
delayStub = sinon.stub(Zotero.Promise, "delay").returns(Promise.resolve());
});
afterEach(function () {
@ -249,7 +249,7 @@ describe("Zotero.HTTP", function () {
assert.equal(spy.callCount, 3);
});
it("should obey Retry-After for 503", function* () {
it("should obey Retry-After for 503", async function () {
var called = 0;
server.respond(function (req) {
if (req.method == "GET" && req.url == baseURL + "error") {
@ -282,7 +282,7 @@ describe("Zotero.HTTP", function () {
called++;
});
spy = sinon.spy(Zotero.HTTP, "_requestInternal");
yield Zotero.HTTP.request("GET", baseURL + "error");
await Zotero.HTTP.request("GET", baseURL + "error");
assert.equal(3, spy.callCount);
// DEBUG: Why are these slightly off?
assert.approximately(delayStub.args[0][0], 5 * 1000, 5);
@ -320,9 +320,9 @@ describe("Zotero.HTTP", function () {
Zotero.HTTP.mock = null;
});
it("should provide a document object", function* () {
it("should provide a document object", async function () {
var called = false;
yield Zotero.HTTP.processDocuments(
await Zotero.HTTP.processDocuments(
testURL,
function (doc) {
assert.equal(doc.location.href, testURL);

View file

@ -1,7 +1,7 @@
"use strict";
describe("Zotero.Integration", function () {
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.importESModule("resource://gre/modules/XPCOMUtils.sys.mjs");
const INTEGRATION_TYPE_ITEM = 1;
const INTEGRATION_TYPE_BIBLIOGRAPHY = 2;
const INTEGRATION_TYPE_TEMP = 3;
@ -16,7 +16,7 @@ describe("Zotero.Integration", function () {
/**
* The Application class corresponds to a word processing application.
*/
DocumentPluginDummy.Application = function() {
DocumentPluginDummy.Application = function () {
this.doc = new DocumentPluginDummy.Document();
this.primaryFieldType = "Field";
this.secondaryFieldType = "Bookmark";
@ -33,19 +33,19 @@ describe("Zotero.Integration", function () {
* Gets the active document.
* @returns {DocumentPluginDummy.Document}
*/
getActiveDocument: function() {return this.doc},
getActiveDocument: function () {return this.doc},
/**
* Gets the document by some app-specific identifier.
* @param {String|Number} docID
*/
getDocument: function(docID) {return this.doc},
QueryInterface: function() {return this},
getDocument: function (docID) {return this.doc},
QueryInterface: function () {return this},
};
/**
* The Document class corresponds to a single word processing document.
*/
DocumentPluginDummy.Document = function() {this.fields = [], this.fieldIdx = 0};
DocumentPluginDummy.Document = function () {this.fields = [], this.fieldIdx = 0};
DocumentPluginDummy.Document.prototype = {
/**
* Displays a dialog in the word processing application
@ -79,12 +79,12 @@ describe("Zotero.Integration", function () {
* Get document data property from the current document
* @returns {String}
*/
getDocumentData: function() {return this.data},
getDocumentData: function () {return this.data},
/**
* Set document data property
* @param {String} data
*/
setDocumentData: function(data) {this.data = data},
setDocumentData: function (data) {this.data = data},
/**
* Inserts a field at cursor position and initializes the field object.
* If Document.insertText() was called previously inserts the field
@ -93,7 +93,7 @@ describe("Zotero.Integration", function () {
* @param {Integer} noteType
* @returns {DocumentPluginDummy.Field}
*/
insertField: function(fieldType, noteType) {
insertField: function (fieldType, noteType) {
if (typeof noteType != "number") {
throw new Error("noteType must be an integer");
}
@ -180,7 +180,7 @@ describe("Zotero.Integration", function () {
* The Field class corresponds to a field containing an individual citation
* or bibliography
*/
DocumentPluginDummy.Field = function(doc, idx) {
DocumentPluginDummy.Field = function (doc, idx) {
this.doc = doc;
this.code = '';
// This is actually required and current integration code depends on text being non-empty upon insertion.
@ -195,11 +195,11 @@ describe("Zotero.Integration", function () {
/**
* Deletes this field and its contents.
*/
delete: function() {this.doc.fields = this.doc.fields.filter((field) => field !== this)},
delete: function () {this.doc.fields = this.doc.fields.filter((field) => field !== this)},
/**
* Removes this field, but maintains the field's contents.
*/
removeCode: function() {this.code = ""},
removeCode: function () {this.code = ""},
/**
* Selects this field.
*/
@ -210,28 +210,28 @@ describe("Zotero.Integration", function () {
* @param {String} text
* @param {Boolean} isRich
*/
setText: function(text, isRich) {this.text = text},
setText: function (text, isRich) {this.text = text},
/**
* Gets the text inside this field, preferably with formatting, but potentially without
* @returns {String}
*/
getText: function() {return this.text},
getText: function () {return this.text},
/**
* Sets field's code
* @param {String} code
*/
setCode: function(code) {this.code = code},
setCode: function (code) {this.code = code},
/**
* Gets field's code.
* @returns {String}
*/
getCode: function() {return this.code},
getCode: function () {return this.code},
/**
* Returns true if this field and the passed field are actually references to the same field.
* @param {DocumentPluginDummy.Field} field
* @returns {Boolean}
*/
equals: function(field) {return this == field},
equals: function (field) {return this == field},
/**
* This field's note index, if it is in a footnote or endnote; otherwise zero.
* @returns {Number}
@ -242,7 +242,7 @@ describe("Zotero.Integration", function () {
* Whether this field is adjacent to the next field (meaning they can be merged).
* @returns {boolean}
*/
isAdjacentToNextField: function() { return this.adjacent },
isAdjacentToNextField: function () { return this.adjacent },
};
// Processing functions for logging and promisification
@ -250,7 +250,7 @@ describe("Zotero.Integration", function () {
for (let methodName in DocumentPluginDummy[cls].prototype) {
if (methodName !== 'QueryInterface') {
let method = DocumentPluginDummy[cls].prototype[methodName];
DocumentPluginDummy[cls].prototype[methodName] = async function() {
DocumentPluginDummy[cls].prototype[methodName] = async function () {
try {
if (cls == 'Field') {
Zotero.debug(`DocumentPluginDummy: ${cls}[${this.idx}].${methodName} invoked with args ${JSON.stringify(arguments)}`, 2);
@ -331,8 +331,8 @@ describe("Zotero.Integration", function () {
function setAddEditItems(items) {
if (items.length == undefined) items = [items];
dialogResults.citationDialog = async function(dialogName, io) {
io.citation.citationItems = items.map(function(item) {
dialogResults.citationDialog = async function (dialogName, io) {
io.citation.citationItems = items.map(function (item) {
item = Zotero.Cite.getItem(item.id);
return {id: item.id, uris: item.cslURIs, itemData: item.cslItemData};
});
@ -379,7 +379,7 @@ describe("Zotero.Integration", function () {
}
setAddEditItems(testItems[0]);
sinon.stub(Zotero.Integration, 'getApplication').callsFake(function(agent, command, docID) {
sinon.stub(Zotero.Integration, 'getApplication').callsFake(function (agent, command, docID) {
if (!applications[docID]) {
applications[docID] = new DocumentPluginDummy.Application();
}
@ -387,7 +387,7 @@ describe("Zotero.Integration", function () {
});
displayDialogStub = sinon.stub(Zotero.Integration, 'displayDialog');
displayDialogStub.callsFake(async function(dialogName, prefs, io, windowType) {
displayDialogStub.callsFake(async function (dialogName, prefs, io, windowType) {
Zotero.debug(`Display dialog: ${dialogName}`, 2);
var ioResult = dialogResults[dialogName.substring(dialogName.lastIndexOf('/')+1, dialogName.length-6)];
if (typeof ioResult == 'function') {
@ -402,36 +402,36 @@ describe("Zotero.Integration", function () {
sinon.stub(Zotero.Integration.Progress.prototype, 'show');
});
after(function() {
after(function () {
Zotero.Integration.Progress.prototype.show.restore();
Zotero.Integration.getApplication.restore();
displayDialogStub.restore();
addEditCitationSpy.restore();
});
describe('Interface', function() {
describe('#execCommand', function() {
describe('Interface', function () {
describe('#execCommand', function () {
var setDocumentDataSpy;
var docID = this.fullTitle();
before(function() {
before(function () {
setDocumentDataSpy = sinon.spy(DocumentPluginDummy.Document.prototype, 'setDocumentData');
});
afterEach(function() {
afterEach(function () {
setDocumentDataSpy.resetHistory();
});
after(function() {
after(function () {
setDocumentDataSpy.restore();
});
it('should call doc.setDocumentData once', function* () {
yield execCommand('addEditCitation', docID);
it('should call doc.setDocumentData once', async function () {
await execCommand('addEditCitation', docID);
assert.isTrue(setDocumentDataSpy.calledOnce);
});
describe('when style used in the document does not exist', function() {
describe('when style used in the document does not exist', function () {
var docID = this.fullTitle();
var displayAlertStub;
var style;
@ -456,15 +456,15 @@ describe("Zotero.Integration", function () {
displayAlertStub.restore();
});
describe('when the style is not from a trusted source', function() {
it('should download the style and if user clicks YES', function* () {
describe('when the style is not from a trusted source', function () {
it('should download the style and if user clicks YES', async function () {
var styleInstallStub = sinon.stub(Zotero.Styles, "install").resolves({
styleTitle: 'Waterbirds',
styleID: 'waterbirds'
});
var style = Zotero.Styles.get(styleID);
var styleGetCalledOnce = false;
var styleGetStub = sinon.stub(Zotero.Styles, 'get').callsFake(function() {
var styleGetStub = sinon.stub(Zotero.Styles, 'get').callsFake(function () {
if (!styleGetCalledOnce) {
styleGetCalledOnce = true;
return false;
@ -472,7 +472,7 @@ describe("Zotero.Integration", function () {
return style;
});
displayAlertStub.resolves(1);
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.isTrue(displayAlertStub.calledOnce);
assert.isFalse(displayDialogStub.calledWith(applications[docID].doc, 'chrome://zotero/content/integration/integrationDocPrefs.xul'));
assert.isTrue(styleInstallStub.calledOnce);
@ -481,9 +481,9 @@ describe("Zotero.Integration", function () {
styleGetStub.restore();
});
it('should prompt with the document preferences dialog if user clicks NO', function* () {
it('should prompt with the document preferences dialog if user clicks NO', async function () {
displayAlertStub.resolves(0);
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.isTrue(displayAlertStub.calledOnce);
// Prefs to select a new style
assert.isTrue(displayDialogStub.calledTwice);
@ -491,15 +491,15 @@ describe("Zotero.Integration", function () {
});
});
it('should download the style without prompting if it is from zotero.org', function* (){
yield initDoc(docID, {styleID: "http://www.zotero.org/styles/waterbirds", locale: 'en-US'});
it('should download the style without prompting if it is from zotero.org', async function () {
await initDoc(docID, {styleID: "http://www.zotero.org/styles/waterbirds", locale: 'en-US'});
var styleInstallStub = sinon.stub(Zotero.Styles, "install").resolves({
styleTitle: 'Waterbirds',
styleID: 'waterbirds'
});
var style = Zotero.Styles.get(styleID);
var styleGetCalledOnce = false;
var styleGetStub = sinon.stub(Zotero.Styles, 'get').callsFake(function() {
var styleGetStub = sinon.stub(Zotero.Styles, 'get').callsFake(function () {
if (!styleGetCalledOnce) {
styleGetCalledOnce = true;
return false;
@ -507,7 +507,7 @@ describe("Zotero.Integration", function () {
return style;
});
displayAlertStub.resolves(1);
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.isFalse(displayAlertStub.called);
assert.isFalse(displayDialogStub.calledWith(applications[docID].doc, 'chrome://zotero/content/integration/integrationDocPrefs.xul'));
assert.isTrue(styleInstallStub.calledOnce);
@ -528,7 +528,7 @@ describe("Zotero.Integration", function () {
let docID = this.test.fullTitle();
let citationDialogOpenedDeferred = Zotero.Promise.defer();
let citationDialogCancelledDeferred = Zotero.Promise.defer();
dialogResults.citationDialog = async function(dialogName, io) {
dialogResults.citationDialog = async function (dialogName, io) {
Zotero.Integration.currentWindow = { isPristine: true, focus: () => 0, cancel: citationDialogCancelledDeferred.resolve };
citationDialogOpenedDeferred.resolve();
await citationDialogCancelledDeferred.promise;
@ -577,7 +577,7 @@ describe("Zotero.Integration", function () {
let docID = this.test.fullTitle();
let citationDialogOpenedDeferred = Zotero.Promise.defer();
let citationDialogCancelledDeferred = Zotero.Promise.defer();
dialogResults.citationDialog = async function(dialogName, io, windowType) {
dialogResults.citationDialog = async function (dialogName, io, windowType) {
Zotero.Integration.currentWindow = { isPristine: false, focus: () => 0, cancel: citationDialogCancelledDeferred.resolve };
Zotero.Integration.currentWindowType = windowType;
citationDialogOpenedDeferred.resolve();
@ -598,11 +598,11 @@ describe("Zotero.Integration", function () {
});
});
describe('#addEditCitation', function() {
describe('#addEditCitation', function () {
it('should insert citation if not in field', insertMultipleCitations);
it('should edit citation if in citation field', function* () {
yield insertMultipleCitations.call(this);
it('should edit citation if in citation field', async function () {
await insertMultipleCitations.call(this);
var docID = this.test.fullTitle();
var doc = applications[docID].doc;
@ -610,15 +610,15 @@ describe("Zotero.Integration", function () {
sinon.stub(doc, 'canInsertField').resolves(false);
setAddEditItems(testItems.slice(3, 5));
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.equal(doc.fields.length, 2);
var citation = yield (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
var citation = await (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
assert.equal(citation.citationItems.length, 2);
assert.equal(citation.citationItems[0].id, testItems[3].id);
});
it('should write an implicitly updated citation into the document', function* () {
yield insertMultipleCitations.call(this);
it('should write an implicitly updated citation into the document', async function () {
await insertMultipleCitations.call(this);
var docID = this.test.fullTitle();
var doc = applications[docID].doc;
@ -626,7 +626,7 @@ describe("Zotero.Integration", function () {
testItems[3].setField('date', '2019-01-02');
setAddEditItems(testItems[3]);
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.equal(doc.fields[2].text, "(Smith, 2019)");
sinon.stub(doc, 'cursorInField').resolves(doc.fields[0]);
@ -636,14 +636,14 @@ describe("Zotero.Integration", function () {
testItems[4].setField('date', '2019-01-01');
setAddEditItems(testItems[4]);
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.equal(doc.fields.length, 3);
assert.equal(doc.fields[0].text, "(Smith, 2019a)");
assert.equal(doc.fields[2].text, "(Smith, 2019b)");
});
it('should place an implicitly updated citation correctly after multiple new insertions', function* () {
yield insertMultipleCitations.call(this);
it('should place an implicitly updated citation correctly after multiple new insertions', async function () {
await insertMultipleCitations.call(this);
var docID = this.test.fullTitle();
var doc = applications[docID].doc;
@ -651,7 +651,7 @@ describe("Zotero.Integration", function () {
testItems[3].setField('date', '2019-01-02');
setAddEditItems(testItems[3]);
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.equal(doc.fields[2].text, "(Smith, 2019)");
sinon.stub(doc, 'cursorInField').resolves(doc.fields[0]);
@ -664,42 +664,42 @@ describe("Zotero.Integration", function () {
testItems[4].setField('date', '2019-01-01');
setAddEditItems(testItems[4]);
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.equal(doc.fields.length, 3);
assert.equal(doc.fields[0].text, "(Smith, 2019a)");
assert.equal(doc.fields[2].text, "(Smith, 2019b)");
});
it('should update bibliography if present', function* () {
yield insertMultipleCitations.call(this);
it('should update bibliography if present', async function () {
await insertMultipleCitations.call(this);
var docID = this.test.fullTitle();
var doc = applications[docID].doc;
let getCiteprocBibliographySpy =
sinon.spy(Zotero.Integration.Bibliography.prototype, 'getCiteprocBibliography');
yield execCommand('addEditBibliography', docID);
await execCommand('addEditBibliography', docID);
assert.isTrue(getCiteprocBibliographySpy.calledOnce);
assert.equal(getCiteprocBibliographySpy.lastCall.returnValue[0].entry_ids.length, 3);
getCiteprocBibliographySpy.resetHistory();
setAddEditItems(testItems[3]);
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.equal(getCiteprocBibliographySpy.lastCall.returnValue[0].entry_ids.length, 4);
getCiteprocBibliographySpy.restore();
});
it('should update bibliography sort order on change to item', function* () {
yield insertMultipleCitations.call(this);
it('should update bibliography sort order on change to item', async function () {
await insertMultipleCitations.call(this);
var docID = this.test.fullTitle();
var doc = applications[docID].doc;
let getCiteprocBibliographySpy =
sinon.spy(Zotero.Integration.Bibliography.prototype, 'getCiteprocBibliography');
yield execCommand('addEditBibliography', docID);
await execCommand('addEditBibliography', docID);
assert.isTrue(getCiteprocBibliographySpy.calledOnce);
assert.equal(getCiteprocBibliographySpy.lastCall.returnValue[0].entry_ids.length, 3);
@ -712,7 +712,7 @@ describe("Zotero.Integration", function () {
testItems[1].setField('title', 'Bbbbb');
setAddEditItems(testItems.slice(1, 3));
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.equal(getCiteprocBibliographySpy.lastCall.returnValue[0].entry_ids.length, 3);
assert.equal(getCiteprocBibliographySpy.lastCall.returnValue[1][0], "Aaaaa. (n.d.). {\\i{}Bbbbb}.");
@ -720,15 +720,15 @@ describe("Zotero.Integration", function () {
getCiteprocBibliographySpy.restore();
});
describe('when original citation text has been modified', function() {
describe('when original citation text has been modified', function () {
var displayAlertStub;
before(function* () {
displayAlertStub = sinon.stub(DocumentPluginDummy.Document.prototype, 'displayAlert').resolves(0);
});
beforeEach(function() {
beforeEach(function () {
displayAlertStub.resetHistory();
});
after(function() {
after(function () {
displayAlertStub.restore();
});
it('should keep modification if "Cancel" selected in editCitation triggered alert', async function () {
@ -762,7 +762,7 @@ describe("Zotero.Integration", function () {
assert.equal(doc.fields.length, 2);
assert.equal(doc.fields[0].text, origText);
});
it('should set dontUpdate: true if "yes" selected in refresh prompt', async function() {
it('should set dontUpdate: true if "yes" selected in refresh prompt', async function () {
await insertMultipleCitations.call(this);
var docID = this.test.fullTitle();
var doc = applications[docID].doc;
@ -780,7 +780,7 @@ describe("Zotero.Integration", function () {
var citation = await (new Zotero.Integration.CitationField(doc.fields[0], doc.fields[0].code)).unserialize();
assert.isOk(citation.properties.dontUpdate);
});
it('should reset citation text if "no" selected in refresh prompt', async function() {
it('should reset citation text if "no" selected in refresh prompt', async function () {
await insertMultipleCitations.call(this);
var docID = this.test.fullTitle();
var doc = applications[docID].doc;
@ -801,7 +801,7 @@ describe("Zotero.Integration", function () {
});
});
it('should detect items cited with Mendeley if they are imported into Zotero', async function() {
it('should detect items cited with Mendeley if they are imported into Zotero', async function () {
var docID = this.test.fullTitle();
if (!(docID in applications)) await initDoc(docID);
var doc = applications[docID].doc;
@ -825,8 +825,8 @@ describe("Zotero.Integration", function () {
assert.include(doc.fields[0].code, Zotero.URI.getItemURI(testItem));
});
describe('when there are copy-pasted citations', function() {
it('should resolve duplicate citationIDs and mark both as new citations', async function() {
describe('when there are copy-pasted citations', function () {
it('should resolve duplicate citationIDs and mark both as new citations', async function () {
var docID = this.test.fullTitle();
if (!(docID in applications)) await initDoc(docID);
var doc = applications[docID].doc;
@ -843,7 +843,7 @@ describe("Zotero.Integration", function () {
var stubUpdateDocument = sinon.stub(Zotero.Integration.Session.prototype, 'updateDocument');
try {
var indicesLength;
stubUpdateDocument.callsFake(function() {
stubUpdateDocument.callsFake(function () {
indicesLength = Object.keys(this.newIndices).length;
return originalUpdateDocument.apply(this, arguments);
});
@ -856,7 +856,7 @@ describe("Zotero.Integration", function () {
}
});
it('should successfully process citations copied in from another doc', async function() {
it('should successfully process citations copied in from another doc', async function () {
var docID = this.test.fullTitle();
if (!(docID in applications)) await initDoc(docID);
var doc = applications[docID].doc;
@ -877,7 +877,7 @@ describe("Zotero.Integration", function () {
var stubUpdateDocument = sinon.stub(Zotero.Integration.Session.prototype, 'updateDocument');
try {
var indices;
stubUpdateDocument.callsFake(function() {
stubUpdateDocument.callsFake(function () {
indices = Object.keys(this.newIndices);
return originalUpdateDocument.apply(this, arguments);
});
@ -918,9 +918,9 @@ describe("Zotero.Integration", function () {
});
});
describe('when delayCitationUpdates is set', function() {
it('should insert a citation with wave underlining', function* (){
yield insertMultipleCitations.call(this);
describe('when delayCitationUpdates is set', function () {
it('should insert a citation with wave underlining', async function () {
await insertMultipleCitations.call(this);
var docID = this.test.fullTitle();
var doc = applications[docID].doc;
var data = new Zotero.Integration.DocumentData(doc.data);
@ -929,14 +929,14 @@ describe("Zotero.Integration", function () {
var setTextSpy = sinon.spy(DocumentPluginDummy.Field.prototype, 'setText');
setAddEditItems(testItems[3]);
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
assert.isTrue(setTextSpy.lastCall.args[0].includes('\\uldash'));
setTextSpy.restore();
});
it('should not write to any other fields besides the one being updated', function* () {
yield insertMultipleCitations.call(this);
it('should not write to any other fields besides the one being updated', async function () {
await insertMultipleCitations.call(this);
var docID = this.test.fullTitle();
var doc = applications[docID].doc;
var data = new Zotero.Integration.DocumentData(doc.data);
@ -947,15 +947,15 @@ describe("Zotero.Integration", function () {
var setCodeSpy = sinon.spy(DocumentPluginDummy.Field.prototype, 'setCode');
setAddEditItems(testItems[3]);
yield execCommand('addEditCitation', docID);
await execCommand('addEditCitation', docID);
var field = setTextSpy.firstCall.thisValue;
for (let i = 0; i < setTextSpy.callCount; i++) {
assert.isTrue(yield field.equals(setTextSpy.getCall(i).thisValue));
assert.isTrue(await field.equals(setTextSpy.getCall(i).thisValue));
}
for (let i = 0; i < setCodeSpy.callCount; i++) {
assert.isTrue(yield field.equals(setCodeSpy.getCall(i).thisValue));
assert.isTrue(await field.equals(setCodeSpy.getCall(i).thisValue));
}
setTextSpy.restore();
@ -1020,7 +1020,7 @@ describe("Zotero.Integration", function () {
});
});
describe('#addEditBibliography', function() {
describe('#addEditBibliography', function () {
var docID = this.fullTitle();
beforeEach(function* () {
setAddEditItems(testItems[0]);
@ -1028,13 +1028,13 @@ describe("Zotero.Integration", function () {
yield execCommand('addEditCitation', docID);
});
it('should insert bibliography if no bibliography field present', function* () {
it('should insert bibliography if no bibliography field present', async function () {
displayDialogStub.resetHistory();
yield execCommand('addEditBibliography', docID);
await execCommand('addEditBibliography', docID);
assert.isFalse(displayDialogStub.called);
var biblPresent = false;
for (let i = applications[docID].doc.fields.length-1; i >= 0; i--) {
let field = yield Zotero.Integration.Field.loadExisting(applications[docID].doc.fields[i]);
let field = await Zotero.Integration.Field.loadExisting(applications[docID].doc.fields[i]);
if (field.type == INTEGRATION_TYPE_BIBLIOGRAPHY) {
biblPresent = true;
break;
@ -1043,16 +1043,16 @@ describe("Zotero.Integration", function () {
assert.isTrue(biblPresent);
});
it('should display the edit bibliography dialog if bibliography present', function* () {
yield execCommand('addEditBibliography', docID);
it('should display the edit bibliography dialog if bibliography present', async function () {
await execCommand('addEditBibliography', docID);
displayDialogStub.resetHistory();
yield execCommand('addEditBibliography', docID);
await execCommand('addEditBibliography', docID);
assert.isTrue(displayDialogStub.calledOnce);
assert.isTrue(displayDialogStub.lastCall.args[0].includes('editBibliographyDialog'));
});
});
describe('#refresh', function() {
describe('#refresh', function () {
it ('should properly disambiguate author after editing in the database', async function () {
var docID = this.test.fullTitle();
let testItem1 = await createDataObject('item', {libraryID: Zotero.Libraries.userLibraryID});
@ -1089,8 +1089,8 @@ describe("Zotero.Integration", function () {
});
});
describe("DocumentData", function() {
it('should properly unserialize old XML document data', function() {
describe("DocumentData", function () {
it('should properly unserialize old XML document data', function () {
var serializedXMLData = `<data data-version="3" zotero-version="5.0.SOURCE"><session id="F0NFmZ32"/><style id="${styleID}" hasBibliography="1" bibliographyStyleHasBeenSet="1"/><prefs><pref name="fieldType" value="ReferenceMark"/><pref name="automaticJournalAbbreviations" value="true"/><pref name="noteType" value="0"/></prefs></data>`;
var data = new Zotero.Integration.DocumentData(serializedXMLData);
var expectedData = {
@ -1113,7 +1113,7 @@ describe("Zotero.Integration", function () {
assert.equal(JSON.stringify(data), JSON.stringify(expectedData));
});
it('should properly unserialize JSON document data', function() {
it('should properly unserialize JSON document data', function () {
var expectedData = JSON.stringify({
style: {
styleID,
@ -1135,7 +1135,7 @@ describe("Zotero.Integration", function () {
assert.equal(JSON.stringify(data), expectedData);
});
it('should properly serialize document data to XML (data ver 3)', function() {
it('should properly serialize document data to XML (data ver 3)', function () {
sinon.spy(Zotero, 'debug');
var data = new Zotero.Integration.DocumentData();
data.sessionID = "owl-sesh";
@ -1171,7 +1171,7 @@ describe("Zotero.Integration", function () {
Zotero.debug.restore();
});
it('should properly serialize document data to JSON (data ver 4)', function() {
it('should properly serialize document data to JSON (data ver 4)', function () {
var data = new Zotero.Integration.DocumentData();
// data version 4 triggers serialization to JSON
// (e.g. when we've retrieved data from the doc and it was ver 4 already)

View file

@ -1,8 +1,8 @@
"use strict";
describe("Zotero.Intl", function() {
describe("Zotero.Intl", function () {
describe("#getString()", function () {
it("should return the right plural form", function* () {
it("should return the right plural form", async function () {
if (Zotero.locale != 'en-US') {
this.skip();
}

View file

@ -2,7 +2,7 @@
describe("Zotero.ItemFields", function () {
describe("#getBaseIDFromTypeAndField()", function () {
it("should return the base field id for an item type and base-mapped field", function* () {
it("should return the base field id for an item type and base-mapped field", async function () {
assert.equal(
Zotero.ItemFields.getBaseIDFromTypeAndField('audioRecording', 'label'),
Zotero.ItemFields.getID('publisher')
@ -18,7 +18,7 @@ describe("Zotero.ItemFields", function () {
);
})
it("should return the base field id for an item type and base field", function* () {
it("should return the base field id for an item type and base field", async function () {
assert.equal(
Zotero.ItemFields.getBaseIDFromTypeAndField('book', 'publisher'),
Zotero.ItemFields.getID('publisher')
@ -32,7 +32,7 @@ describe("Zotero.ItemFields", function () {
);
});
it("should return false for an item type and non-base-mapped field", function* () {
it("should return false for an item type and non-base-mapped field", async function () {
assert.isFalse(
Zotero.ItemFields.getBaseIDFromTypeAndField('audioRecording', 'runningTime')
);

View file

@ -259,21 +259,21 @@ describe("Item pane", function () {
assert.isTrue(fields[2].startsWith('creator'));
});
it("should refresh on item update", function* () {
it("should refresh on item update", async function () {
var item = new Zotero.Item('book');
var id = yield item.saveTx();
var id = await item.saveTx();
var itemBox = doc.getElementById('zotero-editpane-info-box');
var label = itemBox.querySelectorAll('[fieldname="series"]')[1];
assert.equal(label.value, '');
item.setField('series', 'Test');
yield item.saveTx();
await item.saveTx();
label = itemBox.querySelectorAll('[fieldname="series"]')[1];
assert.equal(label.value, 'Test');
yield Zotero.Items.erase(id);
await Zotero.Items.erase(id);
});
@ -1398,11 +1398,11 @@ describe("Item pane", function () {
describe("Notes pane", function () {
it("should refresh on child note change", function* () {
it("should refresh on child note change", async function () {
var item;
var note1;
var note2;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
item = createUnsavedDataObject('item');
await item.save();
@ -1420,26 +1420,26 @@ describe("Item pane", function () {
var body = doc.querySelector('#zotero-editpane-notes .body');
// Wait for note list to update
do {
yield Zotero.Promise.delay(1);
await Zotero.Promise.delay(1);
}
while (body.querySelectorAll('.row .label').length !== 2);
// Update note text
note2.setNote('C');
yield note2.saveTx();
await note2.saveTx();
// Wait for note list to update
do {
yield Zotero.Promise.delay(1);
await Zotero.Promise.delay(1);
}
while ([...body.querySelectorAll('.row .label')].every(label => label.textContent != 'C'));
});
it("should refresh on child note trash", function* () {
it("should refresh on child note trash", async function () {
var item;
var note1;
var note2;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
item = createUnsavedDataObject('item');
await item.save();
@ -1457,27 +1457,27 @@ describe("Item pane", function () {
var body = doc.querySelector('#zotero-editpane-notes .body');
// Wait for note list to update
do {
yield Zotero.Promise.delay(1);
await Zotero.Promise.delay(1);
}
while (body.querySelectorAll('.row .label').length !== 2);
// Click "-" in first note
var promise = waitForDialog();
body.querySelector(".zotero-clicky-minus").click();
yield promise;
await promise;
// Wait for note list to update
do {
yield Zotero.Promise.delay(1);
await Zotero.Promise.delay(1);
}
while (body.querySelectorAll('.row .label').length !== 1);
});
it("should refresh on child note delete", function* () {
it("should refresh on child note delete", async function () {
var item;
var note1;
var note2;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
item = createUnsavedDataObject('item');
await item.save();
@ -1495,15 +1495,15 @@ describe("Item pane", function () {
var body = doc.querySelector('#zotero-editpane-notes .body');
// Wait for note list to update
do {
yield Zotero.Promise.delay(1);
await Zotero.Promise.delay(1);
}
while (body.querySelectorAll('.row .label').length !== 2);
yield note2.eraseTx();
await note2.eraseTx();
// Wait for note list to update
do {
yield Zotero.Promise.delay(1);
await Zotero.Promise.delay(1);
}
while (body.querySelectorAll('.row .label').length !== 1);
});
@ -1713,23 +1713,23 @@ describe("Item pane", function () {
describe("Note editor", function () {
it("should refresh on note update", function* () {
it("should refresh on note update", async function () {
var item = new Zotero.Item('note');
var id = yield item.saveTx();
var id = await item.saveTx();
var noteEditor = doc.getElementById('zotero-note-editor');
// Wait for the editor
yield new Zotero.Promise((resolve, reject) => {
await new Zotero.Promise((resolve, reject) => {
noteEditor.onInit(() => resolve());
});
assert.equal(noteEditor._editorInstance._iframeWindow.wrappedJSObject.getDataSync(), null);
item.setNote('<p>Test</p>');
yield item.saveTx();
await item.saveTx();
// Wait for asynchronous editor update
do {
yield Zotero.Promise.delay(10);
await Zotero.Promise.delay(10);
} while (
!/<div data-schema-version=".*"><p>Test<\/p><\/div>/.test(
noteEditor._editorInstance._iframeWindow.wrappedJSObject.getDataSync().html.replace(/\n/g, '')
@ -1738,8 +1738,8 @@ describe("Item pane", function () {
});
});
describe("Feed buttons", function() {
describe("Mark as Read/Unread", function() {
describe("Feed buttons", function () {
describe("Mark as Read/Unread", function () {
it("should change an item from unread to read", async function () {
var feed = await createFeed();
await select(win, feed);
@ -1768,23 +1768,23 @@ describe("Item pane", function () {
});
it("should update label when state of an item changes", function* () {
let feed = yield createFeed();
yield selectLibrary(win, feed.libraryID);
yield waitForItemsLoad(win);
it("should update label when state of an item changes", async function () {
let feed = await createFeed();
await selectLibrary(win, feed.libraryID);
await waitForItemsLoad(win);
var stub = sinon.stub(win.ZoteroPane, 'startItemReadTimeout');
var item = yield createDataObject('feedItem', { libraryID: feed.libraryID });
var item = await createDataObject('feedItem', { libraryID: feed.libraryID });
// Skip timed mark-as-read
assert.ok(stub.called);
stub.restore();
item.isRead = true;
yield item.saveTx();
await item.saveTx();
let button = ZoteroPane.itemPane.getCurrentPane().querySelector('.feed-item-toggleRead-button');
assert.equal(button.label, Zotero.getString('pane.item.markAsUnread'));
yield item.toggleRead(false);
await item.toggleRead(false);
// Button is re-created
button = ZoteroPane.itemPane.getCurrentPane().querySelector('.feed-item-toggleRead-button');
assert.equal(button.label, Zotero.getString('pane.item.markAsRead'));

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
"use strict";
describe("Zotero.ItemTree", function() {
describe("Zotero.ItemTree", function () {
var win, zp, cv, itemsView;
var existingItemID;
var existingItemID2;
@ -76,7 +76,7 @@ describe("Zotero.ItemTree", function() {
}
});
after(async function() {
after(async function () {
await parentItem.erase();
});
@ -252,12 +252,12 @@ describe("Zotero.ItemTree", function() {
});
describe("#getCellText()", function () {
it("should return new value after edit", function* () {
it("should return new value after edit", async function () {
var str = Zotero.Utilities.randomString();
var item = yield createDataObject('item', { title: str });
var item = await createDataObject('item', { title: str });
var row = itemsView.getRowIndexByID(item.id);
assert.equal(itemsView.getCellText(row, 'title'), str);
yield modifyDataObject(item);
await modifyDataObject(item);
assert.notEqual(itemsView.getCellText(row, 'title'), str);
})
})
@ -325,9 +325,9 @@ describe("Zotero.ItemTree", function() {
await assert.eventually.ok(win.ZoteroPane.itemSelected.returnValues[1]);
});
it("shouldn't select a new item if skipNotifier is passed", function* () {
it("shouldn't select a new item if skipNotifier is passed", async function () {
// Select existing item
yield itemsView.selectItem(existingItemID);
await itemsView.selectItem(existingItemID);
var selected = itemsView.getSelectedItems(true);
assert.lengthOf(selected, 1);
assert.equal(selected[0], existingItemID);
@ -337,7 +337,7 @@ describe("Zotero.ItemTree", function() {
// Create item with skipNotifier flag
var item = new Zotero.Item('book');
var id = yield item.saveTx({
var id = await item.saveTx({
skipNotifier: true
});
@ -399,15 +399,15 @@ describe("Zotero.ItemTree", function() {
assert.equal(selected[0].id, item.id);
});
it("shouldn't clear quicksearch if skipSelect is passed", function* () {
it("shouldn't clear quicksearch if skipSelect is passed", async function () {
var searchString = Zotero.Items.get(existingItemID).getField('title');
yield createDataObject('item');
await createDataObject('item');
var quicksearch = win.document.getElementById('zotero-tb-search-textbox');
quicksearch.value = searchString;
quicksearch.doCommand();
yield itemsView._refreshPromise;
await itemsView._refreshPromise;
assert.equal(itemsView.rowCount, 1);
@ -415,7 +415,7 @@ describe("Zotero.ItemTree", function() {
var item = new Zotero.Item('book');
var ran = Zotero.Utilities.randomString();
item.setField('title', ran);
var id = yield item.saveTx({
var id = await item.saveTx({
skipSelect: true
});
@ -425,18 +425,18 @@ describe("Zotero.ItemTree", function() {
// Clear search
quicksearch.value = "";
quicksearch.doCommand();
yield itemsView._refreshPromise;
await itemsView._refreshPromise;
});
it("shouldn't change selection outside of trash if new trashed item is created with skipSelect", function* () {
yield selectLibrary(win);
yield waitForItemsLoad(win);
it("shouldn't change selection outside of trash if new trashed item is created with skipSelect", async function () {
await selectLibrary(win);
await waitForItemsLoad(win);
itemsView.selection.clearSelection();
var item = createUnsavedDataObject('item');
item.deleted = true;
var id = yield item.saveTx({
var id = await item.saveTx({
skipSelect: true
});
@ -445,10 +445,10 @@ describe("Zotero.ItemTree", function() {
assert.lengthOf(selected, 0);
})
it("shouldn't select a modified item", function* () {
it("shouldn't select a modified item", async function () {
// Create item
var item = new Zotero.Item('book');
var id = yield item.saveTx();
var id = await item.saveTx();
itemsView.selection.clearSelection();
assert.lengthOf(itemsView.getSelectedItems(), 0);
@ -457,7 +457,7 @@ describe("Zotero.ItemTree", function() {
// Modify item
item.setField('title', 'no select on modify');
yield item.saveTx();
await item.saveTx();
// itemSelected should have been called once (from 'selectEventsSuppressed = false'
// in notify()) as a no-op
@ -468,12 +468,12 @@ describe("Zotero.ItemTree", function() {
assert.lengthOf(itemsView.getSelectedItems(), 0);
});
it("should maintain selection on a selected modified item", function* () {
it("should maintain selection on a selected modified item", async function () {
// Create item
var item = new Zotero.Item('book');
var id = yield item.saveTx();
var id = await item.saveTx();
yield itemsView.selectItem(id);
await itemsView.selectItem(id);
var selected = itemsView.getSelectedItems(true);
assert.lengthOf(selected, 1);
assert.equal(selected[0], id);
@ -483,7 +483,7 @@ describe("Zotero.ItemTree", function() {
// Modify item
item.setField('title', 'maintain selection on modify');
yield item.saveTx();
await item.saveTx();
// itemSelected should have been called once (from 'selectEventsSuppressed = false'
// in notify()) as a no-op
@ -496,9 +496,9 @@ describe("Zotero.ItemTree", function() {
assert.equal(selected[0], id);
});
it("should reselect the same row when an item is removed", function* () {
var collection = yield createDataObject('collection');
yield selectCollection(win, collection);
it("should reselect the same row when an item is removed", async function () {
var collection = await createDataObject('collection');
await selectCollection(win, collection);
itemsView = zp.itemsView;
var items = [];
@ -506,7 +506,7 @@ describe("Zotero.ItemTree", function() {
for (let i = 0; i < num; i++) {
let item = createUnsavedDataObject('item', { title: "" + i });
item.addToCollection(collection.id);
yield item.saveTx();
await item.saveTx();
items.push(item);
}
assert.equal(itemsView.rowCount, num);
@ -516,7 +516,7 @@ describe("Zotero.ItemTree", function() {
// Remove item
var treeRow = itemsView.getRow(2);
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
await collection.removeItems([treeRow.ref.id]);
}.bind(this));
@ -525,27 +525,27 @@ describe("Zotero.ItemTree", function() {
// Delete item
var treeRow = itemsView.getRow(2);
yield treeRow.ref.eraseTx();
await treeRow.ref.eraseTx();
// Selection should stay on third row
assert.equal(itemsView.selection.focused, 2);
yield Zotero.Items.erase(items.map(item => item.id));
await Zotero.Items.erase(items.map(item => item.id));
});
it("shouldn't select sibling on attachment erase if attachment wasn't selected", function* () {
var item = yield createDataObject('item');
var att1 = yield importFileAttachment('test.png', { title: 'A', parentItemID: item.id });
var att2 = yield importFileAttachment('test.png', { title: 'B', parentItemID: item.id });
yield zp.itemsView.selectItem(att2.id); // expand
yield zp.itemsView.selectItem(item.id);
yield att1.eraseTx();
it("shouldn't select sibling on attachment erase if attachment wasn't selected", async function () {
var item = await createDataObject('item');
var att1 = await importFileAttachment('test.png', { title: 'A', parentItemID: item.id });
var att2 = await importFileAttachment('test.png', { title: 'B', parentItemID: item.id });
await zp.itemsView.selectItem(att2.id); // expand
await zp.itemsView.selectItem(item.id);
await att1.eraseTx();
assert.sameMembers(zp.itemsView.getSelectedItems(true), [item.id]);
});
it("should keep first visible item in view when other items are added with skipSelect and nothing in view is selected", function* () {
var collection = yield createDataObject('collection');
yield waitForItemsLoad(win);
it("should keep first visible item in view when other items are added with skipSelect and nothing in view is selected", async function () {
var collection = await createDataObject('collection');
await waitForItemsLoad(win);
itemsView = zp.itemsView;
var treebox = itemsView._treebox;
@ -557,7 +557,7 @@ describe("Zotero.ItemTree", function() {
}
var num = numVisibleRows + 10;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
for (let i = 0; i < num; i++) {
let title = getTitle(i, num);
let item = createUnsavedDataObject('item', { title });
@ -575,11 +575,11 @@ describe("Zotero.ItemTree", function() {
var item = createUnsavedDataObject(
'item', { title: getTitle(0, num), collections: [collection.id] }
);
yield item.saveTx({
await item.saveTx({
skipSelect: true
});
// Then add a few more in a transaction
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
for (let i = 0; i < 3; i++) {
var item = createUnsavedDataObject(
'item', { title: getTitle(0, num), collections: [collection.id] }
@ -650,9 +650,9 @@ describe("Zotero.ItemTree", function() {
assert.equal(newOffset, offset);
});
it("shouldn't scroll items list if at top when other items are added with skipSelect", function* () {
var collection = yield createDataObject('collection');
yield select(win, collection);
it("shouldn't scroll items list if at top when other items are added with skipSelect", async function () {
var collection = await createDataObject('collection');
await select(win, collection);
itemsView = zp.itemsView;
var treebox = itemsView._treebox;
@ -664,7 +664,7 @@ describe("Zotero.ItemTree", function() {
}
var num = numVisibleRows + 10;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
// Start at "*1" so we can add items before
for (let i = 1; i < num; i++) {
let title = getTitle(i, num);
@ -681,11 +681,11 @@ describe("Zotero.ItemTree", function() {
var item = createUnsavedDataObject(
'item', { title: getTitle(0, num), collections: [collection.id] }
);
yield item.saveTx({
await item.saveTx({
skipSelect: true
});
// Then add a few more in a transaction
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
for (let i = 0; i < 3; i++) {
var item = createUnsavedDataObject(
'item', { title: getTitle(0, num), collections: [collection.id] }
@ -748,7 +748,7 @@ describe("Zotero.ItemTree", function() {
assert.equal(itemsView.getRow(3).ref.getField('title'), title + " 5");
});
it("should update search results when search conditions are changed", function* () {
it("should update search results when search conditions are changed", async function () {
var search = createUnsavedDataObject('search');
var title1 = Zotero.Utilities.randomString();
var title2 = Zotero.Utilities.randomString();
@ -762,21 +762,21 @@ describe("Zotero.ItemTree", function() {
}
]
});
yield search.saveTx();
await search.saveTx();
yield select(win, search);
await select(win, search);
// Add an item that doesn't match search
var item = yield createDataObject('item', { title: title2 });
yield waitForItemsLoad(win);
var item = await createDataObject('item', { title: title2 });
await waitForItemsLoad(win);
assert.equal(zp.itemsView.rowCount, 0);
// Modify conditions to match item
search.removeCondition(0);
search.addCondition("title", "is", title2);
yield search.saveTx();
await search.saveTx();
yield waitForItemsLoad(win);
await waitForItemsLoad(win);
assert.equal(zp.itemsView.rowCount, 1);
});
@ -920,23 +920,23 @@ describe("Zotero.ItemTree", function() {
});
describe("Trash", function () {
it("should remove untrashed parent item when last trashed child is deleted", function* () {
var item = yield createDataObject('item');
var note = yield createDataObject(
it("should remove untrashed parent item when last trashed child is deleted", async function () {
var item = await createDataObject('item');
var note = await createDataObject(
'item', { itemType: 'note', parentID: item.id, deleted: true }
);
yield selectTrash(win);
await selectTrash(win);
assert.isNumber(zp.itemsView.getRowIndexByID(item.id));
var promise = waitForDialog();
yield zp.emptyTrash();
yield promise;
await zp.emptyTrash();
await promise;
// Small delay for modal to close and notifications to go through
// otherwise, next publications tab does not get opened
yield Zotero.Promise.delay(100);
await Zotero.Promise.delay(100);
assert.equal(zp.itemsView.rowCount, 0);
});
it("should show only top-most trashed collection", async function() {
it("should show only top-most trashed collection", async function () {
var c1 = await createDataObject('collection', { deleted: true });
var c2 = await createDataObject('collection', { parentID: c1.id });
var c3 = await createDataObject('collection', { parentID: c2.id });
@ -950,7 +950,7 @@ describe("Zotero.ItemTree", function() {
assert.isFalse(itemsView.getRowIndexByID(c3.treeViewID));
})
it("should restore all subcollections when parent is restored", async function() {
it("should restore all subcollections when parent is restored", async function () {
var c1 = await createDataObject('collection', { deleted: true });
var c2 = await createDataObject('collection', { parentID: c1.id });
var c3 = await createDataObject('collection', { parentID: c2.id });
@ -1026,32 +1026,32 @@ describe("Zotero.ItemTree", function() {
assert.isNumber(itemsView.getRowIndexByID(item.id));
});
it("should add new item to My Publications items list", function* () {
it("should add new item to My Publications items list", async function () {
var item1 = createUnsavedDataObject('item');
item1.inPublications = true;
yield item1.saveTx();
await item1.saveTx();
yield zp.collectionsView.selectByID("P" + item1.libraryID);
yield waitForItemsLoad(win);
await zp.collectionsView.selectByID("P" + item1.libraryID);
await waitForItemsLoad(win);
var messageElem = win.document.querySelector('.items-tree-message');
assert.equal(messageElem.style.display, 'none');
var item2 = createUnsavedDataObject('item');
item2.inPublications = true;
yield item2.saveTx();
await item2.saveTx();
assert.isNumber(itemsView.getRowIndexByID(item2.id));
});
it("should add modified item to My Publications items list", function* () {
it("should add modified item to My Publications items list", async function () {
var item1 = createUnsavedDataObject('item');
item1.inPublications = true;
yield item1.saveTx();
var item2 = yield createDataObject('item');
await item1.saveTx();
var item2 = await createDataObject('item');
yield zp.collectionsView.selectByID("P" + item1.libraryID);
yield waitForItemsLoad(win);
await zp.collectionsView.selectByID("P" + item1.libraryID);
await waitForItemsLoad(win);
var messageElem = win.document.querySelector('.items-tree-message');
assert.equal(messageElem.style.display, 'none');
@ -1059,36 +1059,36 @@ describe("Zotero.ItemTree", function() {
assert.isFalse(itemsView.getRowIndexByID(item2.id));
item2.inPublications = true;
yield item2.saveTx();
await item2.saveTx();
assert.isNumber(itemsView.getRowIndexByID(item2.id));
});
it("should show Show/Hide button for imported file attachment", function* () {
var item = yield createDataObject('item', { inPublications: true });
var attachment = yield importFileAttachment('test.png', { parentItemID: item.id });
it("should show Show/Hide button for imported file attachment", async function () {
var item = await createDataObject('item', { inPublications: true });
var attachment = await importFileAttachment('test.png', { parentItemID: item.id });
yield zp.collectionsView.selectByID("P" + item.libraryID);
yield waitForItemsLoad(win);
await zp.collectionsView.selectByID("P" + item.libraryID);
await waitForItemsLoad(win);
yield itemsView.selectItem(attachment.id);
yield Zotero.Promise.delay();
await itemsView.selectItem(attachment.id);
await Zotero.Promise.delay();
var box = zp.itemPane.getCurrentPane().querySelector('.item-pane-my-publications-button');
assert.isFalse(box.hidden);
});
it("shouldn't show Show/Hide button for linked file attachment", function* () {
var item = yield createDataObject('item', { inPublications: true });
var attachment = yield Zotero.Attachments.linkFromFile({
it("shouldn't show Show/Hide button for linked file attachment", async function () {
var item = await createDataObject('item', { inPublications: true });
var attachment = await Zotero.Attachments.linkFromFile({
file: OS.Path.join(getTestDataDirectory().path, 'test.png'),
parentItemID: item.id
});
yield zp.collectionsView.selectByID("P" + item.libraryID);
yield waitForItemsLoad(win);
await zp.collectionsView.selectByID("P" + item.libraryID);
await waitForItemsLoad(win);
yield itemsView.selectItem(attachment.id);
await itemsView.selectItem(attachment.id);
var box = zp.itemPane.getCurrentPane().querySelector('.item-pane-my-publications-button');
// box is not created if it shouldn't show
@ -1159,14 +1159,14 @@ describe("Zotero.ItemTree", function() {
Zotero.Prefs.clear('autoRenameFiles.linked');
});
it("should move a child item from one item to another", function* () {
var collection = yield createDataObject('collection');
yield waitForItemsLoad(win);
var item1 = yield createDataObject('item', { title: "A", collections: [collection.id] });
var item2 = yield createDataObject('item', { title: "B", collections: [collection.id] });
var item3 = yield createDataObject('item', { itemType: 'note', parentID: item1.id });
it("should move a child item from one item to another", async function () {
var collection = await createDataObject('collection');
await waitForItemsLoad(win);
var item1 = await createDataObject('item', { title: "A", collections: [collection.id] });
var item2 = await createDataObject('item', { title: "B", collections: [collection.id] });
var item3 = await createDataObject('item', { itemType: 'note', parentID: item1.id });
yield itemsView.selectItem(item3.id);
await itemsView.selectItem(item3.id);
var promise = itemsView.waitForSelect();
@ -1182,7 +1182,7 @@ describe("Zotero.ItemTree", function() {
mozItemCount: 1
});
yield promise;
await promise;
// Old parent should be empty
assert.isFalse(itemsView.isContainerOpen(itemsView.getRowIndexByID(item1.id)));
@ -1193,14 +1193,14 @@ describe("Zotero.ItemTree", function() {
assert.isFalse(itemsView.isContainerEmpty(itemsView.getRowIndexByID(item2.id)));
});
it("should move a child item from last item in list to another", function* () {
var collection = yield createDataObject('collection');
yield waitForItemsLoad(win);
var item1 = yield createDataObject('item', { title: "A", collections: [collection.id] });
var item2 = yield createDataObject('item', { title: "B", collections: [collection.id] });
var item3 = yield createDataObject('item', { itemType: 'note', parentID: item2.id });
it("should move a child item from last item in list to another", async function () {
var collection = await createDataObject('collection');
await waitForItemsLoad(win);
var item1 = await createDataObject('item', { title: "A", collections: [collection.id] });
var item2 = await createDataObject('item', { title: "B", collections: [collection.id] });
var item3 = await createDataObject('item', { itemType: 'note', parentID: item2.id });
yield itemsView.selectItem(item3.id);
await itemsView.selectItem(item3.id);
var promise = itemsView.waitForSelect();
@ -1216,7 +1216,7 @@ describe("Zotero.ItemTree", function() {
mozItemCount: 1
});
yield promise;
await promise;
// Old parent should be empty
assert.isFalse(itemsView.isContainerOpen(itemsView.getRowIndexByID(item2.id)));
@ -1227,7 +1227,7 @@ describe("Zotero.ItemTree", function() {
assert.isFalse(itemsView.isContainerEmpty(itemsView.getRowIndexByID(item1.id)));
});
it("should create a stored top-level attachment when a file is dragged", function* () {
it("should create a stored top-level attachment when a file is dragged", async function () {
var file = getTestDataDirectory();
file.append('test.png');
@ -1245,18 +1245,18 @@ describe("Zotero.ItemTree", function() {
}
})
yield promise;
await promise;
// Attachment add triggers multiple notifications and multiple select events
yield itemsView.waitForSelect();
await itemsView.waitForSelect();
var items = itemsView.getSelectedItems();
var path = yield items[0].getFilePathAsync();
var path = await items[0].getFilePathAsync();
assert.equal(
(yield Zotero.File.getBinaryContentsAsync(path)),
(yield Zotero.File.getBinaryContentsAsync(file))
((await Zotero.File.getBinaryContentsAsync(path))),
((await Zotero.File.getBinaryContentsAsync(file)))
);
});
it("should create a stored top-level attachment when a URL is dragged", function* () {
it("should create a stored top-level attachment when a URL is dragged", async function () {
var promise = itemsView.waitForSelect();
drop(0, -1, {
@ -1271,18 +1271,18 @@ describe("Zotero.ItemTree", function() {
mozItemCount: 1,
})
yield promise;
await promise;
var item = itemsView.getSelectedItems()[0];
assert.equal(item.getField('url'), pdfURL);
assert.equal(
(yield Zotero.File.getBinaryContentsAsync(yield item.getFilePathAsync())),
(yield Zotero.File.getBinaryContentsAsync(pdfPath))
((await Zotero.File.getBinaryContentsAsync(await item.getFilePathAsync()))),
((await Zotero.File.getBinaryContentsAsync(pdfPath)))
);
});
it("should create a stored child attachment when a URL is dragged", function* () {
it("should create a stored child attachment when a URL is dragged", async function () {
var view = zp.itemsView;
var parentItem = yield createDataObject('item');
var parentItem = await createDataObject('item');
var parentRow = view.getRowIndexByID(parentItem.id);
var promise = waitForItemEvent('add');
@ -1299,13 +1299,13 @@ describe("Zotero.ItemTree", function() {
mozItemCount: 1,
})
var itemIDs = yield promise;
var itemIDs = await promise;
var item = Zotero.Items.get(itemIDs[0]);
assert.equal(item.parentItemID, parentItem.id);
assert.equal(item.getField('url'), pdfURL);
assert.equal(
(yield Zotero.File.getBinaryContentsAsync(yield item.getFilePathAsync())),
(yield Zotero.File.getBinaryContentsAsync(pdfPath))
((await Zotero.File.getBinaryContentsAsync(await item.getFilePathAsync()))),
((await Zotero.File.getBinaryContentsAsync(pdfPath)))
);
});
@ -1742,7 +1742,7 @@ describe("Zotero.ItemTree", function() {
});
});
describe("Annotations", function() {
describe("Annotations", function () {
let toplevelItem, attachment, highlight, underline, ink, image, note;
before(async () => {

View file

@ -16,23 +16,23 @@ describe("Zotero.Items", function () {
describe("#addToPublications", function () {
it("should add an item to My Publications", function* () {
var item = yield createDataObject('item');
yield Zotero.Items.addToPublications([item]);
it("should add an item to My Publications", async function () {
var item = await createDataObject('item');
await Zotero.Items.addToPublications([item]);
assert.isTrue(item.inPublications);
assert.equal(
(yield Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", item.id)),
((await Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", item.id))),
1
);
});
describe("#license", function () {
it("should set a license if specified", function* () {
it("should set a license if specified", async function () {
var item = createUnsavedDataObject('item');
item.setField('rights', 'Test');
yield item.saveTx();
yield Zotero.Items.addToPublications(
await item.saveTx();
await Zotero.Items.addToPublications(
[item],
{
license: 'reserved',
@ -43,12 +43,12 @@ describe("Zotero.Items", function () {
assert.equal(item.getField('rights'), 'All Rights Reserved');
});
it("should keep existing Rights field if .keepRights is true", function* () {
it("should keep existing Rights field if .keepRights is true", async function () {
var item1 = createUnsavedDataObject('item');
item1.setField('rights', 'Test');
yield item1.saveTx();
var item2 = yield createDataObject('item');
yield Zotero.Items.addToPublications(
await item1.saveTx();
var item2 = await createDataObject('item');
await Zotero.Items.addToPublications(
[item1, item2],
{
license: 'reserved',
@ -60,70 +60,70 @@ describe("Zotero.Items", function () {
assert.equal(item2.getField('rights'), 'All Rights Reserved');
});
it("shouldn't set a license if not specified", function* () {
it("shouldn't set a license if not specified", async function () {
var item = createUnsavedDataObject('item');
item.setField('rights', 'Test');
yield item.saveTx();
yield Zotero.Items.addToPublications([item]);
await item.saveTx();
await Zotero.Items.addToPublications([item]);
assert.equal(item.getField('rights'), 'Test');
});
});
it("should add child notes if .childNotes is true", function* () {
var item = yield createDataObject('item');
var note = yield createDataObject('item', { itemType: 'note', parentID: item.id });
var attachment = yield Zotero.Attachments.linkFromURL({
it("should add child notes if .childNotes is true", async function () {
var item = await createDataObject('item');
var note = await createDataObject('item', { itemType: 'note', parentID: item.id });
var attachment = await Zotero.Attachments.linkFromURL({
url: "http://example.com",
parentItemID: item.id,
title: "Example"
});
yield Zotero.Items.addToPublications([item], { childNotes: true });
await Zotero.Items.addToPublications([item], { childNotes: true });
assert.isTrue(note.inPublications);
assert.equal(
(yield Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", note.id)),
((await Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", note.id))),
1
);
assert.isFalse(attachment.inPublications);
});
it("should add child link attachments if .childLinks is true", function* () {
var item = yield createDataObject('item');
var attachment1 = yield Zotero.Attachments.linkFromURL({
it("should add child link attachments if .childLinks is true", async function () {
var item = await createDataObject('item');
var attachment1 = await Zotero.Attachments.linkFromURL({
url: "http://example.com",
parentItemID: item.id,
title: "Example"
});
var attachment2 = yield importFileAttachment('test.png', { parentItemID: item.id });
var note = yield createDataObject('item', { itemType: 'note', parentID: item.id });
var attachment2 = await importFileAttachment('test.png', { parentItemID: item.id });
var note = await createDataObject('item', { itemType: 'note', parentID: item.id });
yield Zotero.Items.addToPublications([item], { childLinks: true });
await Zotero.Items.addToPublications([item], { childLinks: true });
assert.isTrue(attachment1.inPublications);
assert.equal(
(yield Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", attachment1.id)),
((await Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", attachment1.id))),
1
);
assert.isFalse(attachment2.inPublications);
assert.isFalse(note.inPublications);
});
it("should add child file attachments if .childFileAttachments is true", function* () {
var item = yield createDataObject('item');
var attachment1 = yield importFileAttachment('test.png', { parentItemID: item.id });
var attachment2 = yield Zotero.Attachments.linkFromURL({
it("should add child file attachments if .childFileAttachments is true", async function () {
var item = await createDataObject('item');
var attachment1 = await importFileAttachment('test.png', { parentItemID: item.id });
var attachment2 = await Zotero.Attachments.linkFromURL({
url: "http://example.com",
parentItemID: item.id,
title: "Example"
});
var note = yield createDataObject('item', { itemType: 'note', parentID: item.id });
var note = await createDataObject('item', { itemType: 'note', parentID: item.id });
yield Zotero.Items.addToPublications([item], { childFileAttachments: true });
await Zotero.Items.addToPublications([item], { childFileAttachments: true });
assert.isTrue(attachment1.inPublications);
assert.equal(
(yield Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", attachment1.id)),
((await Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", attachment1.id))),
1
);
assert.isFalse(attachment2.inPublications);
@ -133,20 +133,20 @@ describe("Zotero.Items", function () {
describe("#removeFromPublications", function () {
it("should remove an item from My Publications", function* () {
var item = yield createDataObject('item');
it("should remove an item from My Publications", async function () {
var item = await createDataObject('item');
item.inPublications = true;
yield item.saveTx();
await item.saveTx();
assert.equal(
(yield Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", item.id)),
((await Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", item.id))),
1
);
yield Zotero.Items.removeFromPublications([item]);
await Zotero.Items.removeFromPublications([item]);
assert.isFalse(item.inPublications);
assert.equal(
(yield Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", item.id)),
((await Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM publicationsItems WHERE itemID=?", item.id))),
0
);
});
@ -219,12 +219,12 @@ describe("Zotero.Items", function () {
describe("#merge()", function () {
it("should merge two items", function* () {
var item1 = yield createDataObject('item');
var item2 = yield createDataObject('item');
it("should merge two items", async function () {
var item1 = await createDataObject('item');
var item2 = await createDataObject('item');
var item2URI = Zotero.URI.getItemURI(item2);
yield Zotero.Items.merge(item1, [item2]);
await Zotero.Items.merge(item1, [item2]);
assert.isFalse(item1.deleted);
assert.isTrue(item2.deleted);
@ -291,15 +291,15 @@ describe("Zotero.Items", function () {
assert.propertyVal(tags[0], 'type', 1);
});
it("should merge two items when servant is linked to an item absent from cache", function* () {
it("should merge two items when servant is linked to an item absent from cache", async function () {
// two group libraries
var groupOneInfo = yield createGroup({
var groupOneInfo = await createGroup({
id: 25026,
name: "Group One"
});
var libraryOneID = Zotero.Groups.getLibraryIDFromGroupID(groupOneInfo.id);
var groupTwoInfo = yield createGroup({
var groupTwoInfo = await createGroup({
id: 11592,
name: "Group Two"
});
@ -308,13 +308,13 @@ describe("Zotero.Items", function () {
assert.notEqual(libraryOneID, libraryTwoID);
// two items in the first library
var item1 = yield createDataObject('item', {libraryID: libraryOneID});
var item2 = yield createDataObject('item', {libraryID: libraryOneID});
var item1 = await createDataObject('item', {libraryID: libraryOneID});
var item2 = await createDataObject('item', {libraryID: libraryOneID});
var item2URI = Zotero.URI.getItemURI(item2);
// one item in the second library, linked to item2 as if it dragged and dropped from it
var itemX = yield createDataObject('item', {libraryID: libraryTwoID});
yield itemX.addLinkedItem(item2);
var itemX = await createDataObject('item', {libraryID: libraryTwoID});
await itemX.addLinkedItem(item2);
// check that the owl:sameAs relation has been registered okay
var rels = itemX.getRelationsByPredicate(Zotero.Relations.linkedObjectPredicate);
@ -327,7 +327,7 @@ describe("Zotero.Items", function () {
delete Zotero.Items._objectCache[itemX.id];
// merge the two items in the first library
yield Zotero.Items.merge(item1, [item2]);
await Zotero.Items.merge(item1, [item2]);
// check that the merge completed okay
assert.isFalse(item1.deleted);
@ -340,15 +340,15 @@ describe("Zotero.Items", function () {
assert.equal(rels[0], item2URI);
})
it("should move merge-tracking relation from replaced item to master", function* () {
var item1 = yield createDataObject('item');
var item2 = yield createDataObject('item');
it("should move merge-tracking relation from replaced item to master", async function () {
var item1 = await createDataObject('item');
var item2 = await createDataObject('item');
var item2URI = Zotero.URI.getItemURI(item2);
var item3 = yield createDataObject('item');
var item3 = await createDataObject('item');
var item3URI = Zotero.URI.getItemURI(item3);
yield Zotero.Items.merge(item2, [item3]);
yield Zotero.Items.merge(item1, [item2]);
await Zotero.Items.merge(item2, [item3]);
await Zotero.Items.merge(item1, [item2]);
// Check for merge-tracking relation from 1 to 3
var rels = item1.getRelationsByPredicate(Zotero.Relations.replacedItemPredicate);
@ -377,37 +377,37 @@ describe("Zotero.Items", function () {
);
});
it("should update relations pointing to replaced item to point to master", function* () {
var item1 = yield createDataObject('item');
it("should update relations pointing to replaced item to point to master", async function () {
var item1 = await createDataObject('item');
var item1URI = Zotero.URI.getItemURI(item1);
var item2 = yield createDataObject('item');
var item2 = await createDataObject('item');
var item2URI = Zotero.URI.getItemURI(item2);
var item3 = createUnsavedDataObject('item');
var predicate = Zotero.Relations.relatedItemPredicate;
item3.addRelation(predicate, item2URI);
yield item3.saveTx();
await item3.saveTx();
yield Zotero.Items.merge(item1, [item2]);
await Zotero.Items.merge(item1, [item2]);
// Check for related-item relation from 3 to 1
var rels = item3.getRelationsByPredicate(predicate);
assert.deepEqual(rels, [item1URI]);
})
it("should not update relations pointing to replaced item in other libraries", function* () {
var group1 = yield createGroup();
var group2 = yield createGroup();
it("should not update relations pointing to replaced item in other libraries", async function () {
var group1 = await createGroup();
var group2 = await createGroup();
var item1 = yield createDataObject('item', { libraryID: group1.libraryID });
var item1 = await createDataObject('item', { libraryID: group1.libraryID });
var item1URI = Zotero.URI.getItemURI(item1);
var item2 = yield createDataObject('item', { libraryID: group1.libraryID });
var item2 = await createDataObject('item', { libraryID: group1.libraryID });
var item2URI = Zotero.URI.getItemURI(item2);
var item3 = createUnsavedDataObject('item', { libraryID: group2.libraryID });
var predicate = Zotero.Relations.linkedObjectPredicate;
item3.addRelation(predicate, item2URI);
yield item3.saveTx();
await item3.saveTx();
yield Zotero.Items.merge(item1, [item2]);
await Zotero.Items.merge(item1, [item2]);
// Check for related-item relation from 3 to 2
var rels = item3.getRelationsByPredicate(predicate);
@ -1034,69 +1034,69 @@ describe("Zotero.Items", function () {
describe("#trash()", function () {
it("should send items to the trash", function* () {
it("should send items to the trash", async function () {
var items = [];
items.push(
(yield createDataObject('item', { synced: true })),
(yield createDataObject('item', { synced: true })),
(yield createDataObject('item', { synced: true }))
((await createDataObject('item', { synced: true }))),
((await createDataObject('item', { synced: true }))),
((await createDataObject('item', { synced: true })))
);
items.forEach(item => {
// Sanity-checked as true in itemTest#deleted
assert.isUndefined(item._changed.deleted);
});
var ids = items.map(item => item.id);
yield Zotero.Items.trashTx(ids);
await Zotero.Items.trashTx(ids);
items.forEach(item => {
assert.isTrue(item.deleted);
// Item should be saved (can't use hasChanged() because that includes .synced)
assert.isUndefined(item._changed.deleted);
assert.isFalse(item.synced);
});
assert.equal((yield Zotero.DB.valueQueryAsync(
assert.equal(((await Zotero.DB.valueQueryAsync(
`SELECT COUNT(*) FROM deletedItems WHERE itemID IN (${ids})`
)), 3);
))), 3);
for (let item of items) {
assert.equal((yield Zotero.DB.valueQueryAsync(
assert.equal(((await Zotero.DB.valueQueryAsync(
`SELECT synced FROM items WHERE itemID=${item.id}`
)), 0);
))), 0);
}
});
it("should update parent item when trashing child item", function* () {
var item = yield createDataObject('item');
var note = yield createDataObject('item', { itemType: 'note', parentID: item.id });
it("should update parent item when trashing child item", async function () {
var item = await createDataObject('item');
var note = await createDataObject('item', { itemType: 'note', parentID: item.id });
assert.lengthOf(item.getNotes(), 1);
yield Zotero.Items.trashTx([note.id]);
await Zotero.Items.trashTx([note.id]);
assert.lengthOf(item.getNotes(), 0);
});
});
describe("#emptyTrash()", function () {
it("should delete items in the trash", function* () {
it("should delete items in the trash", async function () {
var item1 = createUnsavedDataObject('item');
item1.setField('title', 'a');
item1.deleted = true;
var id1 = yield item1.saveTx();
var id1 = await item1.saveTx();
var item2 = createUnsavedDataObject('item');
item2.setField('title', 'b');
item2.deleted = true;
var id2 = yield item2.saveTx();
var id2 = await item2.saveTx();
var item3 = createUnsavedDataObject('item', { itemType: 'attachment', parentID: id2 });
item3.attachmentLinkMode = Zotero.Attachments.LINK_MODE_IMPORTED_URL;
item3.deleted = true;
var id3 = yield item3.saveTx();
var id3 = await item3.saveTx();
yield collectionsView.selectTrash(Zotero.Libraries.userLibraryID);
await collectionsView.selectTrash(Zotero.Libraries.userLibraryID);
yield Zotero.Items.emptyTrash(Zotero.Libraries.userLibraryID);
await Zotero.Items.emptyTrash(Zotero.Libraries.userLibraryID);
assert.isFalse(yield Zotero.Items.getAsync(id1));
assert.isFalse(yield Zotero.Items.getAsync(id2));
assert.isFalse(yield Zotero.Items.getAsync(id3));
assert.isFalse(await Zotero.Items.getAsync(id1));
assert.isFalse(await Zotero.Items.getAsync(id2));
assert.isFalse(await Zotero.Items.getAsync(id3));
// TEMP: This is failing on Travis due to a race condition
//assert.equal(zp.itemsView.rowCount, 0)
@ -1104,7 +1104,7 @@ describe("Zotero.Items", function () {
})
describe("#getFirstCreatorFromData()", function () {
it("should handle single eligible creator", function* () {
it("should handle single eligible creator", async function () {
for (let creatorType of ['author', 'editor', 'contributor']) {
assert.equal(
Zotero.Items.getFirstCreatorFromData(
@ -1124,7 +1124,7 @@ describe("Zotero.Items", function () {
}
});
it("should ignore single ineligible creator", function* () {
it("should ignore single ineligible creator", async function () {
assert.strictEqual(
Zotero.Items.getFirstCreatorFromData(
Zotero.ItemTypes.getID('book'),
@ -1141,7 +1141,7 @@ describe("Zotero.Items", function () {
);
});
it("should handle single eligible creator after ineligible creator", function* () {
it("should handle single eligible creator after ineligible creator", async function () {
for (let creatorType of ['author', 'editor', 'contributor']) {
assert.equal(
Zotero.Items.getFirstCreatorFromData(
@ -1167,7 +1167,7 @@ describe("Zotero.Items", function () {
}
});
it("should handle two eligible creators", function* () {
it("should handle two eligible creators", async function () {
for (let creatorType of ['author', 'editor', 'contributor']) {
assert.equal(
Zotero.Items.getFirstCreatorFromData(
@ -1196,7 +1196,7 @@ describe("Zotero.Items", function () {
}
});
it("should handle three eligible creators", function* () {
it("should handle three eligible creators", async function () {
for (let creatorType of ['author', 'editor', 'contributor']) {
assert.equal(
Zotero.Items.getFirstCreatorFromData(
@ -1228,7 +1228,7 @@ describe("Zotero.Items", function () {
}
});
it("should handle two eligible creators with intervening creators", function* () {
it("should handle two eligible creators with intervening creators", async function () {
for (let creatorType of ['author', 'editor', 'contributor']) {
assert.equal(
Zotero.Items.getFirstCreatorFromData(
@ -1270,24 +1270,24 @@ describe("Zotero.Items", function () {
});
});
describe("#getAsync()", function() {
it("should return Zotero.Item for item ID", function* () {
describe("#getAsync()", function () {
it("should return Zotero.Item for item ID", async function () {
let item = new Zotero.Item('journalArticle');
let id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
let id = await item.saveTx();
item = await Zotero.Items.getAsync(id);
assert.notOk(item.isFeedItem);
assert.instanceOf(item, Zotero.Item);
assert.notInstanceOf(item, Zotero.FeedItem);
});
it("should return Zotero.FeedItem for feed item ID", function* () {
it("should return Zotero.FeedItem for feed item ID", async function () {
let feed = new Zotero.Feed({ name: 'foo', url: 'http://www.' + Zotero.randomString() + '.com' });
yield feed.saveTx();
await feed.saveTx();
let feedItem = new Zotero.FeedItem('journalArticle', { guid: Zotero.randomString() });
feedItem.libraryID = feed.libraryID;
let id = yield feedItem.saveTx();
let id = await feedItem.saveTx();
feedItem = yield Zotero.Items.getAsync(id);
feedItem = await Zotero.Items.getAsync(id);
assert.isTrue(feedItem.isFeedItem);
assert.instanceOf(feedItem, Zotero.FeedItem);

View file

@ -1,4 +1,4 @@
describe("Zotero.Libraries", function() {
describe("Zotero.Libraries", function () {
let groupName = 'test',
group,
builtInLibraries;
@ -10,28 +10,28 @@ describe("Zotero.Libraries", function() {
group = yield createGroup({ name: groupName });
});
it("should provide user library ID as .userLibraryID", function() {
it("should provide user library ID as .userLibraryID", function () {
assert.isDefined(Zotero.Libraries.userLibraryID);
assert(Number.isInteger(Zotero.Libraries.userLibraryID), ".userLibraryID is an integer");
assert.isAbove(Zotero.Libraries.userLibraryID, 0);
});
describe("#getAll()", function() {
it("should return an array of Zotero.Library instances", function() {
describe("#getAll()", function () {
it("should return an array of Zotero.Library instances", function () {
let libraries = Zotero.Libraries.getAll();
assert.isArray(libraries);
assert(libraries.every(library => library instanceof Zotero.Library));
})
it("should return all libraries in sorted order", function* () {
it("should return all libraries in sorted order", async function () {
// Add/remove a few group libraries beforehand to ensure that data is kept in sync
let library = yield createGroup();
let tempLib = yield createGroup();
yield tempLib.eraseTx();
let library = await createGroup();
let tempLib = await createGroup();
await tempLib.eraseTx();
var libraries = Zotero.Libraries.getAll();
var ids = libraries.map(library => library.libraryID);
var dbIDs = yield Zotero.DB.columnQueryAsync("SELECT libraryID FROM libraries");
var dbIDs = await Zotero.DB.columnQueryAsync("SELECT libraryID FROM libraries");
assert.sameMembers(ids, dbIDs);
assert.equal(dbIDs.length, ids.length, "returns correct number of IDs");
@ -51,136 +51,136 @@ describe("Zotero.Libraries", function() {
}
// remove left-over library
yield library.eraseTx();
await library.eraseTx();
});
});
describe("#exists()", function() {
it("should return true for all existing IDs", function() {
describe("#exists()", function () {
it("should return true for all existing IDs", function () {
let ids = Zotero.Libraries.getAll().map(library => library.libraryID);
assert.isTrue(ids.reduce(function(res, id) { return res && Zotero.Libraries.exists(id) }, true));
assert.isTrue(ids.reduce(function (res, id) { return res && Zotero.Libraries.exists(id) }, true));
});
it("should return false for a non-existing ID", function() {
it("should return false for a non-existing ID", function () {
assert.isFalse(Zotero.Libraries.exists(-1), "returns boolean false for a negative ID");
let badID = Zotero.Libraries.getAll().map(lib => lib.libraryID).reduce((a, b) => (a < b ? b : a)) + 1;
assert.isFalse(Zotero.Libraries.exists(badID), "returns boolean false for a non-existent positive ID");
});
});
describe("#getName()", function() {
it("should return correct library name for built-in libraries", function() {
describe("#getName()", function () {
it("should return correct library name for built-in libraries", function () {
assert.equal(Zotero.Libraries.getName(Zotero.Libraries.userLibraryID), Zotero.getString('pane.collections.library'), "user library name is correct");
});
it("should return correct name for a group library", function() {
it("should return correct name for a group library", function () {
assert.equal(Zotero.Libraries.getName(group.libraryID), groupName);
});
it("should throw for invalid library ID", function() {
it("should throw for invalid library ID", function () {
assert.throws(() => Zotero.Libraries.getName(-1), /^Invalid library ID /);
});
});
describe("#getType()", function() {
it("should return correct library type for built-in libraries", function() {
describe("#getType()", function () {
it("should return correct library type for built-in libraries", function () {
assert.equal(Zotero.Libraries.getType(Zotero.Libraries.userLibraryID), 'user', "user library type is correct");
});
it("should return correct library type for a group library", function() {
it("should return correct library type for a group library", function () {
assert.equal(Zotero.Libraries.getType(group.libraryID), 'group');
});
it("should throw for invalid library ID", function() {
it("should throw for invalid library ID", function () {
assert.throws(() => Zotero.Libraries.getType(-1), /^Invalid library ID /);
});
});
describe("#isEditable()", function() {
it("should always return true for user library", function() {
describe("#isEditable()", function () {
it("should always return true for user library", function () {
assert.isTrue(Zotero.Libraries.isEditable(Zotero.Libraries.userLibraryID));
});
it("should return correct state for a group library", function* () {
it("should return correct state for a group library", async function () {
group.editable = true;
yield group.saveTx();
await group.saveTx();
assert.isTrue(Zotero.Libraries.isEditable(group.libraryID));
group.editable = false;
yield group.saveTx();
await group.saveTx();
assert.isFalse(Zotero.Libraries.isEditable(group.libraryID));
});
it("should throw for invalid library ID", function() {
it("should throw for invalid library ID", function () {
assert.throws(Zotero.Libraries.isEditable.bind(Zotero.Libraries, -1), /^Invalid library ID /);
});
it("should not depend on filesEditable", function* () {
it("should not depend on filesEditable", async function () {
let editableStartState = Zotero.Libraries.isEditable(group.libraryID),
filesEditableStartState = Zotero.Libraries.isFilesEditable(group.libraryID);
// Test all combinations
// E: true, FE: true => true
yield Zotero.Libraries.setEditable(group.libraryID, true);
yield Zotero.Libraries.setFilesEditable(group.libraryID, true);
await Zotero.Libraries.setEditable(group.libraryID, true);
await Zotero.Libraries.setFilesEditable(group.libraryID, true);
assert.isTrue(Zotero.Libraries.isEditable(group.libraryID));
// E: false, FE: true => false
yield Zotero.Libraries.setEditable(group.libraryID, false);
await Zotero.Libraries.setEditable(group.libraryID, false);
assert.isFalse(Zotero.Libraries.isEditable(group.libraryID));
// E: false, FE: false => false
yield Zotero.Libraries.setFilesEditable(group.libraryID, false);
await Zotero.Libraries.setFilesEditable(group.libraryID, false);
assert.isFalse(Zotero.Libraries.isEditable(group.libraryID));
// E: true, FE: false => true
yield Zotero.Libraries.setEditable(group.libraryID, true);
await Zotero.Libraries.setEditable(group.libraryID, true);
assert.isTrue(Zotero.Libraries.isEditable(group.libraryID));
// Revert settings
yield Zotero.Libraries.setFilesEditable(group.libraryID, filesEditableStartState);
yield Zotero.Libraries.setEditable(group.libraryID, editableStartState);
await Zotero.Libraries.setFilesEditable(group.libraryID, filesEditableStartState);
await Zotero.Libraries.setEditable(group.libraryID, editableStartState);
});
});
describe("#setEditable()", function() {
it("should not allow changing editable state of built-in libraries", function* () {
describe("#setEditable()", function () {
it("should not allow changing editable state of built-in libraries", async function () {
for (let i=0; i<builtInLibraries.length; i++) {
yield assert.isRejected(Zotero.Libraries.setEditable(builtInLibraries[i]));
await assert.isRejected(Zotero.Libraries.setEditable(builtInLibraries[i]));
}
});
it("should allow changing editable state for group library", function* () {
it("should allow changing editable state for group library", async function () {
let startState = Zotero.Libraries.isEditable(group.libraryID);
yield Zotero.Libraries.setEditable(group.libraryID, !startState);
await Zotero.Libraries.setEditable(group.libraryID, !startState);
assert.equal(Zotero.Libraries.isEditable(group.libraryID), !startState, 'changes state');
yield Zotero.Libraries.setEditable(group.libraryID, startState);
await Zotero.Libraries.setEditable(group.libraryID, startState);
assert.equal(Zotero.Libraries.isEditable(group.libraryID), startState, 'reverts state');
});
it("should throw for invalid library ID", function() {
it("should throw for invalid library ID", function () {
return assert.isRejected(Zotero.Libraries.setEditable(-1), /^Invalid library ID /);
});
});
describe("#isFilesEditable()", function() {
it("should throw for invalid library ID", function() {
describe("#isFilesEditable()", function () {
it("should throw for invalid library ID", function () {
assert.throws(Zotero.Libraries.isFilesEditable.bind(Zotero.Libraries, -1), /^Invalid library ID /);
});
});
describe("#setFilesEditable()", function() {
it("should not allow changing files editable state of built-in libraries", function* () {
describe("#setFilesEditable()", function () {
it("should not allow changing files editable state of built-in libraries", async function () {
for (let i=0; i<builtInLibraries.length; i++) {
yield assert.isRejected(Zotero.Libraries.setFilesEditable(builtInLibraries[i]));
await assert.isRejected(Zotero.Libraries.setFilesEditable(builtInLibraries[i]));
}
});
it("should allow changing files editable state for group library", function* () {
it("should allow changing files editable state for group library", async function () {
let startState = Zotero.Libraries.isFilesEditable(group.libraryID),
editableStartState = Zotero.Libraries.isEditable(group.libraryID);
// Since filesEditable is false for all non-editable libraries
yield Zotero.Libraries.setEditable(group.libraryID, true);
await Zotero.Libraries.setEditable(group.libraryID, true);
yield Zotero.Libraries.setFilesEditable(group.libraryID, !startState);
await Zotero.Libraries.setFilesEditable(group.libraryID, !startState);
assert.equal(Zotero.Libraries.isFilesEditable(group.libraryID), !startState, 'changes state');
yield Zotero.Libraries.setFilesEditable(group.libraryID, startState);
await Zotero.Libraries.setFilesEditable(group.libraryID, startState);
assert.equal(Zotero.Libraries.isFilesEditable(group.libraryID), startState, 'reverts state');
yield Zotero.Libraries.setEditable(group.libraryID, editableStartState);
await Zotero.Libraries.setEditable(group.libraryID, editableStartState);
});
it("should throw for invalid library ID", function* () {
it("should throw for invalid library ID", async function () {
return assert.isRejected(Zotero.Libraries.setFilesEditable(-1), /^Invalid library ID /);
});
});
describe("#isGroupLibrary()", function() {
it("should return false for non-group libraries", function() {
describe("#isGroupLibrary()", function () {
it("should return false for non-group libraries", function () {
for (let i=0; i<builtInLibraries.length; i++) {
let id = builtInLibraries[i],
type = Zotero.Libraries.getType(id);
@ -192,16 +192,16 @@ describe("Zotero.Libraries", function() {
assert.isTrue(Zotero.Libraries.isGroupLibrary(group.libraryID));
})
it("should throw for invalid library ID", function() {
it("should throw for invalid library ID", function () {
assert.throws(Zotero.Libraries.isGroupLibrary.bind(Zotero.Libraries, -1), /^Invalid library ID /);
});
});
describe("#hasTrash()", function() {
it("should return true for all library types", function() {
describe("#hasTrash()", function () {
it("should return true for all library types", function () {
assert.isTrue(Zotero.Libraries.hasTrash(Zotero.Libraries.userLibraryID));
assert.isTrue(Zotero.Libraries.hasTrash(group.libraryID));
});
it("should throw for invalid library ID", function() {
it("should throw for invalid library ID", function () {
assert.throws(Zotero.Libraries.hasTrash.bind(Zotero.Libraries, -1), /^Invalid library ID /);
});
});

View file

@ -1,49 +1,49 @@
describe("Zotero.Library", function() {
describe("#constructor()", function() {
it("should allow no arguments", function() {
describe("Zotero.Library", function () {
describe("#constructor()", function () {
it("should allow no arguments", function () {
assert.doesNotThrow(() => new Zotero.Library());
});
});
describe("#libraryID", function() {
it("should not allow setting a library ID", function() {
describe("#libraryID", function () {
it("should not allow setting a library ID", function () {
let library = new Zotero.Library();
assert.throws(() => library.libraryID = 1);
});
it("should return a library ID for a saved library", function() {
it("should return a library ID for a saved library", function () {
let library = Zotero.Libraries.get(Zotero.Libraries.userLibraryID);
assert.isAbove(library.libraryID, 0);
})
});
describe("#libraryType", function() {
it("should not allow creating a non-basic library", function() {
describe("#libraryType", function () {
it("should not allow creating a non-basic library", function () {
let library = new Zotero.Library();
assert.throws(() => library.libraryType = 'group', /^Invalid library type /);
});
it("should not allow setting a library type for a saved library", function* () {
let library = yield createGroup();
it("should not allow setting a library type for a saved library", async function () {
let library = await createGroup();
assert.throws(() => library.libraryType = 'feed');
});
it("should not allow creating new unique libraries", function* () {
it("should not allow creating new unique libraries", async function () {
for (let i=0; i<Zotero.Library.prototype.fixedLibraries.length; i++) {
let libraryType = Zotero.Library.prototype.fixedLibraries[i];
assert.throws(function() {new Zotero.Library({ libraryType })}, /^Cannot create library of type /, 'cannot create a new ' + libraryType + ' library');
assert.throws(function () {new Zotero.Library({ libraryType })}, /^Cannot create library of type /, 'cannot create a new ' + libraryType + ' library');
}
});
});
describe("#libraryTypeID", function () {
it("should return a group id for a group", function* () {
let library = yield createGroup();
it("should return a group id for a group", async function () {
let library = await createGroup();
assert.typeOf(library.libraryTypeID, 'number');
assert.equal(library.libraryTypeID, library.groupID);
})
})
describe("#libraryVersion", function() {
it("should be settable to increasing values", function() {
describe("#libraryVersion", function () {
it("should be settable to increasing values", function () {
let library = new Zotero.Library();
assert.throws(() => library.libraryVersion = -2);
assert.throws(() => library.libraryVersion = "a");
@ -51,78 +51,78 @@ describe("Zotero.Library", function() {
assert.doesNotThrow(() => library.libraryVersion = 0);
assert.doesNotThrow(() => library.libraryVersion = 5);
});
it("should not be possible to decrement", function() {
it("should not be possible to decrement", function () {
let library = new Zotero.Library();
library.libraryVersion = 5;
assert.throws(() => library.libraryVersion = 0);
});
it("should be possible to set to -1", function() {
it("should be possible to set to -1", function () {
let library = new Zotero.Library();
library.libraryVersion = 5;
assert.doesNotThrow(() => library.libraryVersion = -1);
});
});
describe("#editable", function() {
it("should return editable status", function() {
describe("#editable", function () {
it("should return editable status", function () {
let library = Zotero.Libraries.get(Zotero.Libraries.userLibraryID);
assert.isTrue(library.editable, 'user library is editable');
});
it("should allow setting editable status", function* () {
let library = yield createGroup({ editable: true });
it("should allow setting editable status", async function () {
let library = await createGroup({ editable: true });
assert.isTrue(library.editable);
assert.isTrue(Zotero.Libraries.isEditable(library.libraryID), "sets editable in cache to true");
assert.equal((yield Zotero.DB.valueQueryAsync("SELECT editable FROM libraries WHERE libraryID=?", library.libraryID)), 1)
assert.equal(((await Zotero.DB.valueQueryAsync("SELECT editable FROM libraries WHERE libraryID=?", library.libraryID))), 1)
library.editable = false;
yield library.saveTx();
await library.saveTx();
assert.isFalse(library.editable);
assert.isFalse(Zotero.Libraries.isEditable(library.libraryID), "sets editable in cache to false");
assert.equal((yield Zotero.DB.valueQueryAsync("SELECT editable FROM libraries WHERE libraryID=?", library.libraryID)), 0)
assert.equal(((await Zotero.DB.valueQueryAsync("SELECT editable FROM libraries WHERE libraryID=?", library.libraryID))), 0)
});
it("should also set filesEditable to false", function* () {
let library = yield createGroup({ editable: true, filesEditable: true });
it("should also set filesEditable to false", async function () {
let library = await createGroup({ editable: true, filesEditable: true });
assert.isTrue(library.filesEditable);
library.editable = false;
yield library.saveTx();
await library.saveTx();
assert.isFalse(library.filesEditable);
assert.equal((yield Zotero.DB.valueQueryAsync("SELECT filesEditable FROM libraries WHERE libraryID=?", library.libraryID)), 0)
assert.equal(((await Zotero.DB.valueQueryAsync("SELECT filesEditable FROM libraries WHERE libraryID=?", library.libraryID))), 0)
});
it("should not be settable for user libraries", function* () {
it("should not be settable for user libraries", async function () {
let library = Zotero.Libraries.get(Zotero.Libraries.userLibraryID);
assert.throws(function() {library.editable = false}, /^Cannot change _libraryEditable for user library$/, "does not allow setting user library as not editable");
assert.throws(function () {library.editable = false}, /^Cannot change _libraryEditable for user library$/, "does not allow setting user library as not editable");
});
});
describe("#filesEditable", function() {
it("should always return true for user library", function() {
describe("#filesEditable", function () {
it("should always return true for user library", function () {
assert.isTrue(Zotero.Libraries.userLibrary.filesEditable);
});
it("should return files editable status", function() {
it("should return files editable status", function () {
let library = Zotero.Libraries.get(Zotero.Libraries.userLibraryID);
assert.isTrue(library.filesEditable, 'user library is files editable');
});
it("should allow setting files editable status", function* () {
let library = yield createGroup({ filesEditable: true });
it("should allow setting files editable status", async function () {
let library = await createGroup({ filesEditable: true });
assert.isTrue(library.filesEditable);
assert.isTrue(Zotero.Libraries.isFilesEditable(library.libraryID), "sets files editable in cache to true");
library.filesEditable = false;
yield library.saveTx();
await library.saveTx();
assert.isFalse(library.filesEditable);
assert.isFalse(Zotero.Libraries.isFilesEditable(library.libraryID), "sets files editable in cache to false");
});
it("should not be settable for user libraries", function* () {
it("should not be settable for user libraries", async function () {
let library = Zotero.Libraries.get(Zotero.Libraries.userLibraryID);
assert.throws(function() {library.filesEditable = false}, /^Cannot change _libraryFilesEditable for user library$/, "does not allow setting user library as not files editable");
assert.throws(function () {library.filesEditable = false}, /^Cannot change _libraryFilesEditable for user library$/, "does not allow setting user library as not files editable");
});
});
@ -137,38 +137,38 @@ describe("Zotero.Library", function() {
});
});
describe("#archived", function() {
it("should return archived status", function() {
describe("#archived", function () {
it("should return archived status", function () {
let library = Zotero.Libraries.get(Zotero.Libraries.userLibraryID);
assert.isFalse(library.archived, 'user library is not archived');
});
it("should allow setting archived status", function* () {
let library = yield createGroup({ editable: false, archived: true });
it("should allow setting archived status", async function () {
let library = await createGroup({ editable: false, archived: true });
assert.isTrue(library.archived);
assert.equal((yield Zotero.DB.valueQueryAsync("SELECT archived FROM libraries WHERE libraryID=?", library.libraryID)), 1)
assert.equal(((await Zotero.DB.valueQueryAsync("SELECT archived FROM libraries WHERE libraryID=?", library.libraryID))), 1)
library.archived = false;
yield library.saveTx();
await library.saveTx();
assert.isFalse(library.archived);
assert.equal((yield Zotero.DB.valueQueryAsync("SELECT archived FROM libraries WHERE libraryID=?", library.libraryID)), 0)
assert.equal(((await Zotero.DB.valueQueryAsync("SELECT archived FROM libraries WHERE libraryID=?", library.libraryID))), 0)
});
it("should not be settable for user libraries", function* () {
it("should not be settable for user libraries", async function () {
let library = Zotero.Libraries.get(Zotero.Libraries.userLibraryID);
assert.throws(() => library.archived = true, /^Cannot change _libraryArchived for user library$/, "does not allow setting user library as archived");
});
it("should only be settable on read-only library", function* () {
let library = yield createGroup();
it("should only be settable on read-only library", async function () {
let library = await createGroup();
assert.throws(() => library.archived = true, /^Cannot set editable library as archived$/);
});
});
describe("#save()", function() {
it("should require mandatory parameters to be set", function* () {
describe("#save()", function () {
it("should require mandatory parameters to be set", async function () {
let library = new Zotero.Library({ editable: true, filesEditable: true });
yield assert.isRejected(library.saveTx(), /^libraryType must be set before saving/, 'libraryType is mandatory');
await assert.isRejected(library.saveTx(), /^libraryType must be set before saving/, 'libraryType is mandatory');
// Required group params
let groupID = Zotero.Utilities.rand(1000, 10000);
@ -176,90 +176,90 @@ describe("Zotero.Library", function() {
let description = '';
let version = Zotero.Utilities.rand(1000, 10000);
library = new Zotero.Group({ filesEditable: true, groupID, name , description, version });
yield assert.isRejected(library.saveTx(), /^editable must be set before saving/, 'editable is mandatory');
await assert.isRejected(library.saveTx(), /^editable must be set before saving/, 'editable is mandatory');
library = new Zotero.Group({ editable: true, groupID, name , description, version });
yield assert.isRejected(library.saveTx(), /^filesEditable must be set before saving/, 'filesEditable is mandatory');
await assert.isRejected(library.saveTx(), /^filesEditable must be set before saving/, 'filesEditable is mandatory');
library = new Zotero.Group({ editable: true, filesEditable: true, groupID, name , description, version });
yield assert.isFulfilled(library.saveTx());
await assert.isFulfilled(library.saveTx());
});
it("should save new library to DB", function* () {
let library = yield createGroup({});
it("should save new library to DB", async function () {
let library = await createGroup({});
assert.isAbove(library.libraryID, 0, "sets a libraryID");
assert.isTrue(Zotero.Libraries.exists(library.libraryID));
assert.equal(library.libraryType, 'group');
let inDB = yield Zotero.DB.valueQueryAsync('SELECT COUNT(*) FROM libraries WHERE libraryID=?', library.libraryID);
let inDB = await Zotero.DB.valueQueryAsync('SELECT COUNT(*) FROM libraries WHERE libraryID=?', library.libraryID);
assert.ok(inDB, 'added to DB');
});
it("should save library changes to DB", function* () {
let library = yield createGroup({ editable: true });
it("should save library changes to DB", async function () {
let library = await createGroup({ editable: true });
library.editable = false;
yield library.saveTx();
await library.saveTx();
assert.isFalse(Zotero.Libraries.isEditable(library.libraryID));
});
it("should initialize library after creation", function* () {
let library = yield createGroup({});
it("should initialize library after creation", async function () {
let library = await createGroup({});
Zotero.SyncedSettings.get(library.libraryID, "tagColors");
});
});
describe("#erase()", function() {
it("should erase a group library", function* () {
let library = yield createGroup();
describe("#erase()", function () {
it("should erase a group library", async function () {
let library = await createGroup();
let libraryID = library.libraryID;
yield library.eraseTx();
await library.eraseTx();
assert.isFalse(Zotero.Libraries.exists(libraryID), "library no longer exists in cache");assert.isFalse(Zotero.Libraries.exists(libraryID));
let inDB = yield Zotero.DB.valueQueryAsync('SELECT COUNT(*) FROM libraries WHERE libraryID=?', libraryID);
let inDB = await Zotero.DB.valueQueryAsync('SELECT COUNT(*) FROM libraries WHERE libraryID=?', libraryID);
assert.notOk(inDB, 'removed from DB');
});
it("should erase a read-only library", function* () {
let library = yield createGroup({ editable:false, filesEditable:false });
it("should erase a read-only library", async function () {
let library = await createGroup({ editable:false, filesEditable:false });
yield assert.isFulfilled(library.eraseTx());
await assert.isFulfilled(library.eraseTx());
});
it("should not allow erasing permanent libraries", function* () {
it("should not allow erasing permanent libraries", async function () {
let library = Zotero.Libraries.get(Zotero.Libraries.userLibraryID);
yield assert.isRejected(library.eraseTx(), /^Cannot erase library of type 'user'$/, "does not allow erasing user library");
await assert.isRejected(library.eraseTx(), /^Cannot erase library of type 'user'$/, "does not allow erasing user library");
});
it("should not allow erasing unsaved libraries", function* () {
it("should not allow erasing unsaved libraries", async function () {
let library = new Zotero.Library();
yield assert.isRejected(library.eraseTx());
await assert.isRejected(library.eraseTx());
});
it("should throw when accessing erased library methods, except for #libraryID and #name", function* () {
let library = yield createGroup();
yield library.eraseTx();
it("should throw when accessing erased library methods, except for #libraryID and #name", async function () {
let library = await createGroup();
await library.eraseTx();
assert.doesNotThrow(() => library.libraryID);
assert.throws(() => library.editable = false, /^Group \(\d+\) has been disabled$/);
});
it("should clear child items from caches and DB", function* () {
let group = yield createGroup();
it("should clear child items from caches and DB", async function () {
let group = await createGroup();
let libraryID = group.libraryID;
let collection = yield createDataObject('collection', { libraryID });
assert.ok(yield Zotero.Collections.getAsync(collection.id));
let collection = await createDataObject('collection', { libraryID });
assert.ok(await Zotero.Collections.getAsync(collection.id));
let item = yield createDataObject('item', { libraryID });
assert.ok(yield Zotero.Items.getAsync(item.id));
let item = await createDataObject('item', { libraryID });
assert.ok(await Zotero.Items.getAsync(item.id));
let search = yield createDataObject('search', { libraryID });
assert.ok(yield Zotero.Searches.getAsync(search.id));
let search = await createDataObject('search', { libraryID });
assert.ok(await Zotero.Searches.getAsync(search.id));
yield group.eraseTx();
await group.eraseTx();
assert.notOk((yield Zotero.Searches.getAsync(search.id)), 'search was unloaded');
assert.notOk((yield Zotero.Collections.getAsync(collection.id)), 'collection was unloaded');
assert.notOk((yield Zotero.Items.getAsync(item.id)), 'item was unloaded');
assert.notOk(((await Zotero.Searches.getAsync(search.id))), 'search was unloaded');
assert.notOk(((await Zotero.Collections.getAsync(collection.id))), 'collection was unloaded');
assert.notOk(((await Zotero.Items.getAsync(item.id))), 'item was unloaded');
});
it("should delete attachment files", async function () {
@ -287,97 +287,97 @@ describe("Zotero.Library", function() {
});
describe("#hasCollections()", function() {
it("should throw if called before saving a library", function() {
describe("#hasCollections()", function () {
it("should throw if called before saving a library", function () {
let library = new Zotero.Library();
assert.throws(() => library.hasCollections());
});
it("should stay up to date as collections are added and removed", function* () {
let library = yield createGroup({ editable: true });
it("should stay up to date as collections are added and removed", async function () {
let library = await createGroup({ editable: true });
let libraryID = library.libraryID;
assert.isFalse(library.hasCollections());
let c1 = yield createDataObject('collection', { libraryID });
let c1 = await createDataObject('collection', { libraryID });
assert.isTrue(library.hasCollections());
let c2 = yield createDataObject('collection', { libraryID });
let c2 = await createDataObject('collection', { libraryID });
assert.isTrue(library.hasCollections());
yield c1.eraseTx();
await c1.eraseTx();
assert.isTrue(library.hasCollections());
yield c2.eraseTx();
await c2.eraseTx();
assert.isFalse(library.hasCollections());
})
});
describe("#hasSearches()", function() {
it("should throw if called before saving a library", function() {
describe("#hasSearches()", function () {
it("should throw if called before saving a library", function () {
let library = new Zotero.Library();
assert.throws(() => library.hasSearches());
});
it("should stay up to date as searches are added and removed", function* () {
let library = yield createGroup({ editable: true });
it("should stay up to date as searches are added and removed", async function () {
let library = await createGroup({ editable: true });
let libraryID = library.libraryID;
assert.isFalse(library.hasSearches());
let s1 = yield createDataObject('search', { libraryID });
let s1 = await createDataObject('search', { libraryID });
assert.isTrue(library.hasSearches());
let s2 = yield createDataObject('search', { libraryID });
let s2 = await createDataObject('search', { libraryID });
assert.isTrue(library.hasSearches());
yield s1.eraseTx();
await s1.eraseTx();
assert.isTrue(library.hasSearches());
yield s2.eraseTx();
await s2.eraseTx();
assert.isFalse(library.hasSearches());
})
});
describe("#hasItems()", function() {
it("should throw if called before saving a library", function* () {
describe("#hasItems()", function () {
it("should throw if called before saving a library", async function () {
let library = new Zotero.Library();
try {
yield library.hasItems();
await library.hasItems();
assert.isFalse(true, "Library#hasItems did not throw an error");
} catch (e) {
assert.ok(e);
}
});
it("should stay up to date as items are added and removed", function* () {
let library = yield createGroup({ editable: true });
it("should stay up to date as items are added and removed", async function () {
let library = await createGroup({ editable: true });
let libraryID = library.libraryID;
var hasItems = yield library.hasItems();
var hasItems = await library.hasItems();
assert.isFalse(hasItems);
let i1 = yield createDataObject('item', { libraryID });
hasItems = yield library.hasItems();
let i1 = await createDataObject('item', { libraryID });
hasItems = await library.hasItems();
assert.isTrue(hasItems);
let i2 = yield createDataObject('item', { libraryID });
hasItems = yield library.hasItems();
let i2 = await createDataObject('item', { libraryID });
hasItems = await library.hasItems();
assert.isTrue(hasItems);
yield i1.eraseTx();
hasItems = yield library.hasItems();
await i1.eraseTx();
hasItems = await library.hasItems();
assert.isTrue(hasItems);
yield i2.eraseTx();
hasItems = yield library.hasItems();
await i2.eraseTx();
hasItems = await library.hasItems();
assert.isFalse(hasItems);
});
});
describe("#updateLastSyncTime()", function() {
it("should set sync time to current time", function* () {
let group = yield createGroup();
describe("#updateLastSyncTime()", function () {
it("should set sync time to current time", async function () {
let group = await createGroup();
assert.isFalse(group.lastSync);
group.updateLastSyncTime();
assert.ok(group.lastSync);
assert.closeTo(Date.now(), group.lastSync.getTime(), 1000);
yield group.saveTx();
await group.saveTx();
let dbTime = yield Zotero.DB.valueQueryAsync('SELECT lastSync FROM libraries WHERE libraryID=?', group.libraryID);
let dbTime = await Zotero.DB.valueQueryAsync('SELECT lastSync FROM libraries WHERE libraryID=?', group.libraryID);
assert.equal(dbTime*1000, group.lastSync.getTime());
})
});

View file

@ -1,12 +1,12 @@
var lookupIdentifier = Zotero.Promise.coroutine(function* (win, identifier) {
var lookupIdentifier = async function (win, identifier) {
var textbox = win.document.getElementById("zotero-lookup-textbox");
textbox.value = identifier;
var promise = waitForItemEvent("add");
yield win.Zotero_Lookup.accept(textbox);
await win.Zotero_Lookup.accept(textbox);
return promise;
});
};
describe("Add Item by Identifier", function() {
describe("Add Item by Identifier", function () {
var win;
before(function* () {
@ -17,7 +17,7 @@ describe("Add Item by Identifier", function() {
win = yield loadZoteroPane();
});
after(function() {
after(function () {
if (win) {
win.close();
}
@ -25,25 +25,25 @@ describe("Add Item by Identifier", function() {
// TODO: mock external services: https://github.com/zotero/zotero/issues/699
it("should add an ISBN-10", function() {
it("should add an ISBN-10", function () {
this.timeout(20000);
return lookupIdentifier(win, "0838985890").then(function(ids) {
return lookupIdentifier(win, "0838985890").then(function (ids) {
var item = Zotero.Items.get(ids[0]);
assert.match(item.getField("title"), /^Zotero: a guide for librarians, researchers/);
});
});
it("should add an ISBN-13", function() {
it("should add an ISBN-13", function () {
this.timeout(20000);
return lookupIdentifier(win, "978-0838985892").then(function(ids) {
return lookupIdentifier(win, "978-0838985892").then(function (ids) {
var item = Zotero.Items.get(ids[0]);
assert.match(item.getField("title"), /^Zotero: a guide for librarians, researchers/);
});
});
it("should add a DOI", function() {
it("should add a DOI", function () {
this.timeout(20000);
return lookupIdentifier(win, "10.4103/0976-500X.85940").then(function(ids) {
return lookupIdentifier(win, "10.4103/0976-500X.85940").then(function (ids) {
var item = Zotero.Items.get(ids[0]);
assert.equal(item.getField("title"), "Zotero: A bibliographic assistant to researcher");
});
@ -54,28 +54,28 @@ describe("Add Item by Identifier", function() {
// e.g., arXiv
it.skip("should not add a PDF if a DOI already retrieves one");
it("should add a PMID", function() {
it("should add a PMID", function () {
this.timeout(10000);
return lookupIdentifier(win, "24297125").then(function(ids) {
return lookupIdentifier(win, "24297125").then(function (ids) {
var item = Zotero.Items.get(ids[0]);
assert.equal(item.getField("title"), "Taking control of your digital library: how modern citation managers do more than just referencing");
});
});
it("should add an item within a collection", function* () {
it("should add an item within a collection", async function () {
this.timeout(20000);
var col = yield createDataObject('collection');
yield select(win, col);
var col = await createDataObject('collection');
await select(win, col);
// Initial translator
var ids = yield lookupIdentifier(win, "10.4103/0976-500X.85940");
var ids = await lookupIdentifier(win, "10.4103/0976-500X.85940");
var item = Zotero.Items.get(ids[0]);
assert.equal(item.getField("title"), "Zotero: A bibliographic assistant to researcher");
assert.isTrue(item.inCollection(col.id));
// Fallback translator
var ids = yield lookupIdentifier(win, "10.5281/zenodo.55073");
var ids = await lookupIdentifier(win, "10.5281/zenodo.55073");
var item = Zotero.Items.get(ids[0]);
assert.equal(item.getField("title"), "Comparison Of Spectral Methods Through The Adjacency Matrix And The Laplacian Of A Graph");
assert.isTrue(item.inCollection(col.id));

View file

@ -20,7 +20,7 @@ describe('Zotero_Import_Mendeley', function () {
};
before(async () => {
Components.utils.import('chrome://zotero/content/import/mendeley/mendeleyImport.js');
Cu.import('chrome://zotero/content/import/mendeley/mendeleyImport.js');
// A real HTTP server is used to deliver a Bitcoin PDF so that annotations can be processed during import.
var { HttpServer } = ChromeUtils.importESModule("chrome://remote/content/server/httpd.sys.mjs");;
@ -51,10 +51,10 @@ describe('Zotero_Import_Mendeley', function () {
status: 200,
headers: {},
json: {
access_token: 'ACCESS_TOKEN', // eslint-disable-line camelcase
token_type: 'bearer', // eslint-disable-line camelcase
expires_in: 3600, // eslint-disable-line camelcase
refresh_token: 'REFRESH_TOKEN', // eslint-disable-line camelcase
access_token: 'ACCESS_TOKEN',
token_type: 'bearer',
expires_in: 3600,
refresh_token: 'REFRESH_TOKEN',
msso: null,
scope: 'all'
}

View file

@ -12,15 +12,15 @@ describe("Note Editor", function () {
win.close();
});
var waitForNoteEditor = Zotero.Promise.coroutine(function* (item) {
var waitForNoteEditor = async function (item) {
var noteEditor = win.document.getElementById('zotero-note-editor');
while (noteEditor.item != item) {
Zotero.debug("Waiting for note editor");
yield Zotero.Promise.delay(50);
await Zotero.Promise.delay(50);
noteEditor = win.document.getElementById('zotero-note-editor');
}
return new Zotero.Promise((resolve, reject) => {
noteEditor.onInit(() => resolve(noteEditor));
});
});
};
});

View file

@ -2,20 +2,16 @@
describe("Zotero.Notifier", function () {
describe("#trigger()", function () {
it("should trigger add events before modify events", function* () {
var deferred = Zotero.Promise.defer();
it("should trigger add events before modify events", async function () {
var events = [];
var observer = {
notify: (action, type, ids) => {
events.push(action);
if (events.length == 2) {
deferred.resolve();
}
}
};
var id = Zotero.Notifier.registerObserver(observer, null, 'test_trigger');
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
var item = new Zotero.Item('book');
item.setField('title', 'A');
await item.save();
@ -25,7 +21,6 @@ describe("Zotero.Notifier", function () {
Zotero.Notifier.queue('unknown', 'item', item.id);
});
assert.isTrue(deferred.promise.isResolved());
assert.lengthOf(events, 3);
assert.equal(events[0], 'add');
assert.equal(events[1], 'modify');
@ -34,25 +29,25 @@ describe("Zotero.Notifier", function () {
Zotero.Notifier.unregisterObserver(id);
});
it("should add events to passed queue", function* () {
var collection = yield createDataObject('collection');
it("should add events to passed queue", async function () {
var collection = await createDataObject('collection');
var deferred = Zotero.Promise.defer();
var didNotify = false;
var observer = {
notify: () => deferred.resolve()
notify: () => didNotify = true
};
var id = Zotero.Notifier.registerObserver(observer, null, 'test_trigger');
var queue = new Zotero.Notifier.Queue;
var item = createUnsavedDataObject('item');
item.setCollections([collection.id]);
yield item.saveTx({
await item.saveTx({
notifierQueue: queue
});
assert.isTrue(deferred.promise.isPending());
assert.isFalse(didNotify);
assert.equal(queue.size, 2);
yield Zotero.Notifier.commit(queue);
assert.isTrue(deferred.promise.isResolved());
await Zotero.Notifier.commit(queue);
assert.isTrue(didNotify);
Zotero.Notifier.unregisterObserver(id);
});

View file

@ -1,8 +1,8 @@
"use strict";
describe("Zotero.OpenURL", function() {
describe("Zotero.OpenURL", function () {
describe("#createContextObject()", function () {
it("should use firstCreator for author", function* () {
it("should use firstCreator for author", async function () {
var item = createUnsavedDataObject('item');
item.setCreators([
{

View file

@ -1,66 +1,66 @@
describe("Advanced Preferences", function () {
describe("Files & Folders", function () {
describe("Linked Attachment Base Directory", function () {
var setBaseDirectory = Zotero.Promise.coroutine(function* (basePath) {
var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xhtml", {
var setBaseDirectory = async function (basePath) {
var win = await loadWindow("chrome://zotero/content/preferences/preferences.xhtml", {
pane: 'zotero-prefpane-advanced'
});
// Wait for tab to load
yield win.Zotero_Preferences.waitForFirstPaneLoad();
await win.Zotero_Preferences.waitForFirstPaneLoad();
var promise = waitForDialog();
yield win.Zotero_Preferences.Attachment_Base_Directory.changePath(basePath);
yield promise;
await win.Zotero_Preferences.Attachment_Base_Directory.changePath(basePath);
await promise;
win.close();
});
};
var clearBaseDirectory = Zotero.Promise.coroutine(function* (basePath) {
var win = yield loadWindow("chrome://zotero/content/preferences/preferences.xhtml", {
var clearBaseDirectory = async function (basePath) {
var win = await loadWindow("chrome://zotero/content/preferences/preferences.xhtml", {
pane: 'zotero-prefpane-advanced',
tabIndex: 1
});
// Wait for tab to load
yield win.Zotero_Preferences.waitForFirstPaneLoad();
await win.Zotero_Preferences.waitForFirstPaneLoad();
var promise = waitForDialog();
yield win.Zotero_Preferences.Attachment_Base_Directory.clearPath();
yield promise;
await win.Zotero_Preferences.Attachment_Base_Directory.clearPath();
await promise;
win.close();
});
};
beforeEach(function () {
Zotero.Prefs.clear('baseAttachmentPath');
Zotero.Prefs.clear('saveRelativeAttachmentPath');
});
it("should set new base directory", function* () {
it("should set new base directory", async function () {
var basePath = getTestDataDirectory().path;
yield setBaseDirectory(basePath);
await setBaseDirectory(basePath);
assert.equal(Zotero.Prefs.get('baseAttachmentPath'), basePath);
assert.isTrue(Zotero.Prefs.get('saveRelativeAttachmentPath'));
})
it("should clear base directory", function* () {
it("should clear base directory", async function () {
var basePath = getTestDataDirectory().path;
yield setBaseDirectory(basePath);
yield clearBaseDirectory();
await setBaseDirectory(basePath);
await clearBaseDirectory();
assert.equal(Zotero.Prefs.get('baseAttachmentPath'), '');
assert.isFalse(Zotero.Prefs.get('saveRelativeAttachmentPath'));
})
it("should change absolute path of linked attachment under new base dir to prefixed path", function* () {
it("should change absolute path of linked attachment under new base dir to prefixed path", async function () {
var file = getTestDataDirectory();
file.append('test.png');
var attachment = yield Zotero.Attachments.linkFromFile({ file });
var attachment = await Zotero.Attachments.linkFromFile({ file });
assert.equal(attachment.attachmentPath, file.path);
var basePath = getTestDataDirectory().path;
yield setBaseDirectory(basePath);
await setBaseDirectory(basePath);
assert.equal(
attachment.attachmentPath,
@ -68,13 +68,13 @@ describe("Advanced Preferences", function () {
);
})
it("should change prefixed path to absolute when changing base directory", function* () {
it("should change prefixed path to absolute when changing base directory", async function () {
var basePath = getTestDataDirectory().path;
yield setBaseDirectory(basePath);
await setBaseDirectory(basePath);
var file = getTestDataDirectory();
file.append('test.png');
var attachment = yield Zotero.Attachments.linkFromFile({ file });
var attachment = await Zotero.Attachments.linkFromFile({ file });
assert.equal(
attachment.attachmentPath,
Zotero.Attachments.BASE_PATH_PLACEHOLDER + 'test.png'
@ -82,24 +82,24 @@ describe("Advanced Preferences", function () {
// Choose a nonexistent directory for the base path
var otherPath = OS.Path.join(OS.Path.dirname(basePath), 'foobar');
yield setBaseDirectory(otherPath);
await setBaseDirectory(otherPath);
assert.equal(attachment.attachmentPath, file.path);
})
it("should change prefixed path to absolute when clearing base directory", function* () {
it("should change prefixed path to absolute when clearing base directory", async function () {
var basePath = getTestDataDirectory().path;
yield setBaseDirectory(basePath);
await setBaseDirectory(basePath);
var file = getTestDataDirectory();
file.append('test.png');
var attachment = yield Zotero.Attachments.linkFromFile({ file });
var attachment = await Zotero.Attachments.linkFromFile({ file });
assert.equal(
attachment.attachmentPath,
Zotero.Attachments.BASE_PATH_PLACEHOLDER + 'test.png'
);
yield clearBaseDirectory();
await clearBaseDirectory();
assert.equal(Zotero.Prefs.get('baseAttachmentPath'), '');
assert.isFalse(Zotero.Prefs.get('saveRelativeAttachmentPath'));

View file

@ -9,7 +9,7 @@ describe("Sync Preferences", function () {
yield win.Zotero_Preferences.waitForFirstPaneLoad();
});
after(function() {
after(function () {
win.close();
});
@ -17,7 +17,7 @@ describe("Sync Preferences", function () {
describe("Data Syncing", function () {
var getAPIKeyFromCredentialsStub, deleteAPIKey, indicatorElem, apiKey, apiResponse;
var setCredentials = Zotero.Promise.coroutine(function* (username, password, isIncorrectPasword) {
var setCredentials = async function (username, password, isIncorrectPasword) {
let usernameElem = doc.getElementById('sync-username-textbox');
let passwordElem = doc.getElementById('sync-password');
usernameElem.value = username;
@ -38,8 +38,8 @@ describe("Sync Preferences", function () {
else {
getAPIKeyFromCredentialsStub.resolves(apiResponse);
}
yield win.Zotero_Preferences.Sync.linkAccount();
});
await win.Zotero_Preferences.Sync.linkAccount();
};
before(function* () {
getAPIKeyFromCredentialsStub = sinon.stub(
@ -55,38 +55,38 @@ describe("Sync Preferences", function () {
Zotero.alert.reset();
});
after(function() {
after(function () {
Zotero.HTTP.mock = null;
Zotero.alert.restore();
getAPIKeyFromCredentialsStub.restore();
deleteAPIKey.restore();
});
it("should set API key and display full controls with correct credentials", function* () {
yield setCredentials("Username", "correctPassword");
it("should set API key and display full controls with correct credentials", async function () {
await setCredentials("Username", "correctPassword");
yield assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(), apiKey);
await assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(), apiKey);
assert.equal(doc.getElementById('sync-unauthorized').getAttribute('hidden'), 'true');
});
it("should display dialog when credentials incorrect", function* () {
yield setCredentials("Username", "incorrectPassword", true);
it("should display dialog when credentials incorrect", async function () {
await setCredentials("Username", "incorrectPassword", true);
assert.isTrue(Zotero.alert.called);
yield assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(), "");
await assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(), "");
assert.equal(doc.getElementById('sync-authorized').getAttribute('hidden'), 'true');
});
it("should delete API key and display auth form when 'Unlink Account' clicked", function* () {
yield setCredentials("Username", "correctPassword");
yield assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(), apiKey);
it("should delete API key and display auth form when 'Unlink Account' clicked", async function () {
await setCredentials("Username", "correctPassword");
await assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(), apiKey);
yield win.Zotero_Preferences.Sync.unlinkAccount(false);
await win.Zotero_Preferences.Sync.unlinkAccount(false);
assert.isTrue(deleteAPIKey.called);
yield assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(), "");
await assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(), "");
assert.equal(doc.getElementById('sync-authorized').getAttribute('hidden'), 'true');
});
@ -110,13 +110,13 @@ describe("Sync Preferences", function () {
assert.notEqual(controller.apiClient.apiKey, apiKey1);
});
it("should not unlink on pressing cancel", function* () {
yield setCredentials("Username", "correctPassword");
it("should not unlink on pressing cancel", async function () {
await setCredentials("Username", "correctPassword");
waitForDialog(null, 'cancel');
yield win.Zotero_Preferences.Sync.unlinkAccount();
yield assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(), apiKey);
await win.Zotero_Preferences.Sync.unlinkAccount();
await assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(), apiKey);
assert.equal(doc.getElementById('sync-unauthorized').getAttribute('hidden'), 'true');
});

View file

@ -41,15 +41,15 @@ Path=Profiles/${profile3}
describe("#getDefaultInProfilesDir()", function () {
it("should parse a profiles.ini file", function* () {
var [dir, multiple] = yield Zotero.Profile.getDefaultInProfilesDir(tmpDir);
it("should parse a profiles.ini file", async function () {
var [dir, multiple] = await Zotero.Profile.getDefaultInProfilesDir(tmpDir);
assert.equal(dir, OS.Path.join(tmpDir, "Profiles", profile1));
});
});
describe("#findOtherProfilesUsingDataDirectory()", function () {
it("should find profile with directory as a custom location", function* () {
it("should find profile with directory as a custom location", async function () {
let dataDir = Zotero.DataDirectory.dir;
let contents1 = `user_pref("extensions.lastAppVersion", "49.0");
user_pref("extensions.shownSelectionUI", true);
@ -75,14 +75,14 @@ user_pref("loop.copy.ticket", 196);
let prefsFile1 = OS.Path.join(tmpDir, "Profiles", profile1, "prefs.js");
let prefsFile2 = OS.Path.join(tmpDir, "Profiles", profile2, "prefs.js");
let prefsFile3 = OS.Path.join(tmpDir, "Profiles", profile3, "prefs.js");
yield Zotero.File.putContentsAsync(prefsFile1, contents1);
yield Zotero.File.putContentsAsync(prefsFile2, contents2);
yield Zotero.File.putContentsAsync(prefsFile3, contents3);
await Zotero.File.putContentsAsync(prefsFile1, contents1);
await Zotero.File.putContentsAsync(prefsFile2, contents2);
await Zotero.File.putContentsAsync(prefsFile3, contents3);
var stub = sinon.stub(Zotero.Profile, "getOtherAppProfilesDir")
.returns(OS.Path.join(tmpDir, "Profiles"));
var dirs = yield Zotero.Profile.findOtherProfilesUsingDataDirectory(dataDir);
var dirs = await Zotero.Profile.findOtherProfilesUsingDataDirectory(dataDir);
stub.restore();
@ -91,7 +91,7 @@ user_pref("loop.copy.ticket", 196);
});
it("should find other-app profile with directory as a legacy default location", function* () {
it("should find other-app profile with directory as a legacy default location", async function () {
let contents1 = `user_pref("extensions.lastAppVersion", "49.0");
user_pref("extensions.shownSelectionUI", true);
user_pref("extensions.ui.locale.hidden", true);
@ -105,14 +105,13 @@ user_pref("loop.copy.ticket", 196);
let prefsFile1 = OS.Path.join(tmpDir, "Profiles", profile1, "prefs.js");
let prefsFile2 = OS.Path.join(tmpDir, "Profiles", profile2, "prefs.js");
yield Zotero.File.putContentsAsync(prefsFile1, contents1);
yield Zotero.File.putContentsAsync(prefsFile2, contents2);
await Zotero.File.putContentsAsync(prefsFile1, contents1);
await Zotero.File.putContentsAsync(prefsFile2, contents2);
var stub = sinon.stub(Zotero.Profile, "getOtherAppProfilesDir")
.returns(OS.Path.join(tmpDir, "Profiles"));
Components.utils.import("resource://zotero/config.js");
var dirs = yield Zotero.Profile.findOtherProfilesUsingDataDirectory(
var dirs = await Zotero.Profile.findOtherProfilesUsingDataDirectory(
OS.Path.join(OS.Path.dirname(prefsFile1), Zotero.DataDirectory.legacyDirName)
);
@ -125,7 +124,7 @@ user_pref("loop.copy.ticket", 196);
describe("#updateProfileDataDirectory()", function () {
it("should add new lines to prefs.js", function* () {
it("should add new lines to prefs.js", async function () {
let prefsFile = OS.Path.join(tmpDir, "Profiles", profile1, "prefs.js");
let oldDir = OS.Path.join(OS.Path.dirname(tmpDir), "Old", "Zotero");
let newDir = OS.Path.join(OS.Path.dirname(tmpDir), "New", "Zotero");
@ -140,20 +139,20 @@ user_pref("extensions.zotero.lastDataDir", "${newDir}");
user_pref("extensions.zotero.useDataDir", true);
`;
yield Zotero.File.putContentsAsync(prefsFile, contents);
yield Zotero.Profile.updateProfileDataDirectory(
await Zotero.File.putContentsAsync(prefsFile, contents);
await Zotero.Profile.updateProfileDataDirectory(
OS.Path.join(tmpDir, "Profiles", profile1),
oldDir,
newDir
);
let newContents = yield Zotero.File.getContentsAsync(prefsFile);
let newContents = await Zotero.File.getContentsAsync(prefsFile);
assert.equal(newContents, contents + addition);
});
it("should replace existing lines in prefs.js", function* () {
it("should replace existing lines in prefs.js", async function () {
let prefsFile = OS.Path.join(tmpDir, "Profiles", profile1, "prefs.js");
let oldDir = OS.Path.join(OS.Path.dirname(tmpDir), "Old", "Zotero");
let newDir = OS.Path.join(OS.Path.dirname(tmpDir), "New", "Zotero");
@ -175,14 +174,14 @@ user_pref("extensions.zotero.lastDataDir", "${newDir}");
user_pref("extensions.zotero.useDataDir", true);
`;
yield Zotero.File.putContentsAsync(prefsFile, contents);
yield Zotero.Profile.updateProfileDataDirectory(
await Zotero.File.putContentsAsync(prefsFile, contents);
await Zotero.Profile.updateProfileDataDirectory(
OS.Path.join(tmpDir, "Profiles", profile1),
oldDir,
newDir
);
let newContents = yield Zotero.File.getContentsAsync(prefsFile);
let newContents = await Zotero.File.getContentsAsync(prefsFile);
assert.equal(newContents, expectedContents);
});

View file

@ -1,4 +1,4 @@
describe("Zotero.QuickCopy", function() {
describe("Zotero.QuickCopy", function () {
var quickCopyPref;
var prefName = "export.quickCopy.setting";
@ -46,12 +46,12 @@ describe("Zotero.QuickCopy", function() {
})
describe("#getContentFromItems()", function () {
it("should generate BibTeX", function* () {
var item = yield createDataObject('item');
it("should generate BibTeX", async function () {
var item = await createDataObject('item');
var content = "";
var worked = false;
yield Zotero.Translators.init();
await Zotero.Translators.init();
var translatorID = '9cb70025-a888-4a29-a210-93ec52da40d4'; // BibTeX
var format = 'export=' + translatorID;
@ -59,7 +59,7 @@ describe("Zotero.QuickCopy", function() {
// Translator code for selected format is loaded automatically, so wait for it
var translator = Zotero.Translators.get(translatorID);
while (!translator.code) {
yield Zotero.Promise.delay(50);
await Zotero.Promise.delay(50);
}
Zotero.QuickCopy.getContentFromItems(

View file

@ -1,4 +1,4 @@
describe("Document Recognition", function() {
describe("Document Recognition", function () {
var win;
async function waitForProgressWindow() {
@ -16,7 +16,7 @@ describe("Document Recognition", function() {
this.timeout(60000);
// Load Zotero pane and install PDF tools
yield Zotero.Promise.all([
yield Promise.all([
loadZoteroPane().then(w => win = w)
]);
});
@ -25,7 +25,7 @@ describe("Document Recognition", function() {
yield selectLibrary(win);
});
afterEach(async function() {
afterEach(async function () {
for(let win of getWindows("chrome://zotero/content/progressQueueDialog.xhtml")) {
win.close();
}
@ -41,7 +41,7 @@ describe("Document Recognition", function() {
Zotero.Prefs.clear('autoRenameFiles.linked');
});
after(function() {
after(function () {
Zotero.Prefs.clear('fulltext.textMaxLength');
if (win) {

View file

@ -115,9 +115,9 @@ describe("Related Box", function () {
});
describe("Add button", function () {
it("should add a related item", function* () {
var item1 = yield createDataObject('item');
var item2 = yield createDataObject('item');
it("should add a related item", async function () {
var item1 = await createDataObject('item');
var item2 = await createDataObject('item');
var relatedbox = doc.getElementById('zotero-editpane-related');
assert.lengthOf(relatedbox.querySelectorAll('.row'), 0);
@ -126,23 +126,23 @@ describe("Related Box", function () {
setTimeout(function () {
relatedbox.querySelector('collapsible-section .add').click();
});
var selectWin = yield waitForWindow('chrome://zotero/content/selectItemsDialog.xhtml');
var selectWin = await waitForWindow('chrome://zotero/content/selectItemsDialog.xhtml');
do {
yield Zotero.Promise.delay(50);
await Zotero.Promise.delay(50);
}
while (!selectWin.loaded);
var selectCollectionsView = selectWin.collectionsView;
var selectItemsView = selectWin.itemsView;
yield selectCollectionsView.waitForLoad();
yield selectItemsView.waitForLoad();
await selectCollectionsView.waitForLoad();
await selectItemsView.waitForLoad();
// Select the other item
yield selectItemsView.selectItem(item1.id);
await selectItemsView.selectItem(item1.id);
selectWin.document.querySelector('dialog').acceptDialog();
// Wait for relations list to populate
do {
yield Zotero.Promise.delay(50);
await Zotero.Promise.delay(50);
}
while (!relatedbox.querySelectorAll('.row').length);
@ -160,20 +160,20 @@ describe("Related Box", function () {
})
describe("Remove button", function () {
it("should remove a related item", function* () {
var item1 = yield createDataObject('item');
var item2 = yield createDataObject('item');
it("should remove a related item", async function () {
var item1 = await createDataObject('item');
var item2 = await createDataObject('item');
item1.addRelatedItem(item2);
yield item1.saveTx();
await item1.saveTx();
item2.addRelatedItem(item1);
yield item2.saveTx();
await item2.saveTx();
var relatedbox = doc.getElementById('zotero-editpane-related');
// Wait for relations list to populate
do {
yield Zotero.Promise.delay(50);
await Zotero.Promise.delay(50);
}
while (!relatedbox.querySelectorAll('.row').length);
@ -181,7 +181,7 @@ describe("Related Box", function () {
// Wait for relations list to clear
do {
yield Zotero.Promise.delay(50);
await Zotero.Promise.delay(50);
}
while (relatedbox.querySelectorAll('.row').length);
})

View file

@ -28,16 +28,16 @@ describe("Zotero.Relations", function () {
yield Zotero.Users.init();
})
it("should update relations using local user key to use userID", function* () {
var item1 = yield createDataObject('item');
it("should update relations using local user key to use userID", async function () {
var item1 = await createDataObject('item');
var item2 = createUnsavedDataObject('item');
item2.addRelatedItem(item1);
yield item2.save();
await item2.save();
var rels = item2.getRelationsByPredicate(Zotero.Relations.relatedItemPredicate);
assert.include(rels[0], "/users/local");
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
await Zotero.Relations.updateUser(null, 1);
})
@ -45,18 +45,18 @@ describe("Zotero.Relations", function () {
assert.include(rels[0], "/users/1");
})
it("should update relations from one userID to another", function* () {
yield Zotero.Users.setCurrentUserID(1);
it("should update relations from one userID to another", async function () {
await Zotero.Users.setCurrentUserID(1);
var item1 = yield createDataObject('item');
var item1 = await createDataObject('item');
var item2 = createUnsavedDataObject('item');
item2.addRelatedItem(item1);
yield item2.save();
await item2.save();
var rels = item2.getRelationsByPredicate(Zotero.Relations.relatedItemPredicate);
assert.include(rels[0], "/users/1");
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
await Zotero.Relations.updateUser(1, 2);
});

View file

@ -1,27 +1,27 @@
describe("Zotero.Schema", function() {
describe("Zotero.Schema", function () {
describe("#initializeSchema()", function () {
it("should set last client version", function* () {
yield resetDB({
it("should set last client version", async function () {
await resetDB({
thisArg: this,
skipBundledFiles: true
});
var sql = "SELECT value FROM settings WHERE setting='client' AND key='lastVersion'";
var lastVersion = yield Zotero.DB.valueQueryAsync(sql);
yield assert.eventually.equal(Zotero.DB.valueQueryAsync(sql), Zotero.version);
var lastVersion = await Zotero.DB.valueQueryAsync(sql);
await assert.eventually.equal(Zotero.DB.valueQueryAsync(sql), Zotero.version);
});
});
describe("#updateSchema()", function () {
it("should set last client version", function* () {
it("should set last client version", async function () {
var sql = "REPLACE INTO settings (setting, key, value) VALUES ('client', 'lastVersion', ?)";
yield Zotero.DB.queryAsync(sql, "5.0old");
await Zotero.DB.queryAsync(sql, "5.0old");
yield Zotero.Schema.updateSchema();
await Zotero.Schema.updateSchema();
var sql = "SELECT value FROM settings WHERE setting='client' AND key='lastVersion'";
var lastVersion = yield Zotero.DB.valueQueryAsync(sql);
yield assert.eventually.equal(Zotero.DB.valueQueryAsync(sql), Zotero.version);
var lastVersion = await Zotero.DB.valueQueryAsync(sql);
await assert.eventually.equal(Zotero.DB.valueQueryAsync(sql), Zotero.version);
});
});
@ -40,7 +40,7 @@ describe("Zotero.Schema", function() {
schema = JSON.parse(schemaJSON);
});
after(async function() {
after(async function () {
await resetDB({
thisArg: this,
skipBundledFiles: true
@ -430,16 +430,16 @@ describe("Zotero.Schema", function() {
assert.isTrue(await Zotero.DB.tableExists('retractedItems'));
});
it("should repair a foreign key violation", function* () {
yield assert.eventually.isTrue(Zotero.Schema.integrityCheck());
it("should repair a foreign key violation", async function () {
await assert.eventually.isTrue(Zotero.Schema.integrityCheck());
yield Zotero.DB.queryAsync("PRAGMA foreign_keys = OFF");
yield Zotero.DB.queryAsync("INSERT INTO itemTags VALUES (1234,1234,0)");
yield Zotero.DB.queryAsync("PRAGMA foreign_keys = ON");
await Zotero.DB.queryAsync("PRAGMA foreign_keys = OFF");
await Zotero.DB.queryAsync("INSERT INTO itemTags VALUES (1234,1234,0)");
await Zotero.DB.queryAsync("PRAGMA foreign_keys = ON");
yield assert.eventually.isFalse(Zotero.Schema.integrityCheck());
yield assert.eventually.isTrue(Zotero.Schema.integrityCheck(true));
yield assert.eventually.isTrue(Zotero.Schema.integrityCheck());
await assert.eventually.isFalse(Zotero.Schema.integrityCheck());
await assert.eventually.isTrue(Zotero.Schema.integrityCheck(true));
await assert.eventually.isTrue(Zotero.Schema.integrityCheck());
})
it("should repair invalid nesting between two collections", async function () {

View file

@ -1,4 +1,4 @@
describe("Zotero.Search", function() {
describe("Zotero.Search", function () {
describe("#name", function () {
it("should fail if empty", async function () {
var s = new Zotero.Search();
@ -7,57 +7,57 @@ describe("Zotero.Search", function() {
});
describe("#addCondition()", function () {
it("should convert old-style 'collection' condition value", function* () {
var col = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [col.id] });
it("should convert old-style 'collection' condition value", async function () {
var col = await createDataObject('collection');
var item = await createDataObject('item', { collections: [col.id] });
var s = new Zotero.Search();
s.libraryID = item.libraryID;
s.name = "Test";
s.addCondition('collection', 'is', '0_' + col.key);
var matches = yield s.search();
var matches = await s.search();
assert.sameMembers(matches, [item.id]);
});
});
// This is for Zotero.Search._loadConditions()
describe("Loading", function () {
it("should convert old-style 'collection' condition value", function* () {
var col = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [col.id] });
it("should convert old-style 'collection' condition value", async function () {
var col = await createDataObject('collection');
var item = await createDataObject('item', { collections: [col.id] });
var s = new Zotero.Search();
s.libraryID = item.libraryID;
s.name = "Test";
s.addCondition('collection', 'is', col.key);
yield s.saveTx();
yield Zotero.DB.queryAsync(
await s.saveTx();
await Zotero.DB.queryAsync(
"UPDATE savedSearchConditions SET value=? WHERE savedSearchID=? AND condition=?",
["0_" + col.key, s.id, 'collection']
);
yield s.reload(['conditions'], true);
var matches = yield s.search();
await s.reload(['conditions'], true);
var matches = await s.search();
assert.sameMembers(matches, [item.id]);
});
});
describe("#save()", function () {
it("should fail without a name", function* () {
it("should fail without a name", async function () {
var s = new Zotero.Search;
s.addCondition('title', 'is', 'test');
var e = yield getPromiseError(s.saveTx());
var e = await getPromiseError(s.saveTx());
assert.ok(e);
assert.equal(e.constructor.name, Error.prototype.constructor.name); // TEMP: Error mismatch
assert.equal(e.message, "Name not provided for saved search");
});
it("should save a new search", function* () {
it("should save a new search", async function () {
// Save search
var s = new Zotero.Search;
s.name = "Test";
s.addCondition('title', 'is', 'test');
var id = yield s.saveTx();
var id = await s.saveTx();
assert.typeOf(id, 'number');
// Check saved search
@ -76,45 +76,45 @@ describe("Zotero.Search", function() {
assert.propertyVal(condition, 'required', false)
});
it("should add a condition to an existing search", function* () {
it("should add a condition to an existing search", async function () {
// Save search
var s = new Zotero.Search;
s.libraryID = Zotero.Libraries.userLibraryID;
s.name = "Test";
s.addCondition('title', 'is', 'test');
var id = yield s.saveTx();
var id = await s.saveTx();
assert.typeOf(id, 'number');
// Add condition
s = yield Zotero.Searches.getAsync(id);
s = await Zotero.Searches.getAsync(id);
s.addCondition('title', 'contains', 'foo');
var saved = yield s.saveTx();
var saved = await s.saveTx();
assert.isTrue(saved);
// Check saved search
s = yield Zotero.Searches.getAsync(id);
s = await Zotero.Searches.getAsync(id);
var conditions = s.getConditions();
assert.lengthOf(Object.keys(conditions), 2);
});
it("should remove a condition from an existing search", function* () {
it("should remove a condition from an existing search", async function () {
// Save search
var s = new Zotero.Search;
s.libraryID = Zotero.Libraries.userLibraryID;
s.name = "Test";
s.addCondition('title', 'is', 'test');
s.addCondition('title', 'contains', 'foo');
var id = yield s.saveTx();
var id = await s.saveTx();
assert.typeOf(id, 'number');
// Remove condition
s = yield Zotero.Searches.getAsync(id);
s = await Zotero.Searches.getAsync(id);
s.removeCondition(0);
var saved = yield s.saveTx();
var saved = await s.saveTx();
assert.isTrue(saved);
// Check saved search
s = yield Zotero.Searches.getAsync(id);
s = await Zotero.Searches.getAsync(id);
var conditions = s.getConditions();
assert.lengthOf(Object.keys(conditions), 1);
assert.property(conditions, "0");
@ -176,49 +176,49 @@ describe("Zotero.Search", function() {
});
describe("collection", function () {
it("should find item in collection", function* () {
var col = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [col.id] });
it("should find item in collection", async function () {
var col = await createDataObject('collection');
var item = await createDataObject('item', { collections: [col.id] });
var s = new Zotero.Search();
s.libraryID = item.libraryID;
s.addCondition('collection', 'is', col.key);
var matches = yield s.search();
var matches = await s.search();
assert.sameMembers(matches, [item.id]);
});
it("should find items not in collection", function* () {
var col = yield createDataObject('collection');
var item = yield createDataObject('item', { collections: [col.id] });
it("should find items not in collection", async function () {
var col = await createDataObject('collection');
var item = await createDataObject('item', { collections: [col.id] });
var s = new Zotero.Search();
s.libraryID = item.libraryID;
s.addCondition('collection', 'isNot', col.key);
var matches = yield s.search();
var matches = await s.search();
assert.notInclude(matches, item.id);
});
it("shouldn't find item in collection with no items", function* () {
var col = yield createDataObject('collection');
var item = yield createDataObject('item');
it("shouldn't find item in collection with no items", async function () {
var col = await createDataObject('collection');
var item = await createDataObject('item');
var s = new Zotero.Search();
s.libraryID = item.libraryID;
s.addCondition('collection', 'is', col.key);
var matches = yield s.search();
var matches = await s.search();
assert.lengthOf(matches, 0);
});
it("should find item in subcollection in recursive mode", function* () {
var col1 = yield createDataObject('collection');
var col2 = yield createDataObject('collection', { parentID: col1.id });
var item = yield createDataObject('item', { collections: [col2.id] });
it("should find item in subcollection in recursive mode", async function () {
var col1 = await createDataObject('collection');
var col2 = await createDataObject('collection', { parentID: col1.id });
var item = await createDataObject('item', { collections: [col2.id] });
var s = new Zotero.Search();
s.libraryID = item.libraryID;
s.addCondition('collection', 'is', col1.key);
s.addCondition('recursive', 'true');
var matches = yield s.search();
var matches = await s.search();
assert.sameMembers(matches, [item.id]);
});
@ -289,25 +289,25 @@ describe("Zotero.Search", function() {
});
describe("fileTypeID", function () {
it("should search by attachment file type", function* () {
it("should search by attachment file type", async function () {
let s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('fileTypeID', 'is', Zotero.FileTypes.getID('webpage'));
let matches = yield s.search();
let matches = await s.search();
assert.sameMembers(matches, [fooItem.id, foobarItem.id]);
});
});
describe("fulltextContent", function () {
it("should find text in HTML files", function* () {
it("should find text in HTML files", async function () {
var s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('fulltextContent', 'contains', 'foo bar');
var matches = yield s.search();
var matches = await s.search();
assert.sameMembers(matches, [foobarItem.id]);
});
it("should work in subsearch", function* () {
it("should work in subsearch", async function () {
var s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('fulltextContent', 'contains', 'foo bar');
@ -315,7 +315,7 @@ describe("Zotero.Search", function() {
var s2 = new Zotero.Search();
s2.setScope(s);
s2.addCondition('title', 'contains', 'foobar');
var matches = yield s2.search();
var matches = await s2.search();
assert.sameMembers(matches, [foobarItem.id]);
});
@ -329,54 +329,54 @@ describe("Zotero.Search", function() {
assert.sameMembers(matches, [fooItem.id, foobarItem.id]);
});
it("should find matching items with joinMode=ANY and non-matching other condition", function* () {
it("should find matching items with joinMode=ANY and non-matching other condition", async function () {
var s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('joinMode', 'any');
s.addCondition('fulltextContent', 'contains', 'foo');
s.addCondition('fulltextContent', 'contains', 'bar');
s.addCondition('title', 'contains', 'nomatch');
var matches = yield s.search();
var matches = await s.search();
assert.sameMembers(matches, [fooItem.id, foobarItem.id]);
});
it("should find matching items in regexp mode with joinMode=ANY with matching other condition", function* () {
it("should find matching items in regexp mode with joinMode=ANY with matching other condition", async function () {
var s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('joinMode', 'any');
s.addCondition('fulltextContent/regexp', 'contains', 'foo.+bar');
s.addCondition('title', 'is', fooItem.getField('title'));
var matches = yield s.search();
var matches = await s.search();
assert.sameMembers(matches, [fooItem.id, foobarItem.id]);
});
it("should find matching item in regexp mode with joinMode=ANY and non-matching other condition", function* () {
it("should find matching item in regexp mode with joinMode=ANY and non-matching other condition", async function () {
var s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('joinMode', 'any');
s.addCondition('fulltextContent/regexp', 'contains', 'foo.+bar');
s.addCondition('title', 'contains', 'nomatch');
var matches = yield s.search();
var matches = await s.search();
assert.sameMembers(matches, [foobarItem.id]);
});
it("should find item matching other condition in regexp mode when joinMode=ANY", function* () {
it("should find item matching other condition in regexp mode when joinMode=ANY", async function () {
var s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('joinMode', 'any');
s.addCondition('fulltextContent/regexp', 'contains', 'nomatch');
s.addCondition('title', 'is', foobarItem.getField('title'));
var matches = yield s.search();
var matches = await s.search();
assert.sameMembers(matches, [foobarItem.id]);
});
it("should find matching item in regexp mode with joinMode=ANY and recursive mode flag", function* () {
it("should find matching item in regexp mode with joinMode=ANY and recursive mode flag", async function () {
var s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('joinMode', 'any');
s.addCondition('fulltextContent/regexp', 'contains', 'foo.+bar');
s.addCondition('recursive', 'true');
var matches = yield s.search();
var matches = await s.search();
assert.sameMembers(matches, [foobarItem.id]);
});
@ -442,50 +442,50 @@ describe("Zotero.Search", function() {
});
describe("fulltextWord", function () {
it("should return matches with full-text conditions", function* () {
it("should return matches with full-text conditions", async function () {
let s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('fulltextWord', 'contains', 'foo');
let matches = yield s.search();
let matches = await s.search();
assert.lengthOf(matches, 2);
assert.sameMembers(matches, [fooItem.id, foobarItem.id]);
});
it("should not return non-matches with full-text conditions", function* () {
it("should not return non-matches with full-text conditions", async function () {
let s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('fulltextWord', 'contains', 'nomatch');
let matches = yield s.search();
let matches = await s.search();
assert.lengthOf(matches, 0);
});
it("should return matches for full-text conditions in ALL mode", function* () {
it("should return matches for full-text conditions in ALL mode", async function () {
let s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('joinMode', 'all');
s.addCondition('fulltextWord', 'contains', 'foo');
s.addCondition('fulltextWord', 'contains', 'bar');
let matches = yield s.search();
let matches = await s.search();
assert.deepEqual(matches, [foobarItem.id]);
});
it("should not return non-matches for full-text conditions in ALL mode", function* () {
it("should not return non-matches for full-text conditions in ALL mode", async function () {
let s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('joinMode', 'all');
s.addCondition('fulltextWord', 'contains', 'mjktkiuewf');
s.addCondition('fulltextWord', 'contains', 'zijajkvudk');
let matches = yield s.search();
let matches = await s.search();
assert.lengthOf(matches, 0);
});
it("should return a match that satisfies only one of two full-text condition in ANY mode", function* () {
it("should return a match that satisfies only one of two full-text condition in ANY mode", async function () {
let s = new Zotero.Search();
s.libraryID = userLibraryID;
s.addCondition('joinMode', 'any');
s.addCondition('fulltextWord', 'contains', 'bar');
s.addCondition('fulltextWord', 'contains', 'nomatch');
let matches = yield s.search();
let matches = await s.search();
assert.deepEqual(matches, [foobarItem.id]);
});
});
@ -516,13 +516,13 @@ describe("Zotero.Search", function() {
});
describe("key", function () {
it("should allow more than max bound parameters", function* () {
it("should allow more than max bound parameters", async function () {
let s = new Zotero.Search();
let max = Zotero.DB.MAX_BOUND_PARAMETERS + 100;
for (let i = 0; i < max; i++) {
s.addCondition('key', 'is', Zotero.DataObjectUtilities.generateKey());
}
yield s.search();
await s.search();
});
});
@ -576,27 +576,27 @@ describe("Zotero.Search", function() {
});
describe("savedSearch", function () {
it("should return items in the saved search", function* () {
var search = yield createDataObject('search');
it("should return items in the saved search", async function () {
var search = await createDataObject('search');
var itemTitle = search.getConditions()[0].value;
var item = yield createDataObject('item', { title: itemTitle })
var item = await createDataObject('item', { title: itemTitle })
var s = new Zotero.Search;
s.libraryID = Zotero.Libraries.userLibraryID;
s.addCondition('savedSearch', 'is', search.key);
var matches = yield s.search();
var matches = await s.search();
assert.deepEqual(matches, [item.id]);
});
it("should return items not in the saved search for isNot operator", function* () {
var search = yield createDataObject('search');
it("should return items not in the saved search for isNot operator", async function () {
var search = await createDataObject('search');
var itemTitle = search.getConditions()[0].value;
var item = yield createDataObject('item', { title: itemTitle })
var item = await createDataObject('item', { title: itemTitle })
var s = new Zotero.Search;
s.libraryID = Zotero.Libraries.userLibraryID;
s.addCondition('savedSearch', 'isNot', search.key);
var matches = yield s.search();
var matches = await s.search();
assert.notInclude(matches, item.id);
});
@ -613,14 +613,14 @@ describe("Zotero.Search", function() {
});
describe("unfiled", function () {
it("shouldn't include items in My Publications", function* () {
var item1 = yield createDataObject('item');
var item2 = yield createDataObject('item', { inPublications: true });
it("shouldn't include items in My Publications", async function () {
var item1 = await createDataObject('item');
var item2 = await createDataObject('item', { inPublications: true });
var s = new Zotero.Search;
s.libraryID = Zotero.Libraries.userLibraryID;
s.addCondition('unfiled', 'true');
var matches = yield s.search();
var matches = await s.search();
assert.include(matches, item1.id);
assert.notInclude(matches, item2.id);
});
@ -754,7 +754,7 @@ describe("Zotero.Search", function() {
});
describe("#toJSON()", function () {
it("should output all data", function* () {
it("should output all data", async function () {
let s = new Zotero.Search();
s.name = "Test";
s.addCondition('joinMode', 'any');
@ -780,7 +780,7 @@ describe("Zotero.Search", function() {
});
describe("#fromJSON()", function () {
it("should update all data", function* () {
it("should update all data", async function () {
let s = new Zotero.Search();
s.name = "Test";
s.addCondition('joinMode', 'any');

View file

@ -1,6 +1,6 @@
"use strict";
Components.utils.import("resource://gre/modules/NetUtil.jsm");
ChromeUtils.importESModule("resource://gre/modules/NetUtil.sys.mjs");
describe("Zotero.Server", function () {
var serverPath;
@ -9,10 +9,10 @@ describe("Zotero.Server", function () {
serverPath = 'http://127.0.0.1:' + Zotero.Server.port;
});
describe('DataListener', function() {
describe('DataListener', function () {
describe("_processEndpoint()", function () {
describe("1 argument", function () {
it("integer return", function* () {
it("integer return", async function () {
var called = false;
var endpoint = "/test/" + Zotero.Utilities.randomString();
@ -30,7 +30,7 @@ describe("Zotero.Server", function () {
};
Zotero.Server.Endpoints[endpoint] = handler;
let req = yield Zotero.HTTP.request(
let req = await Zotero.HTTP.request(
"POST",
serverPath + endpoint,
{
@ -49,7 +49,7 @@ describe("Zotero.Server", function () {
assert.equal(req.status, 204);
});
it("array return", function* () {
it("array return", async function () {
var called = false;
var endpoint = "/test/" + Zotero.Utilities.randomString();
@ -66,7 +66,7 @@ describe("Zotero.Server", function () {
};
Zotero.Server.Endpoints[endpoint] = handler;
let req = yield Zotero.HTTP.request(
let req = await Zotero.HTTP.request(
"GET",
serverPath + endpoint,
{
@ -80,7 +80,7 @@ describe("Zotero.Server", function () {
assert.equal(req.responseText, "Test");
});
it("integer promise return", function* () {
it("integer promise return", async function () {
var called = false;
var endpoint = "/test/" + Zotero.Utilities.randomString();
@ -89,15 +89,15 @@ describe("Zotero.Server", function () {
supportedMethods: ["GET"],
supportedDataTypes: "*",
init: Zotero.Promise.coroutine(function* (options) {
init: async function (options) {
called = true;
assert.isObject(options);
return 204;
})
}
};
Zotero.Server.Endpoints[endpoint] = handler;
let req = yield Zotero.HTTP.request(
let req = await Zotero.HTTP.request(
"GET",
serverPath + endpoint,
{
@ -109,7 +109,7 @@ describe("Zotero.Server", function () {
assert.equal(req.status, 204);
});
it("array promise return", function* () {
it("array promise return", async function () {
var called = false;
var endpoint = "/test/" + Zotero.Utilities.randomString();
@ -118,15 +118,15 @@ describe("Zotero.Server", function () {
supportedMethods: ["GET"],
supportedDataTypes: "*",
init: Zotero.Promise.coroutine(function* (options) {
init: async function (options) {
called = true;
assert.isObject(options);
return [201, "text/plain", "Test"];
})
}
};
Zotero.Server.Endpoints[endpoint] = handler;
let req = yield Zotero.HTTP.request(
let req = await Zotero.HTTP.request(
"GET",
serverPath + endpoint,
{

View file

@ -57,13 +57,13 @@ describe("Connector Server", function () {
});
describe('/connector/getTranslatorCode', function() {
it('should respond with translator code', function* () {
describe('/connector/getTranslatorCode', function () {
it('should respond with translator code', async function () {
var code = 'function detectWeb() {}\nfunction doImport() {}';
var translator = buildDummyTranslator(4, code);
sinon.stub(Zotero.Translators, 'get').returns(translator);
var response = yield httpRequest(
var response = await httpRequest(
'POST',
connectorServerPath + "/connector/getTranslatorCode",
{
@ -77,7 +77,7 @@ describe("Connector Server", function () {
);
assert.isTrue(Zotero.Translators.get.calledWith('dummy-translator'));
let translatorCode = yield Zotero.Translators.getCodeForTranslator(translator);
let translatorCode = await Zotero.Translators.getCodeForTranslator(translator);
assert.equal(response.response, translatorCode);
Zotero.Translators.get.restore();
@ -85,13 +85,13 @@ describe("Connector Server", function () {
});
describe("/connector/detect", function() {
it("should return relevant translators with proxies", function* () {
describe("/connector/detect", function () {
it("should return relevant translators with proxies", async function () {
var code = 'function detectWeb() {return "newspaperArticle";}\nfunction doWeb() {}';
var translator = buildDummyTranslator("web", code, {target: "https://www.example.com/.*"});
sinon.stub(Zotero.Translators, 'getAllForType').resolves([translator]);
var response = yield httpRequest(
var response = await httpRequest(
'POST',
connectorServerPath + "/connector/detect",
{
@ -113,9 +113,9 @@ describe("Connector Server", function () {
describe("/connector/saveItems", function () {
it("should save a translated item to the current selected collection", function* () {
var collection = yield createDataObject('collection');
yield select(win, collection);
it("should save a translated item to the current selected collection", async function () {
var collection = await createDataObject('collection');
await select(win, collection);
var body = {
items: [
@ -148,22 +148,22 @@ describe("Connector Server", function () {
);
// Check parent item
var ids = yield promise;
var ids = await promise;
assert.lengthOf(ids, 1);
var item = Zotero.Items.get(ids[0]);
assert.equal(Zotero.ItemTypes.getName(item.itemTypeID), 'newspaperArticle');
assert.isTrue(collection.hasItem(item.id));
var req = yield reqPromise;
var req = await reqPromise;
assert.equal(req.status, 201);
});
it("should switch to My Library if read-only library is selected", function* () {
var group = yield createGroup({
it("should switch to My Library if read-only library is selected", async function () {
var group = await createGroup({
editable: false
});
yield select(win, group);
await select(win, group);
var body = {
items: [
@ -197,7 +197,7 @@ describe("Connector Server", function () {
);
// My Library be selected, and the item should be in it
var ids = yield promise;
var ids = await promise;
assert.equal(
win.ZoteroPane.collectionsView.getSelectedLibraryID(),
Zotero.Libraries.userLibraryID
@ -207,13 +207,13 @@ describe("Connector Server", function () {
assert.equal(item.libraryID, Zotero.Libraries.userLibraryID);
assert.equal(Zotero.ItemTypes.getName(item.itemTypeID), 'newspaperArticle');
var req = yield reqPromise;
var req = await reqPromise;
assert.equal(req.status, 201);
});
it("should use the provided proxy to deproxify item url", function* () {
yield selectLibrary(win, Zotero.Libraries.userLibraryID);
yield waitForItemsLoad(win);
it("should use the provided proxy to deproxify item url", async function () {
await selectLibrary(win, Zotero.Libraries.userLibraryID);
await waitForItemsLoad(win);
var body = {
items: [
@ -236,7 +236,7 @@ describe("Connector Server", function () {
};
var promise = waitForItemEvent('add');
var req = yield httpRequest(
var req = await httpRequest(
'POST',
connectorServerPath + "/connector/saveItems",
{
@ -248,7 +248,7 @@ describe("Connector Server", function () {
);
// Check item
var ids = yield promise;
var ids = await promise;
assert.lengthOf(ids, 1);
var item = Zotero.Items.get(ids[0]);
assert.equal(item.getField('url'), 'https://www.example.com/path');
@ -418,9 +418,9 @@ describe("Connector Server", function () {
});
describe("/connector/saveSnapshot", function () {
it("should save a webpage item to the current selected collection", function* () {
var collection = yield createDataObject('collection');
yield select(win, collection);
it("should save a webpage item to the current selected collection", async function () {
var collection = await createDataObject('collection');
await select(win, collection);
// saveSnapshot saves parent and child before returning
var ids;
@ -433,7 +433,7 @@ describe("Connector Server", function () {
file.append('index.html');
httpd.registerFile("/test", file);
yield httpRequest(
await httpRequest(
'POST',
connectorServerPath + "/connector/saveSnapshot",
{
@ -457,11 +457,11 @@ describe("Connector Server", function () {
assert.equal(item.getField('title'), 'Title');
});
it("should switch to My Library if a read-only library is selected", function* () {
var group = yield createGroup({
it("should switch to My Library if a read-only library is selected", async function () {
var group = await createGroup({
editable: false
});
yield select(win, group);
await select(win, group);
var promise = waitForItemEvent('add');
var reqPromise = httpRequest(
@ -480,7 +480,7 @@ describe("Connector Server", function () {
);
// My Library be selected, and the item should be in it
var ids = yield promise;
var ids = await promise;
assert.equal(
win.ZoteroPane.collectionsView.getSelectedLibraryID(),
Zotero.Libraries.userLibraryID
@ -489,7 +489,7 @@ describe("Connector Server", function () {
var item = Zotero.Items.get(ids[0]);
assert.equal(item.libraryID, Zotero.Libraries.userLibraryID);
var req = yield reqPromise;
var req = await reqPromise;
assert.equal(req.status, 201);
});
});
@ -1512,11 +1512,11 @@ describe("Connector Server", function () {
});
});
describe('/connector/installStyle', function() {
describe('/connector/installStyle', function () {
var endpoint;
var style;
before(function() {
before(function () {
endpoint = connectorServerPath + "/connector/installStyle";
style = `<?xml version="1.0" encoding="utf-8"?>
<style xmlns="http://purl.org/net/xbiblio/csl" version="1.0" default-locale="de-DE">
@ -1529,8 +1529,8 @@ describe("Connector Server", function () {
`;
});
it('should reject styles with invalid text', function* () {
var error = yield getPromiseError(httpRequest(
it('should reject styles with invalid text', async function () {
var error = await getPromiseError(httpRequest(
'POST',
endpoint,
{
@ -1543,12 +1543,12 @@ describe("Connector Server", function () {
assert.equal(error.xmlhttp.responseText, Zotero.getString("styles.installError", "(null)"));
});
it('should import a style with application/vnd.citationstyles.style+xml content-type', function* () {
sinon.stub(Zotero.Styles, 'install').callsFake(function(style) {
it('should import a style with application/vnd.citationstyles.style+xml content-type', async function () {
sinon.stub(Zotero.Styles, 'install').callsFake(function (style) {
var parser = new DOMParser(),
doc = parser.parseFromString(style, "application/xml");
return Zotero.Promise.resolve({
return Promise.resolve({
styleTitle: Zotero.Utilities.xpathText(
doc, '/csl:style/csl:info[1]/csl:title[1]', Zotero.Styles.ns
),
@ -1558,7 +1558,7 @@ describe("Connector Server", function () {
});
});
var response = yield httpRequest(
var response = await httpRequest(
'POST',
endpoint,
{
@ -1572,11 +1572,11 @@ describe("Connector Server", function () {
});
it('should accept text/plain request with X-Zotero-Connector-API-Version or Zotero-Allowed-Request', async function () {
sinon.stub(Zotero.Styles, 'install').callsFake(function(style) {
sinon.stub(Zotero.Styles, 'install').callsFake(function (style) {
var parser = new DOMParser(),
doc = parser.parseFromString(style, "application/xml");
return Zotero.Promise.resolve({
return Promise.resolve({
styleTitle: Zotero.Utilities.xpathText(
doc, '/csl:style/csl:info[1]/csl:title[1]', Zotero.Styles.ns
),
@ -1633,16 +1633,16 @@ describe("Connector Server", function () {
});
});
describe('/connector/import', function() {
describe('/connector/import', function () {
var endpoint;
before(function() {
before(function () {
endpoint = connectorServerPath + "/connector/import";
});
it('should reject resources that do not contain import data', function* () {
it('should reject resources that do not contain import data', async function () {
const sessionID = Zotero.Utilities.randomString();
var error = yield getPromiseError(httpRequest(
var error = await getPromiseError(httpRequest(
'POST',
endpoint + `?session=${sessionID}`,
{

View file

@ -2,82 +2,82 @@
describe("Zotero.Sync.Storage.Local", function () {
describe("#checkForUpdatedFiles()", function () {
it("should flag modified file for upload and return it", function* () {
it("should flag modified file for upload and return it", async function () {
// Create attachment
let item = yield importTextAttachment();
var hash = yield item.attachmentHash;
let item = await importTextAttachment();
var hash = await item.attachmentHash;
// Set file mtime to the past (without milliseconds, which aren't used on OS X)
var mtime = (Math.floor(new Date().getTime() / 1000) * 1000) - 1000;
yield OS.File.setDates((yield item.getFilePathAsync()), null, mtime);
await OS.File.setDates(((await item.getFilePathAsync())), null, mtime);
// Mark as synced, so it will be checked
item.attachmentSyncedModificationTime = mtime;
item.attachmentSyncedHash = hash;
item.attachmentSyncState = "in_sync";
yield item.saveTx({ skipAll: true });
await item.saveTx({ skipAll: true });
// Update mtime and contents
var path = yield item.getFilePathAsync();
yield OS.File.setDates(path);
yield Zotero.File.putContentsAsync(path, Zotero.Utilities.randomString());
var path = await item.getFilePathAsync();
await OS.File.setDates(path);
await Zotero.File.putContentsAsync(path, Zotero.Utilities.randomString());
// File should be returned
var libraryID = Zotero.Libraries.userLibraryID;
var changed = yield Zotero.Sync.Storage.Local.checkForUpdatedFiles(libraryID, [item.id]);
var changed = await Zotero.Sync.Storage.Local.checkForUpdatedFiles(libraryID, [item.id]);
yield item.eraseTx();
await item.eraseTx();
assert.equal(changed, true);
assert.equal(item.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_TO_UPLOAD);
});
it("should skip a file if mod time hasn't changed", function* () {
it("should skip a file if mod time hasn't changed", async function () {
// Create attachment
let item = yield importTextAttachment();
var hash = yield item.attachmentHash;
var mtime = yield item.attachmentModificationTime;
let item = await importTextAttachment();
var hash = await item.attachmentHash;
var mtime = await item.attachmentModificationTime;
// Mark as synced, so it will be checked
item.attachmentSyncedModificationTime = mtime;
item.attachmentSyncedHash = hash;
item.attachmentSyncState = "in_sync";
yield item.saveTx({ skipAll: true });
await item.saveTx({ skipAll: true });
var libraryID = Zotero.Libraries.userLibraryID;
var changed = yield Zotero.Sync.Storage.Local.checkForUpdatedFiles(libraryID, [item.id]);
var changed = await Zotero.Sync.Storage.Local.checkForUpdatedFiles(libraryID, [item.id]);
var syncState = item.attachmentSyncState;
yield item.eraseTx();
await item.eraseTx();
assert.isFalse(changed);
assert.equal(syncState, Zotero.Sync.Storage.Local.SYNC_STATE_IN_SYNC);
})
it("should skip a file if mod time has changed but contents haven't", function* () {
it("should skip a file if mod time has changed but contents haven't", async function () {
// Create attachment
let item = yield importTextAttachment();
var hash = yield item.attachmentHash;
let item = await importTextAttachment();
var hash = await item.attachmentHash;
// Set file mtime to the past (without milliseconds, which aren't used on OS X)
var mtime = (Math.floor(new Date().getTime() / 1000) * 1000) - 1000;
yield OS.File.setDates((yield item.getFilePathAsync()), null, mtime);
await OS.File.setDates(((await item.getFilePathAsync())), null, mtime);
// Mark as synced, so it will be checked
item.attachmentSyncedModificationTime = mtime;
item.attachmentSyncedHash = hash;
item.attachmentSyncState = "in_sync";
yield item.saveTx({ skipAll: true });
await item.saveTx({ skipAll: true });
// Update mtime, but not contents
var path = yield item.getFilePathAsync();
yield OS.File.setDates(path);
var path = await item.getFilePathAsync();
await OS.File.setDates(path);
var libraryID = Zotero.Libraries.userLibraryID;
var changed = yield Zotero.Sync.Storage.Local.checkForUpdatedFiles(libraryID, [item.id]);
var changed = await Zotero.Sync.Storage.Local.checkForUpdatedFiles(libraryID, [item.id]);
var syncState = item.attachmentSyncState;
var syncedModTime = item.attachmentSyncedModificationTime;
var newModTime = yield item.attachmentModificationTime;
var newModTime = await item.attachmentModificationTime;
yield item.eraseTx();
await item.eraseTx();
assert.isFalse(changed);
assert.equal(syncState, Zotero.Sync.Storage.Local.SYNC_STATE_IN_SYNC);
@ -111,20 +111,20 @@ describe("Zotero.Sync.Storage.Local", function () {
})
describe("#updateSyncStates()", function () {
it("should update attachment sync states to 'to_upload'", function* () {
var attachment1 = yield importFileAttachment('test.png');
it("should update attachment sync states to 'to_upload'", async function () {
var attachment1 = await importFileAttachment('test.png');
attachment1.attachmentSyncState = 'in_sync';
yield attachment1.saveTx();
var attachment2 = yield importFileAttachment('test.png');
await attachment1.saveTx();
var attachment2 = await importFileAttachment('test.png');
attachment2.attachmentSyncState = 'in_sync';
yield attachment2.saveTx();
await attachment2.saveTx();
var local = Zotero.Sync.Storage.Local;
yield local.updateSyncStates([attachment1, attachment2], 'to_upload');
await local.updateSyncStates([attachment1, attachment2], 'to_upload');
for (let attachment of [attachment1, attachment2]) {
assert.strictEqual(attachment.attachmentSyncState, local.SYNC_STATE_TO_UPLOAD);
let state = yield Zotero.DB.valueQueryAsync(
let state = await Zotero.DB.valueQueryAsync(
"SELECT syncState FROM itemAttachments WHERE itemID=?", attachment.id
);
assert.strictEqual(state, local.SYNC_STATE_TO_UPLOAD);
@ -133,15 +133,15 @@ describe("Zotero.Sync.Storage.Local", function () {
});
describe("#resetAllSyncStates()", function () {
it("should reset attachment sync states to 'to_upload'", function* () {
var attachment = yield importFileAttachment('test.png');
it("should reset attachment sync states to 'to_upload'", async function () {
var attachment = await importFileAttachment('test.png');
attachment.attachmentSyncState = 'in_sync';
yield attachment.saveTx();
await attachment.saveTx();
var local = Zotero.Sync.Storage.Local;
yield local.resetAllSyncStates(attachment.libraryID)
await local.resetAllSyncStates(attachment.libraryID)
assert.strictEqual(attachment.attachmentSyncState, local.SYNC_STATE_TO_UPLOAD);
var state = yield Zotero.DB.valueQueryAsync(
var state = await Zotero.DB.valueQueryAsync(
"SELECT syncState FROM itemAttachments WHERE itemID=?", attachment.id
);
assert.strictEqual(state, local.SYNC_STATE_TO_UPLOAD);
@ -150,26 +150,26 @@ describe("Zotero.Sync.Storage.Local", function () {
describe("#processDownload()", function () {
describe("single file", function () {
it("should download a single file into the attachment directory", function* () {
it("should download a single file into the attachment directory", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var parentItem = yield createDataObject('item');
var parentItem = await createDataObject('item');
var key = Zotero.DataObjectUtilities.generateKey();
var fileContents = Zotero.Utilities.randomString();
var oldFilename = "Old File";
var tmpDir = Zotero.getTempDirectory().path;
var tmpFile = OS.Path.join(tmpDir, key + '.tmp');
yield Zotero.File.putContentsAsync(tmpFile, fileContents);
await Zotero.File.putContentsAsync(tmpFile, fileContents);
// Create an existing attachment directory to replace
var dir = Zotero.Attachments.getStorageDirectoryByLibraryAndKey(libraryID, key).path;
yield OS.File.makeDir(
await OS.File.makeDir(
dir,
{
unixMode: 0o755
}
);
yield Zotero.File.putContentsAsync(OS.Path.join(dir, oldFilename), '');
await Zotero.File.putContentsAsync(OS.Path.join(dir, oldFilename), '');
var md5 = Zotero.Utilities.Internal.md5(Zotero.File.pathToFile(tmpFile));
var mtime = 1445667239000;
@ -186,32 +186,32 @@ describe("Zotero.Sync.Storage.Local", function () {
md5,
mtime
};
yield Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
await Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
var item = yield Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
yield Zotero.Sync.Storage.Local.processDownload({
var item = await Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
await Zotero.Sync.Storage.Local.processDownload({
item,
md5,
mtime
});
yield OS.File.remove(tmpFile);
await OS.File.remove(tmpFile);
var storageDir = Zotero.Attachments.getStorageDirectory(item).path;
// Make sure previous files don't exist
assert.isFalse(yield OS.File.exists(OS.Path.join(storageDir, oldFilename)));
assert.isFalse(await OS.File.exists(OS.Path.join(storageDir, oldFilename)));
// Make sure main file matches attachment hash and mtime
yield assert.eventually.equal(
await assert.eventually.equal(
item.attachmentHash, Zotero.Utilities.Internal.md5(fileContents)
);
yield assert.eventually.equal(item.attachmentModificationTime, mtime);
await assert.eventually.equal(item.attachmentModificationTime, mtime);
});
it("should download and rename a single file with invalid filename into the attachment directory", function* () {
it("should download and rename a single file with invalid filename into the attachment directory", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var parentItem = yield createDataObject('item');
var parentItem = await createDataObject('item');
var key = Zotero.DataObjectUtilities.generateKey();
var fileContents = Zotero.Utilities.randomString();
@ -220,17 +220,17 @@ describe("Zotero.Sync.Storage.Local", function () {
var filteredFilename = " ab — c .txt.";
var tmpDir = Zotero.getTempDirectory().path;
var tmpFile = OS.Path.join(tmpDir, key + '.tmp');
yield Zotero.File.putContentsAsync(tmpFile, fileContents);
await Zotero.File.putContentsAsync(tmpFile, fileContents);
// Create an existing attachment directory to replace
var dir = Zotero.Attachments.getStorageDirectoryByLibraryAndKey(libraryID, key).path;
yield OS.File.makeDir(
await OS.File.makeDir(
dir,
{
unixMode: 0o755
}
);
yield Zotero.File.putContentsAsync(OS.Path.join(dir, oldFilename), '');
await Zotero.File.putContentsAsync(OS.Path.join(dir, oldFilename), '');
var md5 = Zotero.Utilities.Internal.md5(Zotero.File.pathToFile(tmpFile));
var mtime = 1445667239000;
@ -247,34 +247,34 @@ describe("Zotero.Sync.Storage.Local", function () {
md5,
mtime
};
yield Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
await Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
var item = yield Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
yield Zotero.Sync.Storage.Local.processDownload({
var item = await Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
await Zotero.Sync.Storage.Local.processDownload({
item,
md5,
mtime
});
yield OS.File.remove(tmpFile);
await OS.File.remove(tmpFile);
var storageDir = Zotero.Attachments.getStorageDirectory(item).path;
// Make sure previous file doesn't exist
assert.isFalse(yield OS.File.exists(OS.Path.join(storageDir, oldFilename)));
assert.isFalse(await OS.File.exists(OS.Path.join(storageDir, oldFilename)));
// And new one does
assert.isTrue(yield OS.File.exists(OS.Path.join(storageDir, filteredFilename)));
assert.isTrue(await OS.File.exists(OS.Path.join(storageDir, filteredFilename)));
// Make sure main file matches attachment hash and mtime
yield assert.eventually.equal(
await assert.eventually.equal(
item.attachmentHash, Zotero.Utilities.Internal.md5(fileContents)
);
yield assert.eventually.equal(item.attachmentModificationTime, mtime);
await assert.eventually.equal(item.attachmentModificationTime, mtime);
});
it("should download and rename a single file with invalid filename using Windows parsing rules into the attachment directory", function* () {
it("should download and rename a single file with invalid filename using Windows parsing rules into the attachment directory", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var parentItem = yield createDataObject('item');
var parentItem = await createDataObject('item');
var key = Zotero.DataObjectUtilities.generateKey();
var fileContents = Zotero.Utilities.randomString();
@ -283,17 +283,17 @@ describe("Zotero.Sync.Storage.Local", function () {
var filteredFilename = "ab.txt";
var tmpDir = Zotero.getTempDirectory().path;
var tmpFile = OS.Path.join(tmpDir, key + '.tmp');
yield Zotero.File.putContentsAsync(tmpFile, fileContents);
await Zotero.File.putContentsAsync(tmpFile, fileContents);
// Create an existing attachment directory to replace
var dir = Zotero.Attachments.getStorageDirectoryByLibraryAndKey(libraryID, key).path;
yield OS.File.makeDir(
await OS.File.makeDir(
dir,
{
unixMode: 0o755
}
);
yield Zotero.File.putContentsAsync(OS.Path.join(dir, oldFilename), '');
await Zotero.File.putContentsAsync(OS.Path.join(dir, oldFilename), '');
var md5 = Zotero.Utilities.Internal.md5(Zotero.File.pathToFile(tmpFile));
var mtime = 1445667239000;
@ -310,9 +310,9 @@ describe("Zotero.Sync.Storage.Local", function () {
md5,
mtime
};
yield Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
await Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
var item = yield Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
var item = await Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
// Stub functions to simulate OS.Path.basename() behavior on Windows
var basenameOrigFunc = OS.Path.basename.bind(OS.Path);
@ -331,12 +331,12 @@ describe("Zotero.Sync.Storage.Local", function () {
return pathToFileOrigFunc(path);
});
yield Zotero.Sync.Storage.Local.processDownload({
await Zotero.Sync.Storage.Local.processDownload({
item,
md5,
mtime
});
yield OS.File.remove(tmpFile);
await OS.File.remove(tmpFile);
var storageDir = Zotero.Attachments.getStorageDirectory(item).path;
@ -346,20 +346,20 @@ describe("Zotero.Sync.Storage.Local", function () {
// Make sure path is set correctly
assert.equal(item.getFilePath(), OS.Path.join(storageDir, filteredFilename));
// Make sure previous files don't exist
assert.isFalse(yield OS.File.exists(OS.Path.join(storageDir, oldFilename)));
assert.isFalse(await OS.File.exists(OS.Path.join(storageDir, oldFilename)));
// And new one does
assert.isTrue(yield OS.File.exists(OS.Path.join(storageDir, filteredFilename)));
assert.isTrue(await OS.File.exists(OS.Path.join(storageDir, filteredFilename)));
// Make sure main file matches attachment hash and mtime
yield assert.eventually.equal(
await assert.eventually.equal(
item.attachmentHash, Zotero.Utilities.Internal.md5(fileContents)
);
yield assert.eventually.equal(item.attachmentModificationTime, mtime);
await assert.eventually.equal(item.attachmentModificationTime, mtime);
});
});
describe("ZIP", function () {
it("should download and extract a ZIP file into the attachment directory", function* () {
it("should download and extract a ZIP file into the attachment directory", async function () {
var file1Name = 'index.html';
var file1Contents = '<html><body>Test</body></html>';
var file2Name = 'aux1.txt';
@ -369,7 +369,7 @@ describe("Zotero.Sync.Storage.Local", function () {
var file3Contents = 'Test 2';
var libraryID = Zotero.Libraries.userLibraryID;
var parentItem = yield createDataObject('item');
var parentItem = await createDataObject('item');
var key = Zotero.DataObjectUtilities.generateKey();
var tmpDir = Zotero.getTempDirectory().path;
@ -377,26 +377,26 @@ describe("Zotero.Sync.Storage.Local", function () {
// Create ZIP file with subdirectory
var tmpDir = Zotero.getTempDirectory().path;
var zipDir = yield getTempDirectory();
yield Zotero.File.putContentsAsync(OS.Path.join(zipDir, file1Name), file1Contents);
yield Zotero.File.putContentsAsync(OS.Path.join(zipDir, file2Name), file2Contents);
var zipDir = await getTempDirectory();
await Zotero.File.putContentsAsync(OS.Path.join(zipDir, file1Name), file1Contents);
await Zotero.File.putContentsAsync(OS.Path.join(zipDir, file2Name), file2Contents);
var subDir = OS.Path.join(zipDir, subDirName);
yield OS.File.makeDir(subDir);
yield Zotero.File.putContentsAsync(OS.Path.join(subDir, file3Name), file3Contents);
yield Zotero.File.zipDirectory(zipDir, zipFile);
yield removeDir(zipDir);
await OS.File.makeDir(subDir);
await Zotero.File.putContentsAsync(OS.Path.join(subDir, file3Name), file3Contents);
await Zotero.File.zipDirectory(zipDir, zipFile);
await removeDir(zipDir);
// Create an existing attachment directory (and subdirectory) to replace
var dir = Zotero.Attachments.getStorageDirectoryByLibraryAndKey(libraryID, key).path;
yield OS.File.makeDir(
await OS.File.makeDir(
OS.Path.join(dir, 'subdir'),
{
from: Zotero.DataDirectory.dir,
unixMode: 0o755
}
);
yield Zotero.File.putContentsAsync(OS.Path.join(dir, 'A'), '');
yield Zotero.File.putContentsAsync(OS.Path.join(dir, 'subdir', 'B'), '');
await Zotero.File.putContentsAsync(OS.Path.join(dir, 'A'), '');
await Zotero.File.putContentsAsync(OS.Path.join(dir, 'subdir', 'B'), '');
var md5 = Zotero.Utilities.Internal.md5(Zotero.File.pathToFile(zipFile));
var mtime = 1445667239000;
@ -413,48 +413,48 @@ describe("Zotero.Sync.Storage.Local", function () {
md5,
mtime
};
yield Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
await Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
var item = yield Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
yield Zotero.Sync.Storage.Local.processDownload({
var item = await Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
await Zotero.Sync.Storage.Local.processDownload({
item,
md5,
mtime,
compressed: true
});
yield OS.File.remove(zipFile);
await OS.File.remove(zipFile);
var storageDir = Zotero.Attachments.getStorageDirectory(item).path;
// Make sure previous files don't exist
assert.isFalse(yield OS.File.exists(OS.Path.join(storageDir, 'A')));
assert.isFalse(yield OS.File.exists(OS.Path.join(storageDir, 'subdir')));
assert.isFalse(yield OS.File.exists(OS.Path.join(storageDir, 'subdir', 'B')));
assert.isFalse(await OS.File.exists(OS.Path.join(storageDir, 'A')));
assert.isFalse(await OS.File.exists(OS.Path.join(storageDir, 'subdir')));
assert.isFalse(await OS.File.exists(OS.Path.join(storageDir, 'subdir', 'B')));
// Make sure main file matches attachment hash and mtime
yield assert.eventually.equal(
await assert.eventually.equal(
item.attachmentHash, Zotero.Utilities.Internal.md5(file1Contents)
);
yield assert.eventually.equal(item.attachmentModificationTime, mtime);
await assert.eventually.equal(item.attachmentModificationTime, mtime);
// Check second file
yield assert.eventually.equal(
await assert.eventually.equal(
Zotero.File.getContentsAsync(OS.Path.join(storageDir, file2Name)),
file2Contents
);
// Check subdirectory and file
assert.isTrue((yield OS.File.stat(OS.Path.join(storageDir, subDirName))).isDir);
yield assert.eventually.equal(
assert.isTrue(((await OS.File.stat(OS.Path.join(storageDir, subDirName)))).isDir);
await assert.eventually.equal(
Zotero.File.getContentsAsync(OS.Path.join(storageDir, subDirName, file3Name)),
file3Contents
);
});
it("should download and rename a ZIP file with invalid filename using Windows parsing rules into the attachment directory", function* () {
it("should download and rename a ZIP file with invalid filename using Windows parsing rules into the attachment directory", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var parentItem = yield createDataObject('item');
var parentItem = await createDataObject('item');
var key = Zotero.DataObjectUtilities.generateKey();
var oldFilename = "Old File";
@ -468,22 +468,22 @@ describe("Zotero.Sync.Storage.Local", function () {
// Create ZIP file
var tmpDir = Zotero.getTempDirectory().path;
var zipDir = yield getTempDirectory();
yield Zotero.File.putContentsAsync(OS.Path.join(zipDir, newFilename), fileContents);
yield Zotero.File.putContentsAsync(OS.Path.join(zipDir, newAuxFilename), '');
yield Zotero.File.zipDirectory(zipDir, zipFile);
yield removeDir(zipDir);
var zipDir = await getTempDirectory();
await Zotero.File.putContentsAsync(OS.Path.join(zipDir, newFilename), fileContents);
await Zotero.File.putContentsAsync(OS.Path.join(zipDir, newAuxFilename), '');
await Zotero.File.zipDirectory(zipDir, zipFile);
await removeDir(zipDir);
// Create an existing attachment directory to replace
var dir = Zotero.Attachments.getStorageDirectoryByLibraryAndKey(libraryID, key).path;
yield OS.File.makeDir(
await OS.File.makeDir(
dir,
{
unixMode: 0o755
}
);
yield Zotero.File.putContentsAsync(OS.Path.join(dir, oldFilename), '');
yield Zotero.File.putContentsAsync(OS.Path.join(dir, oldAuxFilename), '');
await Zotero.File.putContentsAsync(OS.Path.join(dir, oldFilename), '');
await Zotero.File.putContentsAsync(OS.Path.join(dir, oldAuxFilename), '');
var md5 = Zotero.Utilities.Internal.md5(Zotero.File.pathToFile(zipFile));
var mtime = 1445667239000;
@ -500,9 +500,9 @@ describe("Zotero.Sync.Storage.Local", function () {
md5,
mtime
};
yield Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
await Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, [json]);
var item = yield Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
var item = await Zotero.Items.getByLibraryAndKeyAsync(libraryID, key);
// Stub functions to simulate OS.Path.basename() behavior on Windows
var basenameOrigFunc = OS.Path.basename.bind(OS.Path);
@ -521,13 +521,13 @@ describe("Zotero.Sync.Storage.Local", function () {
return pathToFileOrigFunc(path);
});
yield Zotero.Sync.Storage.Local.processDownload({
await Zotero.Sync.Storage.Local.processDownload({
item,
md5,
mtime,
compressed: true
});
yield OS.File.remove(zipFile);
await OS.File.remove(zipFile);
var storageDir = Zotero.Attachments.getStorageDirectory(item).path;
@ -537,32 +537,32 @@ describe("Zotero.Sync.Storage.Local", function () {
// Make sure path is set correctly
assert.equal(item.getFilePath(), OS.Path.join(storageDir, filteredFilename));
// Make sure previous files don't exist
assert.isFalse(yield OS.File.exists(OS.Path.join(storageDir, oldFilename)));
assert.isFalse(yield OS.File.exists(OS.Path.join(storageDir, oldAuxFilename)));
assert.isFalse(await OS.File.exists(OS.Path.join(storageDir, oldFilename)));
assert.isFalse(await OS.File.exists(OS.Path.join(storageDir, oldAuxFilename)));
// And new ones do
assert.isTrue(yield OS.File.exists(OS.Path.join(storageDir, filteredFilename)));
assert.isTrue(yield OS.File.exists(OS.Path.join(storageDir, newAuxFilename)));
assert.isTrue(await OS.File.exists(OS.Path.join(storageDir, filteredFilename)));
assert.isTrue(await OS.File.exists(OS.Path.join(storageDir, newAuxFilename)));
// Make sure main file matches attachment hash and mtime
yield assert.eventually.equal(
await assert.eventually.equal(
item.attachmentHash, Zotero.Utilities.Internal.md5(fileContents)
);
yield assert.eventually.equal(item.attachmentModificationTime, mtime);
await assert.eventually.equal(item.attachmentModificationTime, mtime);
});
});
})
describe("#getConflicts()", function () {
it("should return an array of objects for attachments in conflict", function* () {
it("should return an array of objects for attachments in conflict", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var item1 = yield importFileAttachment('test.png');
var item1 = await importFileAttachment('test.png');
item1.version = 10;
yield item1.saveTx();
var item2 = yield importTextAttachment();
var item3 = yield importHTMLAttachment();
await item1.saveTx();
var item2 = await importTextAttachment();
var item3 = await importHTMLAttachment();
item3.version = 11;
yield item3.saveTx();
await item3.saveTx();
var json1 = item1.toJSON();
var json3 = item3.toJSON();
@ -571,20 +571,20 @@ describe("Zotero.Sync.Storage.Local", function () {
var now = Math.round(new Date().getTime() / 1000) * 1000;
json1.mtime = now - 10000;
json3.mtime = now - 20000;
yield Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json1, json3]);
await Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json1, json3]);
item1.attachmentSyncState = "in_conflict";
yield item1.saveTx({ skipAll: true });
await item1.saveTx({ skipAll: true });
item3.attachmentSyncState = "in_conflict";
yield item3.saveTx({ skipAll: true });
await item3.saveTx({ skipAll: true });
var conflicts = yield Zotero.Sync.Storage.Local.getConflicts(libraryID);
var conflicts = await Zotero.Sync.Storage.Local.getConflicts(libraryID);
assert.lengthOf(conflicts, 2);
var item1Conflict = conflicts.find(x => x.left.key == item1.key);
assert.equal(
item1Conflict.left.dateModified,
Zotero.Date.dateToISO(new Date(yield item1.attachmentModificationTime))
Zotero.Date.dateToISO(new Date(await item1.attachmentModificationTime))
);
assert.equal(
item1Conflict.right.dateModified,
@ -594,7 +594,7 @@ describe("Zotero.Sync.Storage.Local", function () {
var item3Conflict = conflicts.find(x => x.left.key == item3.key);
assert.equal(
item3Conflict.left.dateModified,
Zotero.Date.dateToISO(new Date(yield item3.attachmentModificationTime))
Zotero.Date.dateToISO(new Date(await item3.attachmentModificationTime))
);
assert.equal(
item3Conflict.right.dateModified,
@ -622,16 +622,16 @@ describe("Zotero.Sync.Storage.Local", function () {
});
it("should show the conflict resolution window on attachment conflicts", function* () {
it("should show the conflict resolution window on attachment conflicts", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var item1 = yield importFileAttachment('test.png');
var item1 = await importFileAttachment('test.png');
item1.version = 10;
yield item1.saveTx();
var item2 = yield importTextAttachment();
var item3 = yield importHTMLAttachment();
await item1.saveTx();
var item2 = await importTextAttachment();
var item3 = await importHTMLAttachment();
item3.version = 11;
yield item3.saveTx();
await item3.saveTx();
var json1 = item1.toJSON();
var json3 = item3.toJSON();
@ -640,12 +640,12 @@ describe("Zotero.Sync.Storage.Local", function () {
json1.md5 = 'f4ce1167f3a854896c257a0cc1ac387f';
json3.mtime = new Date().getTime() - 10000;
json3.md5 = 'fcd080b1c2cad562237823ec27671bbd';
yield Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json1, json3]);
await Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json1, json3]);
item1.attachmentSyncState = "in_conflict";
yield item1.saveTx({ skipAll: true });
await item1.saveTx({ skipAll: true });
item3.attachmentSyncState = "in_conflict";
yield item3.saveTx({ skipAll: true });
await item3.saveTx({ skipAll: true });
var promise = waitForWindow('chrome://zotero/content/merge.xhtml', async function (dialog) {
var doc = dialog.document;
@ -684,8 +684,8 @@ describe("Zotero.Sync.Storage.Local", function () {
}
wizard.getButton('finish').click();
})
yield Zotero.Sync.Storage.Local.resolveConflicts(libraryID);
yield promise;
await Zotero.Sync.Storage.Local.resolveConflicts(libraryID);
await promise;
assert.equal(item1.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_FORCE_UPLOAD);
assert.equal(item1.attachmentSyncedModificationTime, json1.mtime);
@ -695,18 +695,18 @@ describe("Zotero.Sync.Storage.Local", function () {
assert.isNull(item3.attachmentSyncedHash);
});
it("should handle attachment conflicts with no remote mtime/md5", function* () {
it("should handle attachment conflicts with no remote mtime/md5", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var item1 = yield importFileAttachment('test.png');
var item1 = await importFileAttachment('test.png');
item1.version = 10;
yield item1.saveTx();
await item1.saveTx();
var json1 = item1.toJSON();
yield Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json1]);
await Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json1]);
item1.attachmentSyncState = "in_conflict";
yield item1.saveTx({ skipAll: true });
await item1.saveTx({ skipAll: true });
var promise = waitForWindow('chrome://zotero/content/merge.xhtml', async function (dialog) {
var doc = dialog.document;
@ -730,8 +730,8 @@ describe("Zotero.Sync.Storage.Local", function () {
}
wizard.getButton('finish').click();
});
yield Zotero.Sync.Storage.Local.resolveConflicts(libraryID);
yield promise;
await Zotero.Sync.Storage.Local.resolveConflicts(libraryID);
await promise;
assert.equal(item1.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_FORCE_UPLOAD);
assert.isNull(item1.attachmentSyncedModificationTime);

View file

@ -2,21 +2,21 @@
describe("Zotero.Sync.Storage.Request", function () {
describe("#run()", function () {
it("should run a request and wait for it to complete", function* () {
it("should run a request and wait for it to complete", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var count = 0;
var item = yield importFileAttachment('test.png');
var item = await importFileAttachment('test.png');
var request = new Zotero.Sync.Storage.Request({
type: 'download',
libraryID,
name: `${item.libraryID}/${item.key}`,
onStart: Zotero.Promise.coroutine(function* () {
yield Zotero.Promise.delay(25);
onStart: async function () {
await Zotero.Promise.delay(25);
count++;
return new Zotero.Sync.Storage.Result;
})
}
});
var results = yield request.start();
var results = await request.start();
assert.equal(count, 1);
})
})

View file

@ -1,6 +1,6 @@
"use strict";
describe("Zotero.Styles", function() {
describe("Zotero.Styles", function () {
var styleID = "http://www.zotero.org/styles/cell";
var stylePath = OS.Path.join(getTestDataDirectory().path, 'cell.csl');
var styleFile = Zotero.File.pathToFile(stylePath);
@ -11,35 +11,35 @@ describe("Zotero.Styles", function() {
style = yield Zotero.File.getContentsAsync(stylePath);
});
describe("Zotero.Styles.install", function() {
describe("Zotero.Styles.install", function () {
afterEach(`${styleID} style should be installed`, function* (){
assert.isOk(Zotero.Styles.get(styleID));
yield Zotero.Styles.get(styleID).remove();
});
it("should install the style from string", function* () {
yield Zotero.Styles.install(style, styleID, true);
it("should install the style from string", async function () {
await Zotero.Styles.install(style, styleID, true);
});
it("should install the style from nsIFile", function* () {
yield Zotero.Styles.install(styleFile, styleID, true);
it("should install the style from nsIFile", async function () {
await Zotero.Styles.install(styleFile, styleID, true);
});
it("should install the style from url", function* () {
it("should install the style from url", async function () {
var getContentsFromURLAsync = Zotero.File.getContentsFromURLAsync;
sinon.stub(Zotero.File, 'getContentsFromURLAsync').callsFake(function(url) {
sinon.stub(Zotero.File, 'getContentsFromURLAsync').callsFake(function (url) {
if (url === styleID) {
return Zotero.Promise.resolve(style);
return Promise.resolve(style);
} else {
return getContentsFromURLAsync.apply(Zotero.File, arguments);
}
});
yield Zotero.Styles.install({url: styleID}, styleID, true);
await Zotero.Styles.install({url: styleID}, styleID, true);
Zotero.File.getContentsFromURLAsync.restore();
});
it("should install the style from file path", function* () {
yield Zotero.Styles.install({file: stylePath}, styleID, true);
it("should install the style from file path", async function () {
await Zotero.Styles.install({file: stylePath}, styleID, true);
})
});

View file

@ -1,5 +1,5 @@
describe("Support Functions for Unit Testing", function() {
describe("resetDB", function() {
describe("Support Functions for Unit Testing", function () {
describe("resetDB", function () {
it("should restore the DB to factory settings", async function () {
await Zotero.DB.queryAsync("CREATE TABLE testTable (foo INTEGER PRIMARY KEY)");
assert.isTrue(await Zotero.DB.tableExists('testTable'));
@ -9,18 +9,18 @@ describe("Support Functions for Unit Testing", function() {
assert.isFalse(await Zotero.DB.tableExists('testTable'));
});
});
describe("loadSampleData", function() {
it("should load data from file", function() {
describe("loadSampleData", function () {
it("should load data from file", function () {
let data = loadSampleData('journalArticle');
assert.isObject(data, 'loaded data object');
assert.isNotNull(data);
assert.isAbove(Object.keys(data).length, 0, 'data object is not empty');
});
});
describe("populateDBWithSampleData", function() {
it("should populate database with data", Zotero.Promise.coroutine(function* () {
describe("populateDBWithSampleData", function () {
it("should populate database with data", async function () {
let data = loadSampleData('journalArticle');
yield populateDBWithSampleData(data);
await populateDBWithSampleData(data);
let skipFields = ['id', 'itemType', 'creators']; // Special comparisons
@ -28,7 +28,7 @@ describe("Support Functions for Unit Testing", function() {
let item = data[itemName];
assert.isAbove(item.id, 0, 'assigned new item ID');
let zItem = yield Zotero.Items.getAsync(item.id);
let zItem = await Zotero.Items.getAsync(item.id);
assert.ok(zItem, 'inserted item into database');
// Compare item type
@ -56,9 +56,9 @@ describe("Support Functions for Unit Testing", function() {
}
}
}
}));
it("should populate items with tags", Zotero.Promise.coroutine(function* () {
let data = yield populateDBWithSampleData({
});
it("should populate items with tags", async function () {
let data = await populateDBWithSampleData({
itemWithTags: {
itemType: "journalArticle",
tags: [
@ -68,7 +68,7 @@ describe("Support Functions for Unit Testing", function() {
}
});
let zItem = yield Zotero.Items.getAsync(data.itemWithTags.id);
let zItem = await Zotero.Items.getAsync(data.itemWithTags.id);
assert.ok(zItem, 'inserted item with tags into database');
@ -78,23 +78,23 @@ describe("Support Functions for Unit Testing", function() {
assert.ok(tagID, '"' + tags[i].tag + '" tag was inserted into the database');
assert.ok(zItem.hasTag(tags[i].tag), '"' + tags[i].tag + '" tag was assigned to item');
}
}));
});
});
describe("generateAllTypesAndFieldsData", function() {
it("should generate all types and fields data", function() {
describe("generateAllTypesAndFieldsData", function () {
it("should generate all types and fields data", function () {
let data = generateAllTypesAndFieldsData();
assert.isObject(data, 'created data object');
assert.isNotNull(data);
assert.isAbove(Object.keys(data).length, 0, 'data object is not empty');
});
it("all types and fields sample data should be up to date", function() {
it("all types and fields sample data should be up to date", function () {
assert.deepEqual(loadSampleData('allTypesAndFields'), generateAllTypesAndFieldsData());
});
});
describe("generateItemJSONData", function() {
it("item JSON data should be up to date", Zotero.Promise.coroutine(function* () {
describe("generateItemJSONData", function () {
it("item JSON data should be up to date", async function () {
let oldData = loadSampleData('itemJSON'),
newData = yield generateItemJSONData();
newData = await generateItemJSONData();
assert.isObject(newData, 'created data object');
assert.isNotNull(newData);
@ -114,7 +114,7 @@ describe("Support Functions for Unit Testing", function() {
}
assert.deepEqual(oldData, newData);
}));
});
});
// describe("generateCiteProcJSExportData", function() {
// let citeURL = Zotero.Prefs.get("export.citePaperJournalArticleURL");
@ -144,10 +144,10 @@ describe("Support Functions for Unit Testing", function() {
// assert.deepEqual(oldData, newData, 'citeproc-js export data has not changed');
// }));
// });
describe("generateTranslatorExportData", function() {
it("legacy mode data should be up to date", Zotero.Promise.coroutine(function* () {
describe("generateTranslatorExportData", function () {
it("legacy mode data should be up to date", async function () {
let oldData = loadSampleData('translatorExportLegacy'),
newData = yield generateTranslatorExportData(true);
newData = await generateTranslatorExportData(true);
assert.isObject(newData, 'created data object');
assert.isNotNull(newData);
@ -167,10 +167,10 @@ describe("Support Functions for Unit Testing", function() {
}
assert.deepEqual(oldData, newData, 'translator export data has not changed');
}));
it("data should be up to date", Zotero.Promise.coroutine(function* () {
});
it("data should be up to date", async function () {
let oldData = loadSampleData('translatorExport'),
newData = yield generateTranslatorExportData();
newData = await generateTranslatorExportData();
assert.isObject(newData, 'created data object');
assert.isNotNull(newData);
@ -190,6 +190,6 @@ describe("Support Functions for Unit Testing", function() {
}
assert.deepEqual(oldData, newData, 'translator export data has not changed');
}));
});
});
});

View file

@ -1,8 +1,6 @@
"use strict";
describe("Zotero.Sync.APIClient", function () {
Components.utils.import("resource://zotero/config.js");
var apiKey = Zotero.Utilities.randomString(24);
var baseURL = "http://local.zotero/";
var server, client;
@ -69,7 +67,7 @@ describe("Zotero.Sync.APIClient", function () {
describe("#getGroups()", function () {
it("should automatically fetch multiple pages of results", function* () {
it("should automatically fetch multiple pages of results", async function () {
function groupJSON(groupID) {
return {
id: groupID,
@ -130,7 +128,7 @@ describe("Zotero.Sync.APIClient", function () {
}
});
var results = yield client.getGroups(1);
var results = await client.getGroups(1);
assert.lengthOf(results, 5);
assert.sameMembers(results.map(o => o.id), [1, 2, 3, 4, 5]);
});

File diff suppressed because it is too large Load diff

View file

@ -56,28 +56,28 @@ describe("Zotero.Sync.EventListeners", function () {
});
it("should sync only changed library", function* () {
it("should sync only changed library", async function () {
var mock = sinon.mock(Zotero.Sync.Runner);
var expectation = mock.expects("setSyncTimeout").once();
var group = yield createGroup();
yield createDataObject('item', { libraryID: group.libraryID });
var group = await createGroup();
await createDataObject('item', { libraryID: group.libraryID });
yield Zotero.Promise.delay(10);
await Zotero.Promise.delay(10);
mock.verify();
assert.sameMembers(expectation.getCall(0).args[2].libraries, [group.libraryID]);
});
it("shouldn't sync skipped library", function* () {
it("shouldn't sync skipped library", async function () {
var mock = sinon.mock(Zotero.Sync.Runner);
var expectation = mock.expects("setSyncTimeout").never();
var group = yield createGroup();
var group = await createGroup();
Zotero.Prefs.set('sync.librariesToSkip', JSON.stringify(["G" + group.groupID]));
yield createDataObject('item', { libraryID: group.libraryID });
await createDataObject('item', { libraryID: group.libraryID });
yield Zotero.Promise.delay(10);
await Zotero.Promise.delay(10);
mock.verify();
});

View file

@ -1,15 +1,13 @@
"use strict";
describe("Zotero.Sync.Data.FullTextEngine", function () {
Components.utils.import("resource://zotero/config.js");
var apiKey = Zotero.Utilities.randomString(24);
var baseURL = "http://local.zotero/";
var engine, server, client, caller, stub, spy;
var responses = {};
var setup = Zotero.Promise.coroutine(function* (options = {}) {
var setup = async function (options = {}) {
server = sinon.fakeServer.create();
server.autoRespond = true;
@ -33,7 +31,7 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
});
return { engine, client, caller };
});
};
function setResponse(response) {
setHTTPResponse(server, baseURL, response, responses);
@ -59,25 +57,25 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
})
describe("Full-Text Syncing", function () {
it("should skip full-text download if main library version is the same", function* () {
({ engine, client, caller } = yield setup());
it("should skip full-text download if main library version is the same", async function () {
({ engine, client, caller } = await setup());
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 10;
yield library.saveTx();
yield Zotero.Fulltext.setLibraryVersion(library.id, 10);
yield engine.start();
await library.saveTx();
await Zotero.Fulltext.setLibraryVersion(library.id, 10);
await engine.start();
});
it("should download full-text into a new library and subsequent updates", function* () {
({ engine, client, caller } = yield setup());
it("should download full-text into a new library and subsequent updates", async function () {
({ engine, client, caller } = await setup());
var item = yield createDataObject('item');
var item = await createDataObject('item');
var attachment = new Zotero.Item('attachment');
attachment.parentItemID = item.id;
attachment.attachmentLinkMode = 'imported_file';
attachment.attachmentContentType = 'application/pdf';
attachment.attachmentFilename = 'test.pdf';
yield attachment.saveTx();
await attachment.saveTx();
var content = generateContent()
var spy = sinon.spy(Zotero.Fulltext, "registerContentProcessor")
@ -88,7 +86,7 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
// Set main library version to new version
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = libraryVersion;
yield library.saveTx();
await library.saveTx();
setResponse({
method: "GET",
@ -114,17 +112,17 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
totalPages: 1
}
});
yield engine.start();
await engine.start();
var dir = Zotero.Attachments.getStorageDirectory(attachment).path;
var unprocessed = OS.Path.join(dir, '.zotero-ft-unprocessed');
assert.isTrue(yield OS.File.exists(unprocessed));
var data = JSON.parse(yield Zotero.File.getContentsAsync(unprocessed));
assert.isTrue(await OS.File.exists(unprocessed));
var data = JSON.parse(await Zotero.File.getContentsAsync(unprocessed));
assert.propertyVal(data, 'text', content);
assert.propertyVal(data, 'indexedPages', 1);
assert.propertyVal(data, 'totalPages', 1);
assert.propertyVal(data, 'version', itemFullTextVersion);
yield assert.eventually.equal(
await assert.eventually.equal(
Zotero.FullText.getLibraryVersion(item.libraryID),
libraryVersion
);
@ -135,15 +133,15 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
//
// Get new content
//
({ engine, client, caller } = yield setup());
({ engine, client, caller } = await setup());
item = yield createDataObject('item');
item = await createDataObject('item');
attachment = new Zotero.Item('attachment');
attachment.parentItemID = item.id;
attachment.attachmentLinkMode = 'imported_file';
attachment.attachmentContentType = 'application/pdf';
attachment.attachmentFilename = 'test.pdf';
yield attachment.saveTx();
await attachment.saveTx();
content = generateContent()
spy = sinon.spy(Zotero.Fulltext, "registerContentProcessor")
@ -154,7 +152,7 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
// Set main library version to new version
library.libraryVersion = libraryVersion;
yield library.saveTx();
await library.saveTx();
setResponse({
method: "GET",
@ -180,17 +178,17 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
totalPages: 1
}
});
yield engine.start();
await engine.start();
var dir = Zotero.Attachments.getStorageDirectory(attachment).path;
var unprocessed = OS.Path.join(dir, '.zotero-ft-unprocessed');
assert.isTrue(yield OS.File.exists(unprocessed));
var data = JSON.parse(yield Zotero.File.getContentsAsync(unprocessed));
assert.isTrue(await OS.File.exists(unprocessed));
var data = JSON.parse(await Zotero.File.getContentsAsync(unprocessed));
assert.propertyVal(data, 'text', content);
assert.propertyVal(data, 'indexedPages', 1);
assert.propertyVal(data, 'totalPages', 1);
assert.propertyVal(data, 'version', itemFullTextVersion);
yield assert.eventually.equal(
await assert.eventually.equal(
Zotero.FullText.getLibraryVersion(item.libraryID),
libraryVersion
);
@ -199,16 +197,16 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
spy.restore();
})
it("should handle remotely missing full-text content", function* () {
({ engine, client, caller } = yield setup());
it("should handle remotely missing full-text content", async function () {
({ engine, client, caller } = await setup());
var item = yield createDataObject('item');
var item = await createDataObject('item');
var attachment = new Zotero.Item('attachment');
attachment.parentItemID = item.id;
attachment.attachmentLinkMode = 'imported_file';
attachment.attachmentContentType = 'application/pdf';
attachment.attachmentFilename = 'test.pdf';
yield attachment.saveTx();
await attachment.saveTx();
var itemFullTextVersion = 10;
var libraryVersion = 15;
@ -232,21 +230,21 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
},
text: ""
});
yield engine.start();
await engine.start();
})
it("should upload new full-text content and subsequent updates", function* () {
it("should upload new full-text content and subsequent updates", async function () {
// https://github.com/cjohansen/Sinon.JS/issues/607
var fixSinonBug = ";charset=utf-8";
var library = Zotero.Libraries.userLibrary;
var libraryID = library.id;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
({ engine, client, caller } = yield setup());
({ engine, client, caller } = await setup());
var item = yield createDataObject('item');
var item = await createDataObject('item');
var attachment1 = new Zotero.Item('attachment');
attachment1.parentItemID = item.id;
@ -255,11 +253,11 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
attachment1.attachmentFilename = 'test.html';
attachment1.attachmentCharset = 'utf-8';
attachment1.synced = true;
yield attachment1.saveTx();
yield Zotero.Attachments.createDirectoryForItem(attachment1);
await attachment1.saveTx();
await Zotero.Attachments.createDirectoryForItem(attachment1);
var path = attachment1.getFilePath();
var content1 = "A" + generateContent()
yield Zotero.File.putContentsAsync(path, content1);
await Zotero.File.putContentsAsync(path, content1);
var attachment2 = new Zotero.Item('attachment');
attachment2.parentItemID = item.id;
@ -268,13 +266,13 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
attachment2.attachmentFilename = 'test.html';
attachment2.attachmentCharset = 'utf-8';
attachment2.synced = true;
yield attachment2.saveTx();
yield Zotero.Attachments.createDirectoryForItem(attachment2);
await attachment2.saveTx();
await Zotero.Attachments.createDirectoryForItem(attachment2);
path = attachment2.getFilePath();
var content2 = "B" + generateContent()
yield Zotero.File.putContentsAsync(path, content2);
await Zotero.File.putContentsAsync(path, content2);
yield Zotero.Fulltext.indexItems([attachment1.id, attachment2.id]);
await Zotero.Fulltext.indexItems([attachment1.id, attachment2.id]);
var libraryVersion = 15;
@ -338,19 +336,19 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
}
})
yield engine.start();
await engine.start();
assert.equal(count, 0);
yield assert.eventually.equal(Zotero.FullText.getItemVersion(attachment1.id), libraryVersion);
yield assert.eventually.equal(Zotero.FullText.getItemVersion(attachment2.id), libraryVersion);
yield assert.eventually.equal(Zotero.Fulltext.getLibraryVersion(libraryID), libraryVersion);
await assert.eventually.equal(Zotero.FullText.getItemVersion(attachment1.id), libraryVersion);
await assert.eventually.equal(Zotero.FullText.getItemVersion(attachment2.id), libraryVersion);
await assert.eventually.equal(Zotero.Fulltext.getLibraryVersion(libraryID), libraryVersion);
assert.equal(Zotero.Libraries.userLibrary.libraryVersion, libraryVersion);
//
// Upload new content
//
({ engine, client, caller } = yield setup());
({ engine, client, caller } = await setup());
library.libraryVersion = libraryVersion;
yield library.saveTx();
await library.saveTx();
var attachment3 = new Zotero.Item('attachment');
attachment3.parentItemID = item.id;
@ -359,13 +357,13 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
attachment3.attachmentFilename = 'test.html';
attachment3.attachmentCharset = 'utf-8';
attachment3.synced = true;
yield attachment3.saveTx();
yield Zotero.Attachments.createDirectoryForItem(attachment3);
await attachment3.saveTx();
await Zotero.Attachments.createDirectoryForItem(attachment3);
path = attachment3.getFilePath();
var content3 = generateContent()
yield Zotero.File.putContentsAsync(path, content3);
yield Zotero.Fulltext.indexItems([attachment3.id]);
await Zotero.File.putContentsAsync(path, content3);
await Zotero.Fulltext.indexItems([attachment3.id]);
count = 1;
setResponse({
@ -418,10 +416,10 @@ describe("Zotero.Sync.Data.FullTextEngine", function () {
}
})
yield engine.start();
await engine.start();
assert.equal(count, 0);
yield assert.eventually.equal(Zotero.FullText.getItemVersion(attachment3.id), libraryVersion);
yield assert.eventually.equal(Zotero.Fulltext.getLibraryVersion(libraryID), libraryVersion);
await assert.eventually.equal(Zotero.FullText.getItemVersion(attachment3.id), libraryVersion);
await assert.eventually.equal(Zotero.Fulltext.getLibraryVersion(libraryID), libraryVersion);
assert.equal(Zotero.Libraries.userLibrary.libraryVersion, libraryVersion);
})
});

View file

@ -1,22 +1,22 @@
"use strict";
describe("Zotero.Sync.Data.Local", function() {
describe("Zotero.Sync.Data.Local", function () {
describe("#getAPIKey()/#setAPIKey()", function () {
it("should get and set an API key", function* () {
it("should get and set an API key", async function () {
var apiKey1 = Zotero.Utilities.randomString(24);
var apiKey2 = Zotero.Utilities.randomString(24);
yield Zotero.Sync.Data.Local.setAPIKey(apiKey1);
yield assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(apiKey1), apiKey1);
yield Zotero.Sync.Data.Local.setAPIKey(apiKey2);
yield assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(apiKey2), apiKey2);
await Zotero.Sync.Data.Local.setAPIKey(apiKey1);
await assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(apiKey1), apiKey1);
await Zotero.Sync.Data.Local.setAPIKey(apiKey2);
await assert.eventually.equal(Zotero.Sync.Data.Local.getAPIKey(apiKey2), apiKey2);
})
it("should clear an API key by setting an empty string", function* () {
it("should clear an API key by setting an empty string", async function () {
var apiKey = Zotero.Utilities.randomString(24);
yield Zotero.Sync.Data.Local.setAPIKey(apiKey);
yield Zotero.Sync.Data.Local.setAPIKey("");
yield assert.eventually.strictEqual(Zotero.Sync.Data.Local.getAPIKey(apiKey), "");
await Zotero.Sync.Data.Local.setAPIKey(apiKey);
await Zotero.Sync.Data.Local.setAPIKey("");
await assert.eventually.strictEqual(Zotero.Sync.Data.Local.getAPIKey(apiKey), "");
})
})
@ -24,7 +24,7 @@ describe("Zotero.Sync.Data.Local", function() {
describe("#checkUser()", function () {
var resetDataDirFile;
before(function() {
before(function () {
resetDataDirFile = OS.Path.join(Zotero.DataDirectory.dir, 'reset-data-directory');
sinon.stub(Zotero.Utilities.Internal, 'quitZotero');
});
@ -34,13 +34,13 @@ describe("Zotero.Sync.Data.Local", function() {
Zotero.Utilities.Internal.quitZotero.reset();
});
after(function() {
after(function () {
Zotero.Utilities.Internal.quitZotero.restore();
});
it("should prompt for data reset and create a temp 'reset-data-directory' file on accept", function* (){
yield Zotero.Users.setCurrentUserID(1);
yield Zotero.Users.setCurrentUsername("A");
it("should prompt for data reset and create a temp 'reset-data-directory' file on accept", async function () {
await Zotero.Users.setCurrentUserID(1);
await Zotero.Users.setCurrentUsername("A");
var handled = false;
waitForDialog(function (window) {
@ -60,20 +60,20 @@ describe("Zotero.Sync.Data.Local", function() {
handled = true;
}, 'accept', 'chrome://zotero/content/hardConfirmationDialog.xhtml');
var cont = yield Zotero.Sync.Data.Local.checkUser(window, 2, "B");
var resetDataDirFileExists = yield OS.File.exists(resetDataDirFile);
var cont = await Zotero.Sync.Data.Local.checkUser(window, 2, "B");
var resetDataDirFileExists = await OS.File.exists(resetDataDirFile);
assert.isTrue(handled);
assert.isTrue(cont);
assert.isTrue(resetDataDirFileExists);
});
it("should prompt for data reset and cancel", function* () {
yield Zotero.Users.setCurrentUserID(1);
yield Zotero.Users.setCurrentUsername("A");
it("should prompt for data reset and cancel", async function () {
await Zotero.Users.setCurrentUserID(1);
await Zotero.Users.setCurrentUsername("A");
waitForDialog(false, 'cancel', 'chrome://zotero/content/hardConfirmationDialog.xhtml');
var cont = yield Zotero.Sync.Data.Local.checkUser(window, 2, "B");
var resetDataDirFileExists = yield OS.File.exists(resetDataDirFile);
var cont = await Zotero.Sync.Data.Local.checkUser(window, 2, "B");
var resetDataDirFileExists = await OS.File.exists(resetDataDirFile);
assert.isFalse(cont);
assert.isFalse(resetDataDirFileExists);
@ -83,7 +83,7 @@ describe("Zotero.Sync.Data.Local", function() {
// extra1 functionality not used at the moment
it.skip("should prompt for data reset and allow to choose a new data directory", function* (){
sinon.stub(Zotero.DataDirectory, 'forceChange').returns(Zotero.Promise.resolve(true));
sinon.stub(Zotero.DataDirectory, 'forceChange').returns(Promise.resolve(true));
yield Zotero.Users.setCurrentUserID(1);
yield Zotero.Users.setCurrentUsername("A");
@ -98,14 +98,14 @@ describe("Zotero.Sync.Data.Local", function() {
Zotero.DataDirectory.forceChange.restore();
});
it("should migrate relations using local user key", function* () {
yield Zotero.DB.queryAsync("DELETE FROM settings WHERE setting='account'");
yield Zotero.Users.init();
it("should migrate relations using local user key", async function () {
await Zotero.DB.queryAsync("DELETE FROM settings WHERE setting='account'");
await Zotero.Users.init();
var item1 = yield createDataObject('item');
var item1 = await createDataObject('item');
var item2 = createUnsavedDataObject('item');
item2.addRelatedItem(item1);
yield item2.save();
await item2.save();
var pred = Zotero.Relations.relatedItemPredicate;
assert.isTrue(
@ -113,7 +113,7 @@ describe("Zotero.Sync.Data.Local", function() {
);
waitForDialog(false, 'accept', 'chrome://zotero/content/hardConfirmationDialog.xhtml');
yield Zotero.Sync.Data.Local.checkUser(window, 1, "A");
await Zotero.Sync.Data.Local.checkUser(window, 1, "A");
assert.isTrue(
item2.toJSON().relations[pred][0].startsWith('http://zotero.org/users/1/items/')
@ -126,8 +126,8 @@ describe("Zotero.Sync.Data.Local", function() {
//
// editable
//
it("should prompt if library is changing from editable to non-editable and reset library on accept", function* () {
var group = yield createGroup();
it("should prompt if library is changing from editable to non-editable and reset library on accept", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
var promise = waitForDialog(function (dialog) {
var text = dialog.document.documentElement.textContent;
@ -135,20 +135,20 @@ describe("Zotero.Sync.Data.Local", function() {
});
var mock = sinon.mock(Zotero.Sync.Data.Local);
mock.expects("_libraryHasUnsyncedData").once().returns(Zotero.Promise.resolve(true));
mock.expects("resetUnsyncedLibraryData").once().returns(Zotero.Promise.resolve());
mock.expects("_libraryHasUnsyncedData").once().returns(Promise.resolve(true));
mock.expects("resetUnsyncedLibraryData").once().returns(Promise.resolve());
mock.expects("resetUnsyncedLibraryFiles").never();
assert.isTrue(
yield Zotero.Sync.Data.Local.checkLibraryForAccess(null, libraryID, false, false)
await Zotero.Sync.Data.Local.checkLibraryForAccess(null, libraryID, false, false)
);
yield promise;
await promise;
mock.verify();
});
it("should prompt if library is changing from editable to non-editable but not reset library on cancel", function* () {
var group = yield createGroup();
it("should prompt if library is changing from editable to non-editable but not reset library on cancel", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
var promise = waitForDialog(function (dialog) {
var text = dialog.document.documentElement.textContent;
@ -156,29 +156,29 @@ describe("Zotero.Sync.Data.Local", function() {
}, "cancel");
var mock = sinon.mock(Zotero.Sync.Data.Local);
mock.expects("_libraryHasUnsyncedData").once().returns(Zotero.Promise.resolve(true));
mock.expects("_libraryHasUnsyncedData").once().returns(Promise.resolve(true));
mock.expects("resetUnsyncedLibraryData").never();
mock.expects("resetUnsyncedLibraryFiles").never();
assert.isFalse(
yield Zotero.Sync.Data.Local.checkLibraryForAccess(null, libraryID, false, false)
await Zotero.Sync.Data.Local.checkLibraryForAccess(null, libraryID, false, false)
);
yield promise;
await promise;
mock.verify();
});
it("should not prompt if library is changing from editable to non-editable", function* () {
var group = yield createGroup({ editable: false, filesEditable: false });
it("should not prompt if library is changing from editable to non-editable", async function () {
var group = await createGroup({ editable: false, filesEditable: false });
var libraryID = group.libraryID;
yield Zotero.Sync.Data.Local.checkLibraryForAccess(null, libraryID, true, true);
await Zotero.Sync.Data.Local.checkLibraryForAccess(null, libraryID, true, true);
});
//
// filesEditable
//
it("should prompt if library is changing from filesEditable to non-filesEditable and reset library files on accept", function* () {
var group = yield createGroup();
it("should prompt if library is changing from filesEditable to non-filesEditable and reset library files on accept", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
var promise = waitForDialog(function (dialog) {
var text = dialog.document.documentElement.textContent;
@ -186,20 +186,20 @@ describe("Zotero.Sync.Data.Local", function() {
});
var mock = sinon.mock(Zotero.Sync.Data.Local);
mock.expects("_libraryHasUnsyncedFiles").once().returns(Zotero.Promise.resolve(true));
mock.expects("_libraryHasUnsyncedFiles").once().returns(Promise.resolve(true));
mock.expects("resetUnsyncedLibraryData").never();
mock.expects("resetUnsyncedLibraryFiles").once().returns(Zotero.Promise.resolve());
mock.expects("resetUnsyncedLibraryFiles").once().returns(Promise.resolve());
assert.isTrue(
yield Zotero.Sync.Data.Local.checkLibraryForAccess(null, libraryID, true, false)
await Zotero.Sync.Data.Local.checkLibraryForAccess(null, libraryID, true, false)
);
yield promise;
await promise;
mock.verify();
});
it("should prompt if library is changing from filesEditable to non-filesEditable but not reset library files on cancel", function* () {
var group = yield createGroup();
it("should prompt if library is changing from filesEditable to non-filesEditable but not reset library files on cancel", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
var promise = waitForDialog(function (dialog) {
var text = dialog.document.documentElement.textContent;
@ -207,14 +207,14 @@ describe("Zotero.Sync.Data.Local", function() {
}, "cancel");
var mock = sinon.mock(Zotero.Sync.Data.Local);
mock.expects("_libraryHasUnsyncedFiles").once().returns(Zotero.Promise.resolve(true));
mock.expects("_libraryHasUnsyncedFiles").once().returns(Promise.resolve(true));
mock.expects("resetUnsyncedLibraryData").never();
mock.expects("resetUnsyncedLibraryFiles").never();
assert.isFalse(
yield Zotero.Sync.Data.Local.checkLibraryForAccess(null, libraryID, true, false)
await Zotero.Sync.Data.Local.checkLibraryForAccess(null, libraryID, true, false)
);
yield promise;
await promise;
mock.verify();
});
@ -222,73 +222,73 @@ describe("Zotero.Sync.Data.Local", function() {
describe("#_libraryHasUnsyncedData()", function () {
it("should return true for unsynced setting", function* () {
var group = yield createGroup();
it("should return true for unsynced setting", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
yield Zotero.SyncedSettings.set(libraryID, "testSetting", { foo: "bar" });
assert.isTrue(yield Zotero.Sync.Data.Local._libraryHasUnsyncedData(libraryID));
await Zotero.SyncedSettings.set(libraryID, "testSetting", { foo: "bar" });
assert.isTrue(await Zotero.Sync.Data.Local._libraryHasUnsyncedData(libraryID));
});
it("should return true for unsynced item", function* () {
var group = yield createGroup();
it("should return true for unsynced item", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
yield createDataObject('item', { libraryID });
assert.isTrue(yield Zotero.Sync.Data.Local._libraryHasUnsyncedData(libraryID));
await createDataObject('item', { libraryID });
assert.isTrue(await Zotero.Sync.Data.Local._libraryHasUnsyncedData(libraryID));
});
it("should return false if no changes", function* () {
var group = yield createGroup();
it("should return false if no changes", async function () {
var group = await createGroup();
var libraryID = group.libraryID;
assert.isFalse(yield Zotero.Sync.Data.Local._libraryHasUnsyncedData(libraryID));
assert.isFalse(await Zotero.Sync.Data.Local._libraryHasUnsyncedData(libraryID));
});
});
describe("#resetUnsyncedLibraryData()", function () {
it("should revert group and mark for full sync", function* () {
var group = yield createGroup({
it("should revert group and mark for full sync", async function () {
var group = await createGroup({
version: 1,
libraryVersion: 2
});
var libraryID = group.libraryID;
// New setting
yield Zotero.SyncedSettings.set(libraryID, "testSetting", { foo: "bar" });
await Zotero.SyncedSettings.set(libraryID, "testSetting", { foo: "bar" });
// Changed collection
var changedCollection = yield createDataObject('collection', { libraryID, version: 1 });
var changedCollection = await createDataObject('collection', { libraryID, version: 1 });
var originalCollectionName = changedCollection.name;
yield Zotero.Sync.Data.Local.saveCacheObject(
await Zotero.Sync.Data.Local.saveCacheObject(
'collection', libraryID, changedCollection.toJSON()
);
yield modifyDataObject(changedCollection);
await modifyDataObject(changedCollection);
// Unchanged item
var unchangedItem = yield createDataObject('item', { libraryID, version: 1, synced: true });
yield Zotero.Sync.Data.Local.saveCacheObject(
var unchangedItem = await createDataObject('item', { libraryID, version: 1, synced: true });
await Zotero.Sync.Data.Local.saveCacheObject(
'item', libraryID, unchangedItem.toJSON()
);
// Changed item
var changedItem = yield createDataObject('item', { libraryID, version: 1 });
var changedItem = await createDataObject('item', { libraryID, version: 1 });
var originalChangedItemTitle = changedItem.getField('title');
yield Zotero.Sync.Data.Local.saveCacheObject('item', libraryID, changedItem.toJSON());
yield modifyDataObject(changedItem);
await Zotero.Sync.Data.Local.saveCacheObject('item', libraryID, changedItem.toJSON());
await modifyDataObject(changedItem);
// New item
var newItem = yield createDataObject('item', { libraryID, version: 1 });
var newItem = await createDataObject('item', { libraryID, version: 1 });
var newItemKey = newItem.key;
// Delete item
var deletedItem = yield createDataObject('item', { libraryID });
var deletedItem = await createDataObject('item', { libraryID });
var deletedItemKey = deletedItem.key;
yield deletedItem.eraseTx();
await deletedItem.eraseTx();
// Make group read-only
group.editable = false;
yield group.saveTx();
await group.saveTx();
yield Zotero.Sync.Data.Local.resetUnsyncedLibraryData(libraryID);
await Zotero.Sync.Data.Local.resetUnsyncedLibraryData(libraryID);
assert.isNull(Zotero.SyncedSettings.get(group.libraryID, "testSetting"));
@ -302,7 +302,7 @@ describe("Zotero.Sync.Data.Local", function() {
assert.isFalse(Zotero.Items.get(newItemKey));
assert.isFalse(yield Zotero.Sync.Data.Local.getDateDeleted('item', libraryID, deletedItemKey));
assert.isFalse(await Zotero.Sync.Data.Local.getDateDeleted('item', libraryID, deletedItemKey));
assert.equal(group.libraryVersion, -1);
});
@ -356,41 +356,41 @@ describe("Zotero.Sync.Data.Local", function() {
describe("#resetUnsyncedLibraryFiles()", function () {
it("should delete unsynced files", function* () {
var group = yield createGroup({
it("should delete unsynced files", async function () {
var group = await createGroup({
version: 1,
libraryVersion: 2
});
var libraryID = group.libraryID;
// File attachment that's totally in sync -- leave alone
var attachment1 = yield importFileAttachment('test.png', { libraryID });
var attachment1 = await importFileAttachment('test.png', { libraryID });
attachment1.attachmentSyncState = "in_sync";
attachment1.attachmentSyncedModificationTime = yield attachment1.attachmentModificationTime;
attachment1.attachmentSyncedHash = yield attachment1.attachmentHash;
attachment1.attachmentSyncedModificationTime = await attachment1.attachmentModificationTime;
attachment1.attachmentSyncedHash = await attachment1.attachmentHash;
attachment1.synced = true;
yield attachment1.saveTx({
await attachment1.saveTx({
skipSyncedUpdate: true
});
// File attachment that's in sync with changed file -- delete file and mark for download
var attachment2 = yield importFileAttachment('test.png', { libraryID });
var attachment2 = await importFileAttachment('test.png', { libraryID });
attachment2.synced = true;
yield attachment2.saveTx({
await attachment2.saveTx({
skipSyncedUpdate: true
});
// File attachment that's unsynced -- delete item and file
var attachment3 = yield importFileAttachment('test.pdf', { libraryID });
var attachment3 = await importFileAttachment('test.pdf', { libraryID });
// Has to be called before resetUnsyncedLibraryFiles()
assert.isTrue(yield Zotero.Sync.Data.Local._libraryHasUnsyncedFiles(libraryID));
assert.isTrue(await Zotero.Sync.Data.Local._libraryHasUnsyncedFiles(libraryID));
yield Zotero.Sync.Data.Local.resetUnsyncedLibraryFiles(libraryID);
await Zotero.Sync.Data.Local.resetUnsyncedLibraryFiles(libraryID);
assert.isTrue(yield attachment1.fileExists());
assert.isFalse(yield attachment2.fileExists());
assert.isFalse(yield attachment3.fileExists());
assert.isTrue(await attachment1.fileExists());
assert.isFalse(await attachment2.fileExists());
assert.isFalse(await attachment3.fileExists());
assert.equal(
attachment1.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_IN_SYNC
);
@ -442,8 +442,8 @@ describe("Zotero.Sync.Data.Local", function() {
);
})
it("should return latest version of all objects if no keys passed", function* () {
var versions = yield Zotero.Sync.Data.Local.getLatestCacheObjectVersions(
it("should return latest version of all objects if no keys passed", async function () {
var versions = await Zotero.Sync.Data.Local.getLatestCacheObjectVersions(
'item',
Zotero.Libraries.userLibraryID
);
@ -455,8 +455,8 @@ describe("Zotero.Sync.Data.Local", function() {
assert.equal(versions.CCCCCCCC, 3);
})
it("should return latest version of objects with passed keys", function* () {
var versions = yield Zotero.Sync.Data.Local.getLatestCacheObjectVersions(
it("should return latest version of objects with passed keys", async function () {
var versions = await Zotero.Sync.Data.Local.getLatestCacheObjectVersions(
'item',
Zotero.Libraries.userLibraryID,
['AAAAAAAA', 'CCCCCCCC']
@ -547,12 +547,12 @@ describe("Zotero.Sync.Data.Local", function() {
Zotero.Prefs.set('sync.autoSync', false);
});
it("should update local version number and mark as synced if remote version is identical", function* () {
it("should update local version number and mark as synced if remote version is identical", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
for (let type of types) {
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
let obj = yield createDataObject(type);
let obj = await createDataObject(type);
let data = obj.toJSON();
data.key = obj.key;
data.version = 10;
@ -561,7 +561,7 @@ describe("Zotero.Sync.Data.Local", function() {
version: 10,
data: data
};
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
await Zotero.Sync.Data.Local.processObjectsFromJSON(
type, libraryID, [json], { stopOnError: true }
);
let localObj = objectsClass.getByLibraryAndKey(libraryID, obj.key);
@ -828,29 +828,29 @@ describe("Zotero.Sync.Data.Local", function() {
assert.sameDeepMembers(cacheJSON.data.creators, newCreators);
});
it("should delete older versions in sync cache after processing", function* () {
it("should delete older versions in sync cache after processing", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
for (let type of types) {
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
// Save original version
let obj = yield createDataObject(type, { version: 5 });
let obj = await createDataObject(type, { version: 5 });
let data = obj.toJSON();
yield Zotero.Sync.Data.Local.saveCacheObjects(
await Zotero.Sync.Data.Local.saveCacheObjects(
type, libraryID, [data]
);
// Save newer version
data.version = 10;
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
await Zotero.Sync.Data.Local.processObjectsFromJSON(
type, libraryID, [data], { stopOnError: true }
);
let localObj = objectsClass.getByLibraryAndKey(libraryID, obj.key);
assert.equal(localObj.version, 10);
let versions = yield Zotero.Sync.Data.Local.getCacheObjectVersions(
let versions = await Zotero.Sync.Data.Local.getCacheObjectVersions(
type, libraryID, obj.key
);
assert.sameMembers(
@ -861,14 +861,14 @@ describe("Zotero.Sync.Data.Local", function() {
}
});
it("should delete object from sync queue after processing", function* () {
it("should delete object from sync queue after processing", async function () {
var objectType = 'item';
var libraryID = Zotero.Libraries.userLibraryID;
var key = Zotero.DataObjectUtilities.generateKey();
yield Zotero.Sync.Data.Local.addObjectsToSyncQueue(objectType, libraryID, [key]);
await Zotero.Sync.Data.Local.addObjectsToSyncQueue(objectType, libraryID, [key]);
var versions = yield Zotero.Sync.Data.Local.getObjectsFromSyncQueue(objectType, libraryID);
var versions = await Zotero.Sync.Data.Local.getObjectsFromSyncQueue(objectType, libraryID);
assert.include(versions, key);
var json = {
@ -882,15 +882,15 @@ describe("Zotero.Sync.Data.Local", function() {
}
};
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
await Zotero.Sync.Data.Local.processObjectsFromJSON(
objectType, libraryID, [json], { stopOnError: true }
);
var versions = yield Zotero.Sync.Data.Local.getObjectsFromSyncQueue(objectType, libraryID);
var versions = await Zotero.Sync.Data.Local.getObjectsFromSyncQueue(objectType, libraryID);
assert.notInclude(versions, key);
});
it("should mark new attachment items and library for download", function* () {
it("should mark new attachment items and library for download", async function () {
var library = Zotero.Libraries.userLibrary;
var libraryID = library.id;
Zotero.Sync.Storage.Local.setModeForLibrary(libraryID, 'zfs');
@ -910,7 +910,7 @@ describe("Zotero.Sync.Data.Local", function() {
}
};
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
await Zotero.Sync.Data.Local.processObjectsFromJSON(
'item', libraryID, [json], { stopOnError: true }
);
var item = Zotero.Items.getByLibraryAndKey(libraryID, key);
@ -918,21 +918,21 @@ describe("Zotero.Sync.Data.Local", function() {
assert.isTrue(library.storageDownloadNeeded);
})
it("should mark remotely updated attachment item for forced download", function* () {
it("should mark remotely updated attachment item for forced download", async function () {
var library = Zotero.Libraries.userLibrary;
var libraryID = library.id;
Zotero.Sync.Storage.Local.setModeForLibrary(libraryID, 'zfs');
var item = yield importFileAttachment('test.png');
var item = await importFileAttachment('test.png');
item.version = 5;
item.synced = true;
yield item.saveTx();
await item.saveTx();
// Set file as synced
item.attachmentSyncedModificationTime = yield item.attachmentModificationTime;
item.attachmentSyncedHash = yield item.attachmentHash;
item.attachmentSyncedModificationTime = await item.attachmentModificationTime;
item.attachmentSyncedHash = await item.attachmentHash;
item.attachmentSyncState = "in_sync";
yield item.saveTx({ skipAll: true });
await item.saveTx({ skipAll: true });
// Simulate download of version with updated attachment
var json = item.toResponseJSON();
@ -940,7 +940,7 @@ describe("Zotero.Sync.Data.Local", function() {
json.data.version = 10;
json.data.md5 = '57f8a4fda823187b91e1191487b87fe6';
json.data.mtime = new Date().getTime() + 10000;
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
await Zotero.Sync.Data.Local.processObjectsFromJSON(
'item', libraryID, [json], { stopOnError: true }
);
@ -981,33 +981,33 @@ describe("Zotero.Sync.Data.Local", function() {
assert.isTrue(library.storageDownloadNeeded);
});
it("should ignore attachment metadata when resolving metadata conflict", function* () {
it("should ignore attachment metadata when resolving metadata conflict", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
Zotero.Sync.Storage.Local.setModeForLibrary(libraryID, 'zfs');
var item = yield importFileAttachment('test.png');
var item = await importFileAttachment('test.png');
item.version = 5;
yield item.saveTx();
await item.saveTx();
var json = item.toResponseJSON();
yield Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json]);
await Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json]);
// Set file as synced
item.attachmentSyncedModificationTime = yield item.attachmentModificationTime;
item.attachmentSyncedHash = yield item.attachmentHash;
item.attachmentSyncedModificationTime = await item.attachmentModificationTime;
item.attachmentSyncedHash = await item.attachmentHash;
item.attachmentSyncState = "in_sync";
yield item.saveTx({ skipAll: true });
await item.saveTx({ skipAll: true });
// Modify title locally, leaving item unsynced
var newTitle = Zotero.Utilities.randomString();
item.setField('title', newTitle);
yield item.saveTx();
await item.saveTx();
// Simulate download of version with original title but updated attachment
json.version = 10;
json.data.version = 10;
json.data.md5 = '57f8a4fda823187b91e1191487b87fe6';
json.data.mtime = new Date().getTime() + 10000;
yield Zotero.Sync.Data.Local.processObjectsFromJSON(
await Zotero.Sync.Data.Local.processObjectsFromJSON(
'item', libraryID, [json], { stopOnError: true }
);
@ -1015,7 +1015,7 @@ describe("Zotero.Sync.Data.Local", function() {
assert.equal(item.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_FORCE_DOWNLOAD);
})
it("should roll back partial object changes on error", function* () {
it("should roll back partial object changes on error", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var key1 = "AAAAAAAA";
var key2 = "BBBBBBBB";
@ -1041,14 +1041,14 @@ describe("Zotero.Sync.Data.Local", function() {
}
}
];
yield Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, json);
await Zotero.Sync.Data.Local.processObjectsFromJSON('item', libraryID, json);
// Shouldn't roll back the successful item
yield assert.eventually.equal(Zotero.DB.valueQueryAsync(
await assert.eventually.equal(Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM items WHERE libraryID=? AND key=?", [libraryID, key1]
), 1);
// Should rollback the unsuccessful item
yield assert.eventually.equal(Zotero.DB.valueQueryAsync(
await assert.eventually.equal(Zotero.DB.valueQueryAsync(
"SELECT COUNT(*) FROM items WHERE libraryID=? AND key=?", [libraryID, key2]
), 0);
});
@ -1134,7 +1134,7 @@ describe("Zotero.Sync.Data.Local", function() {
});
describe("#addObjectsToSyncQueue()", function () {
it("should add new objects and update lastCheck and tries for existing objects", function* () {
it("should add new objects and update lastCheck and tries for existing objects", async function () {
var objectType = 'item';
var syncObjectTypeID = Zotero.Sync.Data.Utilities.getSyncObjectTypeID(objectType);
var now = Zotero.Date.getUnixTimestamp();
@ -1142,7 +1142,7 @@ describe("Zotero.Sync.Data.Local", function() {
var key2 = Zotero.DataObjectUtilities.generateKey();
var key3 = Zotero.DataObjectUtilities.generateKey();
var key4 = Zotero.DataObjectUtilities.generateKey();
yield Zotero.DB.queryAsync(
await Zotero.DB.queryAsync(
"INSERT INTO syncQueue (libraryID, key, syncObjectTypeID, lastCheck, tries) "
+ "VALUES (?, ?, ?, ?, ?), (?, ?, ?, ?, ?), (?, ?, ?, ?, ?)",
[
@ -1152,33 +1152,33 @@ describe("Zotero.Sync.Data.Local", function() {
]
);
yield Zotero.Sync.Data.Local.addObjectsToSyncQueue(objectType, lib1, [key1, key2]);
yield Zotero.Sync.Data.Local.addObjectsToSyncQueue(objectType, lib2, [key4]);
await Zotero.Sync.Data.Local.addObjectsToSyncQueue(objectType, lib1, [key1, key2]);
await Zotero.Sync.Data.Local.addObjectsToSyncQueue(objectType, lib2, [key4]);
var sql = "SELECT lastCheck, tries FROM syncQueue WHERE libraryID=? "
+ `AND syncObjectTypeID=${syncObjectTypeID} AND key=?`;
var row;
// key1
row = yield Zotero.DB.rowQueryAsync(sql, [lib1, key1]);
row = await Zotero.DB.rowQueryAsync(sql, [lib1, key1]);
assert.approximately(row.lastCheck, now, 1);
assert.equal(row.tries, 1);
// key2
row = yield Zotero.DB.rowQueryAsync(sql, [lib1, key2]);
row = await Zotero.DB.rowQueryAsync(sql, [lib1, key2]);
assert.approximately(row.lastCheck, now, 1);
assert.equal(row.tries, 2);
// key3
row = yield Zotero.DB.rowQueryAsync(sql, [lib2, key3]);
row = await Zotero.DB.rowQueryAsync(sql, [lib2, key3]);
assert.equal(row.lastCheck, now - 86400);
assert.equal(row.tries, 2);
// key4
row = yield Zotero.DB.rowQueryAsync(sql, [lib2, key4]);
row = await Zotero.DB.rowQueryAsync(sql, [lib2, key4]);
assert.approximately(row.lastCheck, now, 1);
assert.equal(row.tries, 0);
});
});
describe("#getObjectsToTryFromSyncQueue()", function () {
it("should get objects that should be retried", function* () {
it("should get objects that should be retried", async function () {
var objectType = 'item';
var syncObjectTypeID = Zotero.Sync.Data.Utilities.getSyncObjectTypeID(objectType);
var now = Zotero.Date.getUnixTimestamp();
@ -1186,7 +1186,7 @@ describe("Zotero.Sync.Data.Local", function() {
var key2 = Zotero.DataObjectUtilities.generateKey();
var key3 = Zotero.DataObjectUtilities.generateKey();
var key4 = Zotero.DataObjectUtilities.generateKey();
yield Zotero.DB.queryAsync(
await Zotero.DB.queryAsync(
"INSERT INTO syncQueue (libraryID, key, syncObjectTypeID, lastCheck, tries) "
+ "VALUES (?, ?, ?, ?, ?), (?, ?, ?, ?, ?), (?, ?, ?, ?, ?)",
[
@ -1196,22 +1196,22 @@ describe("Zotero.Sync.Data.Local", function() {
]
);
var keys = yield Zotero.Sync.Data.Local.getObjectsToTryFromSyncQueue('item', lib1);
var keys = await Zotero.Sync.Data.Local.getObjectsToTryFromSyncQueue('item', lib1);
assert.sameMembers(keys, [key1]);
var keys = yield Zotero.Sync.Data.Local.getObjectsToTryFromSyncQueue('item', lib2);
var keys = await Zotero.Sync.Data.Local.getObjectsToTryFromSyncQueue('item', lib2);
assert.sameMembers(keys, [key3]);
});
});
describe("#removeObjectsFromSyncQueue()", function () {
it("should remove objects from the sync queue", function* () {
it("should remove objects from the sync queue", async function () {
var objectType = 'item';
var syncObjectTypeID = Zotero.Sync.Data.Utilities.getSyncObjectTypeID(objectType);
var now = Zotero.Date.getUnixTimestamp();
var key1 = Zotero.DataObjectUtilities.generateKey();
var key2 = Zotero.DataObjectUtilities.generateKey();
var key3 = Zotero.DataObjectUtilities.generateKey();
yield Zotero.DB.queryAsync(
await Zotero.DB.queryAsync(
"INSERT INTO syncQueue (libraryID, key, syncObjectTypeID, lastCheck, tries) "
+ "VALUES (?, ?, ?, ?, ?), (?, ?, ?, ?, ?), (?, ?, ?, ?, ?)",
[
@ -1221,13 +1221,13 @@ describe("Zotero.Sync.Data.Local", function() {
]
);
yield Zotero.Sync.Data.Local.removeObjectsFromSyncQueue('item', lib1, [key1]);
await Zotero.Sync.Data.Local.removeObjectsFromSyncQueue('item', lib1, [key1]);
var sql = "SELECT COUNT(*) FROM syncQueue WHERE libraryID=? "
+ `AND syncObjectTypeID=${syncObjectTypeID} AND key=?`;
assert.notOk(yield Zotero.DB.valueQueryAsync(sql, [lib1, key1]));
assert.ok(yield Zotero.DB.valueQueryAsync(sql, [lib1, key2]));
assert.ok(yield Zotero.DB.valueQueryAsync(sql, [lib2, key3]));
assert.notOk(await Zotero.DB.valueQueryAsync(sql, [lib1, key1]));
assert.ok(await Zotero.DB.valueQueryAsync(sql, [lib1, key2]));
assert.ok(await Zotero.DB.valueQueryAsync(sql, [lib2, key3]));
})
});
@ -1240,12 +1240,12 @@ describe("Zotero.Sync.Data.Local", function() {
}
})
it("should be run on version upgrade", function* () {
it("should be run on version upgrade", async function () {
var sql = "REPLACE INTO settings (setting, key, value) VALUES ('client', 'lastVersion', ?)";
yield Zotero.DB.queryAsync(sql, "5.0foo");
await Zotero.DB.queryAsync(sql, "5.0foo");
spy = sinon.spy(Zotero.Sync.Data.Local, "resetSyncQueueTries");
yield Zotero.Schema.updateSchema();
await Zotero.Schema.updateSchema();
assert.ok(spy.called);
});
});
@ -1253,12 +1253,12 @@ describe("Zotero.Sync.Data.Local", function() {
describe("#showConflictResolutionWindow()", function () {
it("should show title of note parent", function* () {
var parentItem = yield createDataObject('item', { title: "Parent" });
it("should show title of note parent", async function () {
var parentItem = await createDataObject('item', { title: "Parent" });
var note = new Zotero.Item('note');
note.parentKey = parentItem.key;
note.setNote("Test");
yield note.saveTx();
await note.saveTx();
var promise = waitForWindow('chrome://zotero/content/merge.xhtml', function (dialog) {
var doc = dialog.document;
@ -1288,7 +1288,7 @@ describe("Zotero.Sync.Data.Local", function() {
}
]);
yield promise;
await promise;
});
it("should switch types by showing regular item after note", async function () {

View file

@ -1,8 +1,6 @@
"use strict";
describe("Zotero.Sync.Runner", function () {
Components.utils.import("resource://zotero/config.js");
var apiKey = Zotero.Utilities.randomString(24);
var baseURL = "http://local.zotero/";
var userLibraryID, runner, caller, server, stub, spy;
@ -211,9 +209,9 @@ describe("Zotero.Sync.Runner", function () {
})
describe("#checkAccess()", function () {
it("should check key access", function* () {
it("should check key access", async function () {
setResponse('keyInfo.fullAccess');
var json = yield runner.checkAccess(runner.getAPIClient({ apiKey }));
var json = await runner.checkAccess(runner.getAPIClient({ apiKey }));
var compare = {};
Object.assign(compare, responses.keyInfo.fullAccess.json);
delete compare.key;
@ -239,21 +237,21 @@ describe("Zotero.Sync.Runner", function () {
}
})
it("should check library access and versions without library list", function* () {
it("should check library access and versions without library list", async function () {
// Create group with same id and version as groups response
var groupData = responses.groups.ownerGroup;
var group1 = yield createGroup({
var group1 = await createGroup({
id: groupData.json.id,
version: groupData.json.version
});
groupData = responses.groups.memberGroup;
var group2 = yield createGroup({
var group2 = await createGroup({
id: groupData.json.id,
version: groupData.json.version
});
setResponse('userGroups.groupVersions');
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }), false, responses.keyInfo.fullAccess.json
);
assert.lengthOf(libraries, 3);
@ -263,21 +261,21 @@ describe("Zotero.Sync.Runner", function () {
);
})
it("should check library access and versions with library list", function* () {
it("should check library access and versions with library list", async function () {
// Create groups with same id and version as groups response
var groupData = responses.groups.ownerGroup;
var group1 = yield createGroup({
var group1 = await createGroup({
id: groupData.json.id,
version: groupData.json.version
});
groupData = responses.groups.memberGroup;
var group2 = yield createGroup({
var group2 = await createGroup({
id: groupData.json.id,
version: groupData.json.version
});
setResponse('userGroups.groupVersions');
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json,
@ -286,7 +284,7 @@ describe("Zotero.Sync.Runner", function () {
assert.lengthOf(libraries, 1);
assert.sameMembers(libraries, [userLibraryID]);
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json,
@ -295,7 +293,7 @@ describe("Zotero.Sync.Runner", function () {
assert.lengthOf(libraries, 1);
assert.sameMembers(libraries, [userLibraryID]);
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json,
@ -305,7 +303,7 @@ describe("Zotero.Sync.Runner", function () {
assert.sameMembers(libraries, [group1.libraryID]);
})
it("should filter out nonexistent skipped libraries if library list not provided", function* () {
it("should filter out nonexistent skipped libraries if library list not provided", async function () {
var unskippedGroupID = responses.groups.ownerGroup.json.id;
var skippedGroupID = responses.groups.memberGroup.json.id;
Zotero.Prefs.set('sync.librariesToSkip', `["L4", "G${skippedGroupID}"]`);
@ -313,7 +311,7 @@ describe("Zotero.Sync.Runner", function () {
setResponse('userGroups.groupVersions');
setResponse('groups.ownerGroup');
setResponse('groups.memberGroup');
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json
@ -326,12 +324,12 @@ describe("Zotero.Sync.Runner", function () {
assert.isFalse(Zotero.Groups.get(skippedGroupID));
});
it("should filter out existing skipped libraries if library list not provided", function* () {
it("should filter out existing skipped libraries if library list not provided", async function () {
var unskippedGroupID = responses.groups.ownerGroup.json.id;
var skippedGroupID = responses.groups.memberGroup.json.id;
Zotero.Prefs.set('sync.librariesToSkip', `["L4", "G${skippedGroupID}"]`);
var skippedGroup = yield createGroup({
var skippedGroup = await createGroup({
id: skippedGroupID,
version: responses.groups.memberGroup.json.version - 1
});
@ -339,7 +337,7 @@ describe("Zotero.Sync.Runner", function () {
setResponse('userGroups.groupVersions');
setResponse('groups.ownerGroup');
setResponse('groups.memberGroup');
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json
@ -352,15 +350,15 @@ describe("Zotero.Sync.Runner", function () {
assert.equal(skippedGroup.version, responses.groups.memberGroup.json.version - 1);
});
it("should filter out remotely missing archived libraries if library list not provided", function* () {
it("should filter out remotely missing archived libraries if library list not provided", async function () {
var ownerGroupID = responses.groups.ownerGroup.json.id;
var archivedGroupID = 162512451; // nonexistent group id
var ownerGroup = yield createGroup({
var ownerGroup = await createGroup({
id: ownerGroupID,
version: responses.groups.ownerGroup.json.version
});
var archivedGroup = yield createGroup({
var archivedGroup = await createGroup({
id: archivedGroupID,
editable: false,
archived: true
@ -368,7 +366,7 @@ describe("Zotero.Sync.Runner", function () {
setResponse('userGroups.groupVersions');
setResponse('groups.memberGroup');
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json
@ -386,15 +384,15 @@ describe("Zotero.Sync.Runner", function () {
);
});
it("should unarchive library if available remotely", function* () {
it("should unarchive library if available remotely", async function () {
var syncedGroupID = responses.groups.ownerGroup.json.id;
var archivedGroupID = responses.groups.memberGroup.json.id;
var syncedGroup = yield createGroup({
var syncedGroup = await createGroup({
id: syncedGroupID,
version: responses.groups.ownerGroup.json.version
});
var archivedGroup = yield createGroup({
var archivedGroup = await createGroup({
id: archivedGroupID,
version: responses.groups.memberGroup.json.version - 1,
editable: false,
@ -404,7 +402,7 @@ describe("Zotero.Sync.Runner", function () {
setResponse('userGroups.groupVersions');
setResponse('groups.ownerGroup');
setResponse('groups.memberGroup');
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json
@ -418,9 +416,9 @@ describe("Zotero.Sync.Runner", function () {
assert.isFalse(archivedGroup.archived);
});
it("shouldn't filter out skipped libraries if library list is provided", function* () {
it("shouldn't filter out skipped libraries if library list is provided", async function () {
var groupData = responses.groups.memberGroup;
var group = yield createGroup({
var group = await createGroup({
id: groupData.json.id,
version: groupData.json.version
});
@ -430,7 +428,7 @@ describe("Zotero.Sync.Runner", function () {
setResponse('userGroups.groupVersions');
setResponse('groups.ownerGroup');
setResponse('groups.memberGroup');
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json,
@ -441,16 +439,16 @@ describe("Zotero.Sync.Runner", function () {
assert.sameMembers(libraries, [userLibraryID, group.libraryID]);
});
it("should update outdated group metadata", function* () {
it("should update outdated group metadata", async function () {
// Create groups with same id as groups response but earlier versions
var groupData1 = responses.groups.ownerGroup;
var group1 = yield createGroup({
var group1 = await createGroup({
id: groupData1.json.id,
version: groupData1.json.version - 1,
editable: false
});
var groupData2 = responses.groups.memberGroup;
var group2 = yield createGroup({
var group2 = await createGroup({
id: groupData2.json.id,
version: groupData2.json.version - 1,
editable: true
@ -461,9 +459,9 @@ describe("Zotero.Sync.Runner", function () {
setResponse('groups.memberGroup');
// Simulate acceptance of library reset for group 2 editable change
var stub = sinon.stub(Zotero.Sync.Data.Local, "checkLibraryForAccess")
.returns(Zotero.Promise.resolve(true));
.returns(Promise.resolve(true));
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }), false, responses.keyInfo.fullAccess.json
);
@ -483,24 +481,24 @@ describe("Zotero.Sync.Runner", function () {
assert.isFalse(group2.editable);
})
it("should update outdated group metadata for group created with classic sync", function* () {
it("should update outdated group metadata for group created with classic sync", async function () {
var groupData1 = responses.groups.ownerGroup;
var group1 = yield createGroup({
var group1 = await createGroup({
id: groupData1.json.id,
version: 0,
editable: false
});
var groupData2 = responses.groups.memberGroup;
var group2 = yield createGroup({
var group2 = await createGroup({
id: groupData2.json.id,
version: 0,
editable: true
});
yield Zotero.DB.queryAsync(
await Zotero.DB.queryAsync(
"UPDATE groups SET version=0 WHERE groupID IN (?, ?)", [group1.id, group2.id]
);
yield Zotero.Libraries.init();
await Zotero.Libraries.init();
group1 = Zotero.Groups.get(group1.id);
group2 = Zotero.Groups.get(group2.id);
@ -509,9 +507,9 @@ describe("Zotero.Sync.Runner", function () {
setResponse('groups.memberGroup');
// Simulate acceptance of library reset for group 2 editable change
var stub = sinon.stub(Zotero.Sync.Data.Local, "checkLibraryForAccess")
.returns(Zotero.Promise.resolve(true));
.returns(Promise.resolve(true));
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json,
@ -531,11 +529,11 @@ describe("Zotero.Sync.Runner", function () {
assert.isFalse(group2.editable);
})
it("should create locally missing groups", function* () {
it("should create locally missing groups", async function () {
setResponse('userGroups.groupVersions');
setResponse('groups.ownerGroup');
setResponse('groups.memberGroup');
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }), false, responses.keyInfo.fullAccess.json
);
assert.lengthOf(libraries, 3);
@ -555,18 +553,18 @@ describe("Zotero.Sync.Runner", function () {
assert.isFalse(group2.editable);
})
it("should delete remotely missing groups", function* () {
it("should delete remotely missing groups", async function () {
var groupData1 = responses.groups.ownerGroup;
var group1 = yield createGroup({ id: groupData1.json.id, version: groupData1.json.version });
var group1 = await createGroup({ id: groupData1.json.id, version: groupData1.json.version });
var groupData2 = responses.groups.memberGroup;
var group2 = yield createGroup({ id: groupData2.json.id, version: groupData2.json.version });
var group2 = await createGroup({ id: groupData2.json.id, version: groupData2.json.version });
setResponse('userGroups.groupVersionsOnlyMemberGroup');
waitForDialog(function (dialog) {
var text = dialog.document.documentElement.textContent;
assert.include(text, group1.name);
});
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }), false, responses.keyInfo.fullAccess.json
);
assert.lengthOf(libraries, 2);
@ -575,9 +573,9 @@ describe("Zotero.Sync.Runner", function () {
assert.isTrue(Zotero.Groups.exists(groupData2.json.id));
})
it("should keep remotely missing groups", function* () {
var group1 = yield createGroup({ editable: true, filesEditable: true });
var group2 = yield createGroup({ editable: true, filesEditable: true });
it("should keep remotely missing groups", async function () {
var group1 = await createGroup({ editable: true, filesEditable: true });
var group2 = await createGroup({ editable: true, filesEditable: true });
setResponse('userGroups.groupVersionsEmpty');
var called = 0;
@ -601,7 +599,7 @@ describe("Zotero.Sync.Runner", function () {
assert.include(text, otherGroup.name);
}, "extra1");
}, "extra1");
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }), false, responses.keyInfo.fullAccess.json
);
assert.equal(called, 2);
@ -616,24 +614,24 @@ describe("Zotero.Sync.Runner", function () {
});
})
it("should cancel sync with remotely missing groups", function* () {
it("should cancel sync with remotely missing groups", async function () {
var groupData = responses.groups.ownerGroup;
var group = yield createGroup({ id: groupData.json.id, version: groupData.json.version });
var group = await createGroup({ id: groupData.json.id, version: groupData.json.version });
setResponse('userGroups.groupVersionsEmpty');
waitForDialog(function (dialog) {
var text = dialog.document.documentElement.textContent;
assert.include(text, group.name);
}, "cancel");
var libraries = yield runner.checkLibraries(
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }), false, responses.keyInfo.fullAccess.json
);
assert.lengthOf(libraries, 0);
assert.isTrue(Zotero.Groups.exists(groupData.json.id));
})
it("should prompt to revert local changes on loss of library write access", function* () {
var group = yield createGroup({
it("should prompt to revert local changes on loss of library write access", async function () {
var group = await createGroup({
version: 1,
libraryVersion: 2
});
@ -679,8 +677,8 @@ describe("Zotero.Sync.Runner", function () {
// First, test cancelling
var stub = sinon.stub(Zotero.Sync.Data.Local, "checkLibraryForAccess")
.returns(Zotero.Promise.resolve(false));
var libraries = yield runner.checkLibraries(
.returns(Promise.resolve(false));
var libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }), false, responses.keyInfo.fullAccess.json
);
assert.notInclude(libraries, group.libraryID);
@ -689,8 +687,8 @@ describe("Zotero.Sync.Runner", function () {
stub.reset();
// Next, reset
stub.returns(Zotero.Promise.resolve(true));
libraries = yield runner.checkLibraries(
stub.returns(Promise.resolve(true));
libraries = await runner.checkLibraries(
runner.getAPIClient({ apiKey }), false, responses.keyInfo.fullAccess.json
);
assert.include(libraries, group.libraryID);
@ -702,7 +700,7 @@ describe("Zotero.Sync.Runner", function () {
})
describe("#sync()", function () {
it("should perform a sync across all libraries and update library versions", function* () {
it("should perform a sync across all libraries and update library versions", async function () {
setResponse('keyInfo.fullAccess');
setResponse('userGroups.groupVersions');
setResponse('groups.ownerGroup');
@ -903,7 +901,7 @@ describe("Zotero.Sync.Runner", function () {
var startTime = new Date().getTime();
yield runner.sync({
await runner.sync({
onError: e => { throw e },
});
@ -928,7 +926,7 @@ describe("Zotero.Sync.Runner", function () {
})
it("should handle user-initiated cancellation", function* () {
it("should handle user-initiated cancellation", async function () {
setResponse('keyInfo.fullAccess');
setResponse('userGroups.groupVersions');
setResponse('groups.ownerGroup');
@ -936,14 +934,14 @@ describe("Zotero.Sync.Runner", function () {
var stub = sinon.stub(Zotero.Sync.Data.Engine.prototype, "start");
stub.onCall(0).returns(Zotero.Promise.resolve());
stub.onCall(0).returns(Promise.resolve());
var e = new Zotero.Sync.UserCancelledException();
e.handledRejection = true;
stub.onCall(1).returns(Zotero.Promise.reject(e));
stub.onCall(1).returns(Promise.reject(e));
// Shouldn't be reached
stub.onCall(2).throws();
yield runner.sync({
await runner.sync({
onError: e => { throw e },
});
@ -951,7 +949,7 @@ describe("Zotero.Sync.Runner", function () {
});
it("should handle user-initiated cancellation for current library", function* () {
it("should handle user-initiated cancellation for current library", async function () {
setResponse('keyInfo.fullAccess');
setResponse('userGroups.groupVersions');
setResponse('groups.ownerGroup');
@ -959,12 +957,12 @@ describe("Zotero.Sync.Runner", function () {
var stub = sinon.stub(Zotero.Sync.Data.Engine.prototype, "start");
stub.returns(Zotero.Promise.resolve());
stub.returns(Promise.resolve());
var e = new Zotero.Sync.UserCancelledException(true);
e.handledRejection = true;
stub.onCall(1).returns(Zotero.Promise.reject(e));
stub.onCall(1).returns(Promise.reject(e));
yield runner.sync({
await runner.sync({
onError: e => { throw e },
});
@ -974,7 +972,7 @@ describe("Zotero.Sync.Runner", function () {
})
describe("#createAPIKeyFromCredentials()", function() {
describe("#createAPIKeyFromCredentials()", function () {
var data = {
name: "Automatic Zotero Client Key",
username: "Username",
@ -997,7 +995,7 @@ describe("Zotero.Sync.Runner", function () {
var incorrectPostData = Object.assign({password: 'incorrectPassword'}, data);
var responseData = Object.assign({userID: 1, key: apiKey}, data);
it("should return json with key when credentials valid", function* () {
it("should return json with key when credentials valid", async function () {
server.respond(function (req) {
if (req.method == "POST") {
var json = JSON.parse(req.requestBody);
@ -1006,11 +1004,11 @@ describe("Zotero.Sync.Runner", function () {
}
});
var json = yield runner.createAPIKeyFromCredentials('Username', 'correctPassword');
var json = await runner.createAPIKeyFromCredentials('Username', 'correctPassword');
assert.equal(json.key, apiKey);
});
it("should return false when credentials invalid", function* () {
it("should return false when credentials invalid", async function () {
server.respond(function (req) {
if (req.method == "POST") {
var json = JSON.parse(req.requestBody);
@ -1019,13 +1017,13 @@ describe("Zotero.Sync.Runner", function () {
}
});
var key = yield runner.createAPIKeyFromCredentials('Username', 'incorrectPassword');
var key = await runner.createAPIKeyFromCredentials('Username', 'incorrectPassword');
assert.isFalse(key);
});
});
describe("#deleteAPIKey()", function() {
it("should send DELETE request with correct key", function* (){
describe("#deleteAPIKey()", function () {
it("should send DELETE request with correct key", async function () {
Zotero.Sync.Data.Local.setAPIKey(apiKey);
server.respond(function (req) {
@ -1036,7 +1034,7 @@ describe("Zotero.Sync.Runner", function () {
req.respond(204);
});
yield runner.deleteAPIKey();
await runner.deleteAPIKey();
});
});
@ -1071,8 +1069,8 @@ describe("Zotero.Sync.Runner", function () {
});
it("should show a custom button in the error panel", function* () {
win = yield loadZoteroPane();
it("should show a custom button in the error panel", async function () {
win = await loadZoteroPane();
var libraryID = Zotero.Libraries.userLibraryID;
setResponse({
@ -1082,7 +1080,7 @@ describe("Zotero.Sync.Runner", function () {
headers: {},
text: "Invalid Key"
});
yield runner.sync({
await runner.sync({
background: true
});
@ -1097,12 +1095,12 @@ describe("Zotero.Sync.Runner", function () {
});
it("should show a button in error panel to select a too-long note", function* () {
win = yield loadZoteroPane();
it("should show a button in error panel to select a too-long note", async function () {
win = await loadZoteroPane();
var doc = win.document;
var text = "".padStart(256, "a");
var item = yield createDataObject('item', { itemType: 'note', note: text });
var item = await createDataObject('item', { itemType: 'note', note: text });
setResponse('keyInfo.fullAccess');
setResponse('userGroups.groupVersions');
@ -1131,7 +1129,7 @@ describe("Zotero.Sync.Runner", function () {
}
});
yield runner.sync({ libraries: [Zotero.Libraries.userLibraryID] });
await runner.sync({ libraries: [Zotero.Libraries.userLibraryID] });
var errorIcon = doc.getElementById('zotero-tb-sync-error');
assert.isFalse(errorIcon.hidden);
@ -1258,13 +1256,13 @@ describe("Zotero.Sync.Runner", function () {
// TODO: Test multiple long tags and tags across libraries
describe("Long Tag Fixer", function () {
it("should split a tag", function* () {
win = yield loadZoteroPane();
it("should split a tag", async function () {
win = await loadZoteroPane();
var item = yield createDataObject('item');
var item = await createDataObject('item');
var tag = "title;feeling;matter;drum;treatment;caring;earthy;shrill;unit;obedient;hover;healthy;cheap;clever;wren;wicked;clip;shoe;jittery;shape;clear;dime;increase;complete;level;milk;false;infamous;lamentable;measure;cuddly;tasteless;peace;top;pencil;caption;unusual;depressed;frantic";
item.addTag(tag, 1);
yield item.saveTx();
await item.saveTx();
setResponse('keyInfo.fullAccess');
setResponse('userGroups.groupVersions');
@ -1322,19 +1320,19 @@ describe("Zotero.Sync.Runner", function () {
});
waitForDialog(null, 'accept', 'chrome://zotero/content/longTagFixer.xhtml');
yield runner.sync({ libraries: [Zotero.Libraries.userLibraryID] });
await runner.sync({ libraries: [Zotero.Libraries.userLibraryID] });
assert.isFalse(Zotero.Tags.getID(tag));
assert.isNumber(Zotero.Tags.getID('feeling'));
});
it("should delete a tag", function* () {
win = yield loadZoteroPane();
it("should delete a tag", async function () {
win = await loadZoteroPane();
var item = yield createDataObject('item');
var item = await createDataObject('item');
var tag = "title;feeling;matter;drum;treatment;caring;earthy;shrill;unit;obedient;hover;healthy;cheap;clever;wren;wicked;clip;shoe;jittery;shape;clear;dime;increase;complete;level;milk;false;infamous;lamentable;measure;cuddly;tasteless;peace;top;pencil;caption;unusual;depressed;frantic";
item.addTag(tag, 1);
yield item.saveTx();
await item.saveTx();
setResponse('keyInfo.fullAccess');
setResponse('userGroups.groupVersions');
@ -1394,7 +1392,7 @@ describe("Zotero.Sync.Runner", function () {
waitForDialog(function (window) {
window.Zotero_Long_Tag_Fixer.switchMode(2);
}, 'accept', 'chrome://zotero/content/longTagFixer.xhtml');
yield runner.sync({ libraries: [Zotero.Libraries.userLibraryID] });
await runner.sync({ libraries: [Zotero.Libraries.userLibraryID] });
assert.isFalse(Zotero.Tags.getID(tag));
assert.isFalse(Zotero.Tags.getID('feeling'));

View file

@ -1,7 +1,7 @@
describe('Zotero.SyncedSettings', function() {
it('should not affect cached value when modifying the setting after #set() call', function* () {
describe('Zotero.SyncedSettings', function () {
it('should not affect cached value when modifying the setting after #set() call', async function () {
let setting = {athing: 1};
yield Zotero.SyncedSettings.set(Zotero.Libraries.userLibraryID, 'setting', setting);
await Zotero.SyncedSettings.set(Zotero.Libraries.userLibraryID, 'setting', setting);
setting.athing = 2;
let storedSetting = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'setting');

View file

@ -3,12 +3,12 @@
describe("Tag Selector", function () {
var libraryID, win, doc, collectionsView, tagSelectorElem, tagSelector;
var clearTagColors = Zotero.Promise.coroutine(function* (libraryID) {
var clearTagColors = async function (libraryID) {
var tagColors = Zotero.Tags.getColors(libraryID);
for (let name of tagColors.keys()) {
yield Zotero.Tags.setColor(libraryID, name, false);
await Zotero.Tags.setColor(libraryID, name, false);
}
});
};
function getColoredTags() {
return [...getColoredTagElements()].map(elem => elem.textContent);
@ -114,35 +114,35 @@ describe("Tag Selector", function () {
});
describe("#handleSearch()", function () {
it("should filter to tags matching the search", function* () {
var collection = yield createDataObject('collection');
yield select(win, collection);
it("should filter to tags matching the search", async function () {
var collection = await createDataObject('collection');
await select(win, collection);
var item = createUnsavedDataObject('item', { collections: [collection.id] });
item.setTags(['a', 'b', 'c']);
var promise = waitForTagSelector(win);
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
promise = waitForTagSelector(win);
tagSelector.handleSearch('a');
yield Zotero.Promise.delay(500);
await Zotero.Promise.delay(500);
yield promise;
await promise;
var tags = getRegularTags();
assert.sameMembers(tags, ['a']);
tagSelector.handleSearch('');
yield Zotero.Promise.delay(500);
await Zotero.Promise.delay(500);
yield item.eraseTx();
await item.eraseTx();
});
});
describe("#handleTagSelected()", function () {
it("should remove tags not on matching items on tag click", function* () {
var collection = yield createDataObject('collection');
yield select(win, collection);
it("should remove tags not on matching items on tag click", async function () {
var collection = await createDataObject('collection');
await select(win, collection);
var item1 = createUnsavedDataObject('item', { collections: [collection.id] });
item1.setTags([
{
@ -165,15 +165,15 @@ describe("Tag Selector", function () {
}
]);
var promise = waitForTagSelector(win);
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
await item1.save();
await item2.save();
await item3.save();
});
yield promise;
await promise;
tagSelector.handleTagSelected('A');
yield waitForTagSelector(win);
await waitForTagSelector(win);
var tags = getRegularTags();
assert.sameMembers(tags, ['A', 'B']);
@ -182,15 +182,15 @@ describe("Tag Selector", function () {
describe("#displayAllTags", function () {
it("should show all tags in library when true", function* () {
it("should show all tags in library when true", async function () {
tagSelector.displayAllTags = true;
var tag1 = 'A ' + Zotero.Utilities.randomString();
var tag2 = 'B ' + Zotero.Utilities.randomString();
var tag3 = 'C ' + Zotero.Utilities.randomString();
var collection = yield createDataObject('collection');
yield select(win, collection);
var collection = await createDataObject('collection');
await select(win, collection);
var item1 = createUnsavedDataObject('item');
item1.setTags([tag1]);
var item2 = createUnsavedDataObject('item', { collections: [collection.id] });
@ -198,12 +198,12 @@ describe("Tag Selector", function () {
var item3 = createUnsavedDataObject('item', { collections: [collection.id] });
item3.setTags([tag3]);
var promise = waitForTagSelector(win);
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
await item1.save();
await item2.save();
await item3.save();
});
yield promise;
await promise;
var tags = getRegularTags();
assert.includeMembers(tags, [tag1, tag2, tag3]);
@ -264,14 +264,14 @@ describe("Tag Selector", function () {
assert.isBelow(tags.indexOf(tag2), tags.indexOf(tag3));
});
it("should add a tag when an item is added in a collection", function* () {
it("should add a tag when an item is added in a collection", async function () {
var promise, tagSelector;
// Add collection
promise = waitForTagSelector(win);
var collection = yield createDataObject('collection');
yield select(win, collection);
yield promise;
var collection = await createDataObject('collection');
await select(win, collection);
await promise;
// Tag selector should be empty in new collection
assert.equal(getRegularTags().length, 0);
@ -285,8 +285,8 @@ describe("Tag Selector", function () {
]);
item.setCollections([collection.id]);
promise = waitForTagSelector(win)
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
// Tag selector should show the new item's tag
assert.equal(getRegularTags().length, 1);
@ -399,13 +399,13 @@ describe("Tag Selector", function () {
assert.isTrue(elems[2].classList.contains('disabled'));
});
it("should add a tag when an item is added to a collection", function* () {
it("should add a tag when an item is added to a collection", async function () {
var promise, tagSelector;
// Add collection
var collection = yield createDataObject('collection');
yield select(win, collection);
yield waitForTagSelector(win);
var collection = await createDataObject('collection');
await select(win, collection);
await waitForTagSelector(win);
// Tag selector should be empty in new collection
assert.equal(getRegularTags().length, 0);
@ -417,35 +417,35 @@ describe("Tag Selector", function () {
tag: 'C'
}
]);
yield item.saveTx();
await item.saveTx();
// Tag selector should still be empty in collection
assert.equal(getRegularTags().length, 0);
item.setCollections([collection.id]);
promise = waitForTagSelector(win);
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
// Tag selector should show the new item's tag
assert.equal(getRegularTags().length, 1);
})
it("should show a colored tag at the top of the list even when linked to no items", function* () {
it("should show a colored tag at the top of the list even when linked to no items", async function () {
var tagElems = tagSelectorElem.querySelectorAll('.tag-selector-item');
var count = tagElems.length;
yield Zotero.Tags.setColor(libraryID, "Top", '#AAAAAA');
yield waitForTagSelector(win);
await Zotero.Tags.setColor(libraryID, "Top", '#AAAAAA');
await waitForTagSelector(win);
tagElems = tagSelectorElem.querySelectorAll('.tag-selector-item');
assert.equal(tagElems.length, count + 1);
});
it("shouldn't re-insert a new tag that matches an existing color", function* () {
it("shouldn't re-insert a new tag that matches an existing color", async function () {
// Add A and B as colored tags without any items
yield Zotero.Tags.setColor(libraryID, "A", '#CC9933', 1);
yield Zotero.Tags.setColor(libraryID, "B", '#990000', 2);
await Zotero.Tags.setColor(libraryID, "A", '#CC9933', 1);
await Zotero.Tags.setColor(libraryID, "B", '#990000', 2);
// Add A to an item to make it a real tag
var item = createUnsavedDataObject('item');
@ -455,8 +455,8 @@ describe("Tag Selector", function () {
}
]);
var promise = waitForTagSelector(win);
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
var tagElems = tagSelectorElem.querySelectorAll('.tag-selector-item');
@ -468,12 +468,12 @@ describe("Tag Selector", function () {
assert.isAbove(tags.get("B"), tags.get("A"));
})
it("should remove a tag when an item is removed from a collection", function* () {
it("should remove a tag when an item is removed from a collection", async function () {
// Add collection
var promise = waitForTagSelector(win);
var collection = yield createDataObject('collection');
yield select(win, collection);
yield promise;
var collection = await createDataObject('collection');
await select(win, collection);
await promise;
// Add item with tag to collection
var item = createUnsavedDataObject('item');
@ -484,27 +484,27 @@ describe("Tag Selector", function () {
]);
item.setCollections([collection.id]);
promise = waitForTagSelector(win);
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
// Tag selector should show the new item's tag
assert.equal(getRegularTags().length, 1);
item.setCollections();
promise = waitForTagSelector(win);
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
// Tag selector shouldn't show the removed item's tag
assert.equal(getRegularTags().length, 0);
})
it("should remove a tag when an item in a collection is moved to the trash", function* () {
it("should remove a tag when an item in a collection is moved to the trash", async function () {
// Add collection
var promise = waitForTagSelector(win);
var collection = yield createDataObject('collection');
yield select(win, collection);
yield promise;
var collection = await createDataObject('collection');
await select(win, collection);
await promise;
// Add item with tag to collection
var item = createUnsavedDataObject('item');
@ -515,8 +515,8 @@ describe("Tag Selector", function () {
]);
item.setCollections([collection.id]);
promise = waitForTagSelector(win)
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
// Tag selector should show the new item's tag
assert.equal(getRegularTags().length, 1);
@ -524,8 +524,8 @@ describe("Tag Selector", function () {
// Move item to trash
item.deleted = true;
promise = waitForTagSelector(win);
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
// Tag selector shouldn't show the deleted item's tag
assert.equal(getRegularTags().length, 0);
@ -569,8 +569,8 @@ describe("Tag Selector", function () {
assert.isTrue(elems[tags.indexOf(tag)].classList.contains('disabled'));
});
it("should remove a tag when a tag is deleted for a library", function* () {
yield selectLibrary(win);
it("should remove a tag when a tag is deleted for a library", async function () {
await selectLibrary(win);
var item = createUnsavedDataObject('item');
item.setTags([
@ -579,8 +579,8 @@ describe("Tag Selector", function () {
}
]);
var promise = waitForTagSelector(win);
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
// Tag selector should show the new tag
assert.include(getRegularTags(), "A");
@ -589,8 +589,8 @@ describe("Tag Selector", function () {
promise = waitForTagSelector(win);
waitForDialog();
tagSelector.contextTag = {name: "A"};
yield tagSelector.openDeletePrompt();
yield promise;
await tagSelector.openDeletePrompt();
await promise;
// Tag selector shouldn't show the deleted tag
assert.notInclude(getRegularTags(), "A");
@ -667,8 +667,8 @@ describe("Tag Selector", function () {
});
describe("#openRenamePrompt", function () {
it("should rename a tag and update the tag selector", function* () {
yield selectLibrary(win);
it("should rename a tag and update the tag selector", async function () {
await selectLibrary(win);
var tag = Zotero.Utilities.randomString();
var newTag = Zotero.Utilities.randomString();
@ -679,8 +679,8 @@ describe("Tag Selector", function () {
}
]);
var promise = waitForTagSelector(win);
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
promise = waitForTagSelector(win);
var promptPromise = waitForDialog(function (dialogWindow, dialog) {
@ -688,31 +688,31 @@ describe("Tag Selector", function () {
dialog.acceptDialog();
})
tagSelector.contextTag = {name: tag};
yield tagSelector.openRenamePrompt();
yield promise;
yield promptPromise;
await tagSelector.openRenamePrompt();
await promise;
await promptPromise;
var tags = getRegularTags();
assert.include(tags, newTag);
});
it("should rename a non-matching colored tag and update the tag selector", function* () {
yield selectLibrary(win);
it("should rename a non-matching colored tag and update the tag selector", async function () {
await selectLibrary(win);
var oldTag = Zotero.Utilities.randomString();
var newTag = Zotero.Utilities.randomString();
var promise = waitForTagSelector(win);
yield Zotero.Tags.setColor(libraryID, oldTag, "#F3F3F3");
yield promise;
await Zotero.Tags.setColor(libraryID, oldTag, "#F3F3F3");
await promise;
waitForDialog(function (dialogWindow, dialog) {
dialogWindow.document.getElementById('loginTextbox').value = newTag;
dialog.acceptDialog();
});
tagSelector.contextTag = {name: oldTag};
yield tagSelector.openRenamePrompt();
yield waitForTagSelector(win);;
await tagSelector.openRenamePrompt();
await waitForTagSelector(win);;
var tags = getColoredTags();
assert.notInclude(tags, oldTag);
@ -721,8 +721,8 @@ describe("Tag Selector", function () {
})
describe("#openColorPickerWindow()", function () {
it("should assign a color to a tag", function* () {
yield selectLibrary(win);
it("should assign a color to a tag", async function () {
await selectLibrary(win);
var tag = "b " + Zotero.Utilities.randomString();
var item = createUnsavedDataObject('item');
item.setTags([
@ -734,8 +734,8 @@ describe("Tag Selector", function () {
}
]);
var promise = waitForTagSelector(win);
yield item.saveTx();
yield promise;
await item.saveTx();
await promise;
assert.include(getRegularTags(), "a");
@ -743,17 +743,17 @@ describe("Tag Selector", function () {
var dialogPromise = waitForDialog(false, undefined, 'chrome://zotero/content/tagColorChooser.xhtml');
var tagSelectorPromise = waitForTagSelector(win);
tagSelector.contextTag = {name: tag};
yield tagSelector.openColorPickerWindow();
yield dialogPromise;
yield tagSelectorPromise;
await tagSelector.openColorPickerWindow();
await dialogPromise;
await tagSelectorPromise;
assert.include(getColoredTags(), tag);
assert.notInclude(getRegularTags(), tag);
})
});
describe("#deleteAutomatic()", function() {
it('should delete automatic tags', async function() {
describe("#deleteAutomatic()", function () {
it('should delete automatic tags', async function () {
await selectLibrary(win);
var item = createUnsavedDataObject('item');
item.setTags([

View file

@ -2,22 +2,22 @@
describe("Zotero.Tags", function () {
describe("#getID()", function () {
it("should return tag id", function* () {
it("should return tag id", async function () {
var tagName = Zotero.Utilities.randomString();
var item = createUnsavedDataObject('item');
item.addTag(tagName);
yield item.saveTx();
await item.saveTx();
assert.typeOf(Zotero.Tags.getID(tagName), "number");
})
})
describe("#getName()", function () {
it("should return tag id", function* () {
it("should return tag id", async function () {
var tagName = Zotero.Utilities.randomString();
var item = createUnsavedDataObject('item');
item.addTag(tagName);
yield item.saveTx();
await item.saveTx();
var libraryID = Zotero.Libraries.userLibraryID;
var tagID = Zotero.Tags.getID(tagName);
@ -26,12 +26,12 @@ describe("Zotero.Tags", function () {
})
describe("#rename()", function () {
it("should mark items as changed", function* () {
var item1 = yield createDataObject('item', { tags: [{ tag: "A" }], synced: true });
var item2 = yield createDataObject('item', { tags: [{ tag: "A" }, { tag: "B" }], synced: true });
var item3 = yield createDataObject('item', { tags: [{ tag: "B" }, { tag: "C" }], synced: true });
it("should mark items as changed", async function () {
var item1 = await createDataObject('item', { tags: [{ tag: "A" }], synced: true });
var item2 = await createDataObject('item', { tags: [{ tag: "A" }, { tag: "B" }], synced: true });
var item3 = await createDataObject('item', { tags: [{ tag: "B" }, { tag: "C" }], synced: true });
yield Zotero.Tags.rename(item1.libraryID, "A", "D");
await Zotero.Tags.rename(item1.libraryID, "A", "D");
assert.isFalse(item1.synced);
assert.isFalse(item2.synced);
assert.isTrue(item3.synced);
@ -127,22 +127,22 @@ describe("Zotero.Tags", function () {
})
describe("#purge()", function () {
it("should remove orphaned tags", function* () {
it("should remove orphaned tags", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var tagName = Zotero.Utilities.randomString();
var item = createUnsavedDataObject('item');
item.addTag(tagName);
yield item.saveTx();
await item.saveTx();
var tagID = Zotero.Tags.getID(tagName);
assert.typeOf(tagID, "number");
yield item.eraseTx();
await item.eraseTx();
assert.equal(Zotero.Tags.getName(tagID), tagName);
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
await Zotero.Tags.purge();
});
@ -164,11 +164,11 @@ describe("Zotero.Tags", function () {
}
});
it("should set color for a tag", function* () {
it("should set color for a tag", async function () {
var aColor = '#ABCDEF';
var bColor = '#BCDEF0';
yield Zotero.Tags.setColor(libraryID, "A", aColor);
yield Zotero.Tags.setColor(libraryID, "B", bColor);
await Zotero.Tags.setColor(libraryID, "A", aColor);
await Zotero.Tags.setColor(libraryID, "B", bColor);
var o = Zotero.Tags.getColor(libraryID, "A")
assert.equal(o.color, aColor);
@ -183,14 +183,14 @@ describe("Zotero.Tags", function () {
assert.sameMembers(o.map(c => c.color), [aColor, bColor]);
});
it("should clear color for a tag", function* () {
it("should clear color for a tag", async function () {
var aColor = '#ABCDEF';
yield Zotero.Tags.setColor(libraryID, "A", aColor);
await Zotero.Tags.setColor(libraryID, "A", aColor);
var o = Zotero.Tags.getColor(libraryID, "A")
assert.equal(o.color, aColor);
assert.equal(o.position, 0);
yield Zotero.Tags.setColor(libraryID, "A", false);
await Zotero.Tags.setColor(libraryID, "A", false);
assert.equal(Zotero.Tags.getColors(libraryID).size, 0);
assert.isFalse(Zotero.Tags.getColor(libraryID, "A"));

View file

@ -125,7 +125,7 @@ describe("Item Tags Box", function () {
describe("#notify()", function () {
it("should update an existing tag on rename", function* () {
it("should update an existing tag on rename", async function () {
var tag = Zotero.Utilities.randomString();
var newTag = Zotero.Utilities.randomString();
@ -135,25 +135,25 @@ describe("Item Tags Box", function () {
tag: tag
}
]);
yield item.saveTx();
await item.saveTx();
var tagsbox = doc.querySelector('#zotero-editpane-tags');
var rows = tagsbox.querySelectorAll('.row');
assert.equal(rows.length, 1);
assert.equal(rows[0].querySelector("editable-text").value, tag);
yield Zotero.Tags.rename(Zotero.Libraries.userLibraryID, tag, newTag);
await Zotero.Tags.rename(Zotero.Libraries.userLibraryID, tag, newTag);
rows = tagsbox.querySelectorAll('.row');
assert.equal(rows.length, 1);
assert.equal(rows[0].querySelector("editable-text").value, newTag);
})
it("should update when a tag's color is removed", function* () {
it("should update when a tag's color is removed", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var tag = Zotero.Utilities.randomString();
yield Zotero.Tags.setColor(libraryID, tag, "#990000");
await Zotero.Tags.setColor(libraryID, tag, "#990000");
var item = createUnsavedDataObject('item');
item.setTags([
{
@ -163,7 +163,7 @@ describe("Item Tags Box", function () {
tag: "_A"
}
]);
yield item.saveTx();
await item.saveTx();
var tagsbox = doc.querySelector('#zotero-editpane-tags');
var rows = tagsbox.querySelectorAll('.row');
@ -175,7 +175,7 @@ describe("Item Tags Box", function () {
assert.notOk(getComputedStyle(rows[1]).getPropertyValue('--tag-color'));
assert.equal(rows[1].querySelector("editable-text").value, "_A");
yield Zotero.Tags.setColor(libraryID, tag, false);
await Zotero.Tags.setColor(libraryID, tag, false);
// No color remains on the tag
rows = tagsbox.querySelectorAll('.row');
@ -183,7 +183,7 @@ describe("Item Tags Box", function () {
assert.notOk(getComputedStyle(rows[1]).getPropertyValue('--tag-color'));
})
it("should update when a tag is removed from the library", function* () {
it("should update when a tag is removed from the library", async function () {
var tag = Zotero.Utilities.randomString();
var item = createUnsavedDataObject('item');
@ -192,22 +192,22 @@ describe("Item Tags Box", function () {
tag: tag
}
]);
yield item.saveTx();
await item.saveTx();
var tagsbox = doc.querySelector('#zotero-editpane-tags');
var rows = tagsbox.querySelectorAll('.row');
assert.equal(rows.length, 1);
assert.equal(rows[0].querySelector("editable-text").value, tag);
yield Zotero.Tags.removeFromLibrary(Zotero.Libraries.userLibraryID, Zotero.Tags.getID(tag));
await Zotero.Tags.removeFromLibrary(Zotero.Libraries.userLibraryID, Zotero.Tags.getID(tag));
rows = tagsbox.querySelectorAll('.row');
assert.equal(rows.length, 0);
})
})
describe("#render", function() {
it("should render colored tags followed by emoji tags followed by ordinary tags", async function() {
describe("#render", function () {
it("should render colored tags followed by emoji tags followed by ordinary tags", async function () {
let item = await createDataObject('item', {
tags: [
{ tag: 'A_usual_tag' },

View file

@ -1,4 +1,4 @@
new function() {
new function () {
var { HttpServer } = ChromeUtils.importESModule("chrome://remote/content/server/httpd.sys.mjs");;
const { HiddenBrowser } = ChromeUtils.importESModule('chrome://zotero/content/HiddenBrowser.mjs');
@ -37,7 +37,7 @@ function saveItemsThroughTranslator(translatorType, items, translateOptions = {}
" item.complete();\n"+
" }\n"+
"}"));
return translate.translate(translateOptions).then(function(items) {
return translate.translate(translateOptions).then(function (items) {
return items;
});
}
@ -102,31 +102,31 @@ function getTestPDF() {
* restarted by resetDB(), which would erase our registered endpoints.
*/
function setupAttachmentEndpoints() {
var SnapshotTest = function() {};
var SnapshotTest = function () {};
Zotero.Server.Endpoints["/test/translate/test.html"] = SnapshotTest;
SnapshotTest.prototype = {
"supportedMethods":["GET"],
"init":function(data, sendResponseCallback) {
"init":function (data, sendResponseCallback) {
Zotero.File.getBinaryContentsAsync(getTestSnapshot()).then(function (data) {
sendResponseCallback(200, "text/html", data);
});
}
}
var PDFTest = function() {};
var PDFTest = function () {};
Zotero.Server.Endpoints["/test/translate/test.pdf"] = PDFTest;
PDFTest.prototype = {
"supportedMethods":["GET"],
"init":function(data, sendResponseCallback) {
"init":function (data, sendResponseCallback) {
Zotero.File.getBinaryContentsAsync(getTestPDF()).then(function (data) {
sendResponseCallback(200, "application/pdf", data);
});
}
}
var NonExistentTest = function() {};
var NonExistentTest = function () {};
Zotero.Server.Endpoints["/test/translate/does_not_exist.html"] = NonExistentTest;
NonExistentTest.prototype = {
"supportedMethods":["GET"],
"init":function(data, sendResponseCallback) {
"init":function (data, sendResponseCallback) {
sendResponseCallback(404, "text/html", "File does not exist");
}
}
@ -141,7 +141,7 @@ function setupAsyncEndpoints() {
Zotero.Server.Endpoints["/test/translate/test.json"] = JSONTest;
JSONTest.prototype = {
"supportedMethods": ["GET"],
"init": function(data, sendResponseCallback) {
"init": function (data, sendResponseCallback) {
sendResponseCallback(200, "application/json", JSON.stringify({
success: true,
array: [1, 2, 3]
@ -150,7 +150,7 @@ function setupAsyncEndpoints() {
}
}
describe("Zotero.Translate", function() {
describe("Zotero.Translate", function () {
let serverURL
let htmlURL;
@ -165,8 +165,8 @@ describe("Zotero.Translate", function() {
setupAttachmentEndpoints();
});
describe("Zotero.Item", function() {
it('should save ordinary fields and creators', function* () {
describe("Zotero.Item", function () {
it('should save ordinary fields and creators', async function () {
this.timeout(10000);
let data = loadSampleData('allTypesAndFields');
let trueItems = loadSampleData('itemJSON');
@ -179,7 +179,7 @@ describe("Zotero.Translate", function() {
delete trueItem.key;
}
let newItems = yield saveItemsThroughTranslator("import", saveItems);
let newItems = await saveItemsThroughTranslator("import", saveItems);
let savedItems = {};
for (let i=0; i<newItems.length; i++) {
let savedItem = newItems[i].toJSON();
@ -227,26 +227,26 @@ describe("Zotero.Translate", function() {
}
});
it('should accept deprecated SQL accessDates', function* () {
it('should accept deprecated SQL accessDates', async function () {
let myItem = {
"itemType":"webpage",
"title":"Test Item",
"accessDate":"2015-01-02 03:04:05"
}
let newItems = yield saveItemsThroughTranslator("import", [myItem]);
let newItems = await saveItemsThroughTranslator("import", [myItem]);
assert.equal(newItems[0].getField("accessDate"), "2015-01-02 03:04:05");
});
it('should save tags', function* () {
it('should save tags', async function () {
let myItem = {
"itemType":"book",
"title":"Test Item",
"tags":TEST_TAGS
};
checkTestTags((yield saveItemsThroughTranslator("import", [myItem]))[0]);
checkTestTags(((await saveItemsThroughTranslator("import", [myItem])))[0]);
});
it('should save notes', function* () {
it('should save notes', async function () {
let myItems = [
{
"itemType":"book",
@ -266,12 +266,12 @@ describe("Zotero.Translate", function() {
}
];
let newItems = itemsArrayToObject(yield saveItemsThroughTranslator("import", myItems));
let newItems = itemsArrayToObject(await saveItemsThroughTranslator("import", myItems));
let noteIDs = newItems["Test Item"].getNotes();
let note1 = yield Zotero.Items.getAsync(noteIDs[0]);
let note1 = await Zotero.Items.getAsync(noteIDs[0]);
assert.equal(Zotero.ItemTypes.getName(note1.itemTypeID), "note");
assert.equal(note1.note, "1 note as string");
let note2 = yield Zotero.Items.getAsync(noteIDs[1]);
let note2 = await Zotero.Items.getAsync(noteIDs[1]);
assert.equal(Zotero.ItemTypes.getName(note2.itemTypeID), "note");
assert.equal(note2.note, "2 note as object");
checkTestTags(note2);
@ -297,7 +297,7 @@ describe("Zotero.Translate", function() {
assert.equal(relations["dc:relation"][0], itemURI);
});
it('should save collections', function* () {
it('should save collections', async function () {
let translate = new Zotero.Translate.Import();
translate.setString("");
translate.setTranslator(buildDummyTranslator(4,
@ -319,27 +319,27 @@ describe("Zotero.Translate", function() {
' collection.children = [{"id":1}, {"type":"collection", "name":"Child Collection", "children":[{"id":2}]}];\n'+
' collection.complete();\n'+
'}'));
let newItems = yield translate.translate();
let newItems = await translate.translate();
assert.equal(newItems.length, 3);
newItems = itemsArrayToObject(newItems);
assert.equal(newItems["Not in Collection"].getCollections().length, 0);
let parentCollection = newItems["In Parent Collection"].getCollections();
assert.equal(parentCollection.length, 1);
parentCollection = (yield Zotero.Collections.getAsync(parentCollection))[0];
parentCollection = ((await Zotero.Collections.getAsync(parentCollection)))[0];
assert.equal(parentCollection.name, "Parent Collection");
assert.isTrue(parentCollection.hasChildCollections());
let childCollection = newItems["In Child Collection"].getCollections();
assert.equal(childCollection.length, 1);
childCollection = (yield Zotero.Collections.getAsync(childCollection[0]));
childCollection = ((await Zotero.Collections.getAsync(childCollection[0])));
assert.equal(childCollection.name, "Child Collection");
let parentChildren = parentCollection.getChildCollections();
assert.equal(parentChildren.length, 1);
assert.equal(parentChildren[0], childCollection);
});
it('import translators should save attachments', function* () {
it('import translators should save attachments', async function () {
let emptyPDF = getTestPDF().path;
let snapshot = getTestSnapshot().path;
let myItems = [
@ -373,8 +373,8 @@ describe("Zotero.Translate", function() {
"attachments":childAttachments
});
let newItems = itemsArrayToObject(yield saveItemsThroughTranslator("import", myItems));
let containedAttachments = yield Zotero.Items.getAsync(newItems["Container Item"].getAttachments());
let newItems = itemsArrayToObject(await saveItemsThroughTranslator("import", myItems));
let containedAttachments = await Zotero.Items.getAsync(newItems["Container Item"].getAttachments());
assert.equal(containedAttachments.length, 3);
for (let savedAttachments of [[newItems["Empty PDF"], newItems["Link to zotero.org"]],
@ -398,7 +398,7 @@ describe("Zotero.Translate", function() {
checkTestTags(containedAttachments[2]);
});
it('import translators should save missing snapshots as links', function* () {
it('import translators should save missing snapshots as links', async function () {
let missingFile = getTestDataDirectory();
missingFile.append("missing");
assert.isFalse(missingFile.exists());
@ -420,10 +420,10 @@ describe("Zotero.Translate", function() {
}
];
let newItems = yield saveItemsThroughTranslator("import", myItems);
let newItems = await saveItemsThroughTranslator("import", myItems);
assert.equal(newItems.length, 1);
assert.equal(newItems[0].getField("title"), "Container Item");
let containedAttachments = yield Zotero.Items.getAsync(newItems[0].getAttachments());
let containedAttachments = await Zotero.Items.getAsync(newItems[0].getAttachments());
assert.equal(containedAttachments.length, 1);
assert.equal(containedAttachments[0].getField("title"), "Snapshot with missing file");
@ -433,7 +433,7 @@ describe("Zotero.Translate", function() {
checkTestTags(containedAttachments[0]);
});
it('import translators should ignore missing file attachments', function* () {
it('import translators should ignore missing file attachments', async function () {
let missingFile = getTestDataDirectory();
missingFile.append("missing");
assert.isFalse(missingFile.exists());
@ -457,7 +457,7 @@ describe("Zotero.Translate", function() {
}
];
let newItems = yield saveItemsThroughTranslator("import", myItems);
let newItems = await saveItemsThroughTranslator("import", myItems);
assert.equal(newItems.length, 1);
assert.equal(newItems[0].getField("title"), "Container Item");
assert.equal(newItems[0].getAttachments().length, 0);
@ -643,34 +643,34 @@ describe("Zotero.Translate", function() {
assert.notEqual(newPath, path);
});
it('web translators should set accessDate to current date', function* () {
it('web translators should set accessDate to current date', async function () {
let myItem = {
"itemType":"webpage",
"title":"Test Item",
"url":"http://www.zotero.org/"
};
let newItems = yield saveItemsThroughTranslator("web", [myItem]);
let newItems = await saveItemsThroughTranslator("web", [myItem]);
let currentDate = new Date();
let delta = currentDate - Zotero.Date.sqlToDate(newItems[0].getField("accessDate"), true);
assert.isAbove(delta, -500);
assert.isBelow(delta, 5000);
});
it('web translators should set accessDate to current date for CURRENT_TIMESTAMP', function* () {
it('web translators should set accessDate to current date for CURRENT_TIMESTAMP', async function () {
let myItem = {
itemType: "webpage",
title: "Test Item",
url: "https://www.zotero.org/",
accessDate: 'CURRENT_TIMESTAMP'
};
let newItems = yield saveItemsThroughTranslator("web", [myItem]);
let newItems = await saveItemsThroughTranslator("web", [myItem]);
let currentDate = new Date();
let delta = currentDate - Zotero.Date.sqlToDate(newItems[0].getField("accessDate"), true);
assert.isAbove(delta, -500);
assert.isBelow(delta, 5000);
});
it('web translators should save attachments', function* () {
it('web translators should save attachments', async function () {
let myItems = [
{
"itemType":"book",
@ -699,9 +699,9 @@ describe("Zotero.Translate", function() {
}
];
let newItems = yield saveItemsThroughTranslator("web", myItems);
let newItems = await saveItemsThroughTranslator("web", myItems);
assert.equal(newItems.length, 1);
let containedAttachments = itemsArrayToObject(yield Zotero.Items.getAsync(newItems[0].getAttachments()));
let containedAttachments = itemsArrayToObject(await Zotero.Items.getAsync(newItems[0].getAttachments()));
let link = containedAttachments["Link to zotero.org"];
assert.equal(link.getField("url"), "http://www.zotero.org/");
@ -724,10 +724,10 @@ describe("Zotero.Translate", function() {
checkTestTags(pdf, true);
});
it('web translators should save attachment from browser document', function* () {
it('web translators should save attachment from browser document', async function () {
let browser = new HiddenBrowser();
yield browser.load(htmlURL);
let doc = yield browser.getDocument();
await browser.load(htmlURL);
let doc = await browser.getDocument();
let translate = new Zotero.Translate.Web();
translate.setDocument(doc);
@ -744,7 +744,7 @@ describe("Zotero.Translate", function() {
' }];\n'+
' item.complete();\n'+
'}'));
let newItems = yield translate.translate();
let newItems = await translate.translate();
assert.equal(newItems.length, 1);
let containedAttachments = Zotero.Items.get(newItems[0].getAttachments());
assert.equal(containedAttachments.length, 1);
@ -759,7 +759,7 @@ describe("Zotero.Translate", function() {
browser.destroy();
});
it('web translators should save attachment from non-browser document', function* () {
it('web translators should save attachment from non-browser document', async function () {
return Zotero.HTTP.processDocuments(
htmlURL,
async function (doc) {
@ -793,7 +793,7 @@ describe("Zotero.Translate", function() {
);
});
it('web translators should ignore attachments that return error codes', function* () {
it('web translators should ignore attachments that return error codes', async function () {
this.timeout(60000);
let myItems = [
{
@ -812,13 +812,13 @@ describe("Zotero.Translate", function() {
}
];
let newItems = yield saveItemsThroughTranslator("web", myItems);
let newItems = await saveItemsThroughTranslator("web", myItems);
assert.equal(newItems.length, 1);
let containedAttachments = yield Zotero.Items.getAsync(newItems[0].getAttachments());
let containedAttachments = await Zotero.Items.getAsync(newItems[0].getAttachments());
assert.equal(containedAttachments.length, 0);
});
it('web translators should save PDFs only if the content type matches', function* () {
it('web translators should save PDFs only if the content type matches', async function () {
this.timeout(60000);
let myItems = [
{
@ -841,9 +841,9 @@ describe("Zotero.Translate", function() {
}
];
let newItems = yield saveItemsThroughTranslator("web", myItems);
let newItems = await saveItemsThroughTranslator("web", myItems);
assert.equal(newItems.length, 1);
let containedAttachments = yield Zotero.Items.getAsync(newItems[0].getAttachments());
let containedAttachments = await Zotero.Items.getAsync(newItems[0].getAttachments());
assert.equal(containedAttachments.length, 1);
let pdf = containedAttachments[0];
@ -854,7 +854,7 @@ describe("Zotero.Translate", function() {
checkTestTags(pdf, true);
});
it('should not convert tags to canonical form in child translators', function* () {
it('should not convert tags to canonical form in child translators', async function () {
var childTranslator = buildDummyTranslator(1,
`function detectWeb() {}
function doImport() {
@ -886,10 +886,10 @@ describe("Zotero.Translate", function() {
var translate = new Zotero.Translate.Import();
translate.setTranslator(parentTranslator);
translate.setString("");
yield translate._loadTranslator(parentTranslator);
await translate._loadTranslator(parentTranslator);
translate._sandboxManager.importObject({childItemDone});
var items = yield translate.translate();
var items = await translate.translate();
// Canonicalized tags after parent translator
assert.deepEqual([{tag: 'owl'}, {tag: 'tag'}], items[0].getTags());
@ -1005,7 +1005,7 @@ describe("Zotero.Translate", function() {
checkTestTags(snapshot, true);
});
it("should use loaded document instead of reloading if possible", function* () {
it("should use loaded document instead of reloading if possible", async function () {
var translate = new Zotero.Translate.Web();
translate.setDocument(doc);
translate.setTranslator(
@ -1037,7 +1037,7 @@ describe("Zotero.Translate", function() {
}`
)
);
var newItems = yield translate.translate();
var newItems = await translate.translate();
assert.equal(newItems.length, 1);
var item = newItems[0];
@ -1211,12 +1211,12 @@ describe("Zotero.Translate", function() {
describe("Translators", function () {
it("should round-trip child attachment via BibTeX", function* () {
var item = yield createDataObject('item');
yield importFileAttachment('test.png', { parentItemID: item.id });
it("should round-trip child attachment via BibTeX", async function () {
var item = await createDataObject('item');
await importFileAttachment('test.png', { parentItemID: item.id });
var translation = new Zotero.Translate.Export();
var tmpDir = yield getTempDirectory();
var tmpDir = await getTempDirectory();
var exportDir = OS.Path.join(tmpDir, 'export');
translation.setLocation(Zotero.File.pathToFile(exportDir));
translation.setItems([item]);
@ -1224,17 +1224,17 @@ describe("Zotero.Translate", function() {
translation.setDisplayOptions({
exportFileData: true
});
yield translation.translate();
await translation.translate();
var exportFile = OS.Path.join(exportDir, 'export.bib');
assert.isTrue(yield OS.File.exists(exportFile));
assert.isTrue(await OS.File.exists(exportFile));
var translation = new Zotero.Translate.Import();
translation.setLocation(Zotero.File.pathToFile(exportFile));
var translators = yield translation.getTranslators();
var translators = await translation.getTranslators();
translation.setTranslator(translators[0]);
var importCollection = yield createDataObject('collection');
var items = yield translation.translate({
var importCollection = await createDataObject('collection');
var items = await translation.translate({
libraryID: Zotero.Libraries.userLibraryID,
collections: [importCollection.id]
});
@ -1243,7 +1243,7 @@ describe("Zotero.Translate", function() {
var attachments = items[0].getAttachments();
assert.lengthOf(attachments, 1);
var attachment = Zotero.Items.get(attachments[0]);
assert.isTrue(yield attachment.fileExists());
assert.isTrue(await attachment.fileExists());
});
it("should round-trip collections via Zotero RDF", async function () {
@ -1507,8 +1507,8 @@ describe("Zotero.Translate", function() {
describe("ItemSaver", function () {
describe("#saveCollections()", function () {
it("should add top-level collections to specified collection", function* () {
var collection = yield createDataObject('collection');
it("should add top-level collections to specified collection", async function () {
var collection = await createDataObject('collection');
var collections = [
{
name: "Collection",
@ -1543,7 +1543,7 @@ describe("Zotero.Translate", function() {
+ " }\n"
+ "}"
));
yield translation.translate({
await translation.translate({
collections: [collection.id]
});
assert.lengthOf(translation.newCollections, 1);
@ -1556,8 +1556,8 @@ describe("Zotero.Translate", function() {
});
describe("#_saveAttachment()", function () {
it("should save standalone attachment to collection", function* () {
var collection = yield createDataObject('collection');
it("should save standalone attachment to collection", async function () {
var collection = await createDataObject('collection');
var items = [
{
itemType: "attachment",
@ -1581,7 +1581,7 @@ describe("Zotero.Translate", function() {
+ " }\n"
+ "}"
));
yield translation.translate({
await translation.translate({
collections: [collection.id]
});
assert.lengthOf(translation.newItems, 1);
@ -1590,8 +1590,8 @@ describe("Zotero.Translate", function() {
});
});
describe('#saveItems', function() {
it("should deproxify item and attachment urls when proxy provided", function* (){
describe('#saveItems', function () {
it("should deproxify item and attachment urls when proxy provided", async function () {
var itemID;
var item = loadSampleData('journalArticle');
item = item.journalArticle;
@ -1607,12 +1607,12 @@ describe("Zotero.Translate", function() {
});
var itemDeferred = Zotero.Promise.defer();
var attachmentDeferred = Zotero.Promise.defer();
itemSaver.saveItems([item], Zotero.Promise.coroutine(function* (attachment, progressPercentage) {
itemSaver.saveItems([item], async function (attachment, progressPercentage) {
// ItemSaver returns immediately without waiting for attachments, so we use the callback
// to test attachments
if (progressPercentage != 100) return;
try {
yield itemDeferred.promise;
await itemDeferred.promise;
let item = Zotero.Items.get(itemID);
attachment = Zotero.Items.get(item.getAttachments()[0]);
assert.equal(attachment.getField('url'), 'https://www.example.com/pdf.pdf');
@ -1620,7 +1620,7 @@ describe("Zotero.Translate", function() {
} catch (e) {
attachmentDeferred.reject(e);
}
})).then(function(items) {
}).then(function (items) {
try {
assert.equal(items[0].getField('url'), 'https://www.example.com/');
itemID = items[0].id;
@ -1629,14 +1629,14 @@ describe("Zotero.Translate", function() {
itemDeferred.reject(e);
}
});
yield Zotero.Promise.all([itemDeferred.promise, attachmentDeferred.promise]);
await Promise.all([itemDeferred.promise, attachmentDeferred.promise]);
});
});
});
describe("Error Handling", function () {
it("should propagate saveItems() errors from synchronous doImport()", function* () {
it("should propagate saveItems() errors from synchronous doImport()", async function () {
var items = [
{
// Invalid object
@ -1668,7 +1668,7 @@ describe("Zotero.Translate", function() {
+ " }"
+ "}"
));
var e = yield getPromiseError(translation.translate());
var e = await getPromiseError(translation.translate());
Zotero.Notifier.unregisterObserver(notifierID);
assert.ok(e);
@ -1679,7 +1679,7 @@ describe("Zotero.Translate", function() {
assert.isNull(translation._currentState);
});
it("should propagate saveItems() errors from asynchronous doImport()", function* () {
it("should propagate saveItems() errors from asynchronous doImport()", async function () {
var items = [
{
// Invalid object
@ -1724,7 +1724,7 @@ describe("Zotero.Translate", function() {
}
}
));
var e = yield getPromiseError(translation.translate());
var e = await getPromiseError(translation.translate());
Zotero.Notifier.unregisterObserver(notifierID);
assert.ok(e);
@ -1735,9 +1735,9 @@ describe("Zotero.Translate", function() {
assert.isNull(translation._currentState);
});
it("should propagate errors from saveItems with synchronous doSearch()", function* () {
it("should propagate errors from saveItems with synchronous doSearch()", async function () {
var stub = sinon.stub(Zotero.Translate.ItemSaver.prototype, "saveItems");
stub.returns(Zotero.Promise.reject(new Error("Save error")));
stub.returns(Promise.reject(new Error("Save error")));
var translation = new Zotero.Translate.Search();
translation.setTranslator(buildDummyTranslator(
@ -1751,7 +1751,7 @@ describe("Zotero.Translate", function() {
+ "}"
));
translation.setSearch({ itemType: "journalArticle", DOI: "10.111/Test"});
var e = yield getPromiseError(translation.translate({
var e = await getPromiseError(translation.translate({
libraryID: Zotero.Libraries.userLibraryID,
saveAttachments: false
}));
@ -1760,9 +1760,9 @@ describe("Zotero.Translate", function() {
stub.restore();
});
it("should propagate errors from saveItems() with asynchronous doSearch()", function* () {
it("should propagate errors from saveItems() with asynchronous doSearch()", async function () {
var stub = sinon.stub(Zotero.Translate.ItemSaver.prototype, "saveItems");
stub.returns(Zotero.Promise.reject(new Error("Save error")));
stub.returns(Promise.reject(new Error("Save error")));
var translation = new Zotero.Translate.Search();
translation.setTranslator(buildDummyTranslator(
@ -1783,7 +1783,7 @@ describe("Zotero.Translate", function() {
}
));
translation.setSearch({ itemType: "journalArticle", DOI: "10.111/Test"});
var e = yield getPromiseError(translation.translate({
var e = await getPromiseError(translation.translate({
libraryID: Zotero.Libraries.userLibraryID,
saveAttachments: false
}));
@ -1794,17 +1794,17 @@ describe("Zotero.Translate", function() {
});
});
describe("Zotero.Translate.ItemGetter", function() {
describe("nextItem", function() {
it('should return false for an empty database', Zotero.Promise.coroutine(function* () {
describe("Zotero.Translate.ItemGetter", function () {
describe("nextItem", function () {
it('should return false for an empty database', async function () {
let getter = new Zotero.Translate.ItemGetter();
assert.isFalse(getter.nextItem());
}));
it('should return items in order they are supplied', Zotero.Promise.coroutine(function* () {
});
it('should return items in order they are supplied', async function () {
let getter = new Zotero.Translate.ItemGetter();
let items, itemIDs, itemURIs;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
items = [
await new Zotero.Item('journalArticle'),
await new Zotero.Item('book')
@ -1819,12 +1819,12 @@ describe("Zotero.Translate.ItemGetter", function() {
assert.equal((getter.nextItem()).uri, itemURIs[0], 'first item comes out first');
assert.equal((getter.nextItem()).uri, itemURIs[1], 'second item comes out second');
assert.isFalse((getter.nextItem()), 'end of item queue');
}));
it('should return items with tags in expected format', Zotero.Promise.coroutine(function* () {
});
it('should return items with tags in expected format', async function () {
let getter = new Zotero.Translate.ItemGetter();
let itemWithAutomaticTag, itemWithManualTag, itemWithMultipleTags
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
itemWithAutomaticTag = new Zotero.Item('journalArticle');
itemWithAutomaticTag.addTag('automatic tag', 0);
await itemWithAutomaticTag.save();
@ -1868,19 +1868,19 @@ describe("Zotero.Translate.ItemGetter", function() {
assert.isArray(translatorItem.tags, 'item contains multiple tags in an array' + suffix);
assert.lengthOf(translatorItem.tags, 2, 'expected number of tags returned' + suffix);
}
}));
it('should return item collections in expected format', Zotero.Promise.coroutine(function* () {
});
it('should return item collections in expected format', async function () {
let getter = new Zotero.Translate.ItemGetter();
let items, collections;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
items = getter._itemsLeft = [
new Zotero.Item('journalArticle'), // Not in collection
new Zotero.Item('journalArticle'), // In a single collection
new Zotero.Item('journalArticle'), //In two collections
new Zotero.Item('journalArticle') // In a nested collection
];
await Zotero.Promise.all(items.map(item => item.save()));
await Promise.all(items.map(item => item.save()));
collections = [
new Zotero.Collection,
@ -1926,13 +1926,13 @@ describe("Zotero.Translate.ItemGetter", function() {
assert.isArray(translatorItem.collections, 'item in a nested collection has a collections array');
assert.equal(translatorItem.collections.length, 1, 'item in a single nested collection lists one collection');
assert.equal(translatorItem.collections[0], collections[2].key, 'item in a single collection identifies correct collection');
}));
});
it('should return item relations in expected format', Zotero.Promise.coroutine(function* () {
it('should return item relations in expected format', async function () {
let getter = new Zotero.Translate.ItemGetter();
let items;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
items = [
new Zotero.Item('journalArticle'), // Item with no relations
@ -1943,7 +1943,7 @@ describe("Zotero.Translate.ItemGetter", function() {
new Zotero.Item('journalArticle'), // But this item is not related to the item below
new Zotero.Item('journalArticle')
];
await Zotero.Promise.all(items.map(item => item.save()));
await Promise.all(items.map(item => item.save()));
await items[1].addRelatedItem(items[2]);
await items[2].addRelatedItem(items[1]);
@ -1992,12 +1992,12 @@ describe("Zotero.Translate.ItemGetter", function() {
assert.isDefined(translatorItem.relations['dc:relation'], 'item that is the object of one relation from item with two relations uses "dc:relation" as the predicate');
assert.lengthOf(translatorItem.relations['dc:relation'], 1, 'item that is the object of one relation from item with two relations lists one "dc:relation" object');
assert.equal(translatorItem.relations['dc:relation'][0], Zotero.URI.getItemURI(items[3]), 'item that is the object of one relation from item with two relations identifies correct subject URI');
}));
});
it('should return standalone note in expected format', Zotero.Promise.coroutine(function* () {
it('should return standalone note in expected format', async function () {
let relatedItem, note, collection;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
relatedItem = new Zotero.Item('journalArticle');
await relatedItem.save();
@ -2077,10 +2077,10 @@ describe("Zotero.Translate.ItemGetter", function() {
assert.equal(translatorNote.collections[0], collection.key, 'identifies correct collection' + suffix);
}
}
}));
it('should return attached note in expected format', Zotero.Promise.coroutine(function* () {
});
it('should return attached note in expected format', async function () {
let relatedItem, items, collection, note;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
relatedItem = new Zotero.Item('journalArticle');
await relatedItem.save();
@ -2088,7 +2088,7 @@ describe("Zotero.Translate.ItemGetter", function() {
new Zotero.Item('journalArticle'),
new Zotero.Item('journalArticle')
];
await Zotero.Promise.all(items.map(item => item.save()));
await Promise.all(items.map(item => item.save()));
collection = new Zotero.Collection;
collection.name = 'test';
@ -2122,7 +2122,7 @@ describe("Zotero.Translate.ItemGetter", function() {
assert.equal(translatorItem.notes.length, 0, 'item with no notes contains empty notes array' + suffix);
note.parentID = item.id;
yield note.saveTx();
await note.saveTx();
getter = new Zotero.Translate.ItemGetter();
getter._itemsLeft = [item];
@ -2182,14 +2182,14 @@ describe("Zotero.Translate.ItemGetter", function() {
assert.isUndefined(translatorNote.collections, 'has no collections array' + suffix);
}
}
}));
});
it('should return stored/linked file and URI attachments in expected format', Zotero.Promise.coroutine(function* () {
it('should return stored/linked file and URI attachments in expected format', async function () {
this.timeout(60000);
let file = getTestPDF();
let item, relatedItem;
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
item = new Zotero.Item('journalArticle');
await item.save();
relatedItem = new Zotero.Item('journalArticle');
@ -2198,14 +2198,14 @@ describe("Zotero.Translate.ItemGetter", function() {
// Attachment items
let attachments = [
yield Zotero.Attachments.importFromFile({"file":file}), // Standalone stored file
yield Zotero.Attachments.linkFromFile({"file":file}), // Standalone link to file
yield Zotero.Attachments.importFromFile({"file":file, "parentItemID":item.id}), // Attached stored file
yield Zotero.Attachments.linkFromFile({"file":file, "parentItemID":item.id}), // Attached link to file
yield Zotero.Attachments.linkFromURL({"url":'http://example.com', "parentItemID":item.id, "contentType":'application/pdf', "title":'empty'}) // Attached link to URL
await Zotero.Attachments.importFromFile({"file":file}), // Standalone stored file
await Zotero.Attachments.linkFromFile({"file":file}), // Standalone link to file
await Zotero.Attachments.importFromFile({"file":file, "parentItemID":item.id}), // Attached stored file
await Zotero.Attachments.linkFromFile({"file":file, "parentItemID":item.id}), // Attached link to file
await Zotero.Attachments.linkFromURL({"url":'http://example.com', "parentItemID":item.id, "contentType":'application/pdf', "title":'empty'}) // Attached link to URL
];
yield Zotero.DB.executeTransaction(async function () {
await Zotero.DB.executeTransaction(async function () {
// Make sure all fields are populated
for (let i=0; i<attachments.length; i++) {
let attachment = attachments[i];
@ -2235,7 +2235,7 @@ describe("Zotero.Translate.ItemGetter", function() {
let getter = new Zotero.Translate.ItemGetter();
getter._itemsLeft = items.slice();
let exportDir = yield getTempDirectory();
let exportDir = await getTempDirectory();
getter._exportFileDirectory = Zotero.File.pathToFile(exportDir);
let legacy = getter.legacy = legacyMode[i];
@ -2349,18 +2349,18 @@ describe("Zotero.Translate.ItemGetter", function() {
// saveFile function
assert.isFunction(attachment.saveFile, prefix + 'has saveFile function' + suffix);
yield attachment.saveFile(attachment.defaultPath);
await attachment.saveFile(attachment.defaultPath);
assert.equal(attachment.path, OS.Path.join(exportDir, OS.Path.normalize(attachment.defaultPath)), prefix + 'path is set correctly after saveFile call' + suffix);
let fileExists = yield OS.File.exists(attachment.path);
let fileExists = await OS.File.exists(attachment.path);
assert.isTrue(fileExists, prefix + 'file was copied to the correct path by saveFile function' + suffix);
fileExists = yield OS.File.exists(attachment.localPath);
fileExists = await OS.File.exists(attachment.localPath);
assert.isTrue(fileExists, prefix + 'file was not removed from original location' + suffix);
let e;
e = yield getPromiseError(attachment.saveFile(attachment.defaultPath));
e = await getPromiseError(attachment.saveFile(attachment.defaultPath));
assert.match(e.message, /^ERROR_FILE_EXISTS /, prefix + 'saveFile does not overwrite existing file by default' + suffix);
e = yield getPromiseError(attachment.saveFile('file/../../'));
e = await getPromiseError(attachment.saveFile('file/../../'));
assert.match(e.message, /./, prefix + 'saveFile does not allow exporting outside export directory' + suffix);
/** TODO: check if overwriting existing file works **/
}
@ -2394,15 +2394,15 @@ describe("Zotero.Translate.ItemGetter", function() {
/** TODO: test other relations and multiple relations per predicate (should be an array) **/
}
}
}));
});
});
describe("#setCollection()", function () {
it("should add collection items", function* () {
var col = yield createDataObject('collection');
var item1 = yield createDataObject('item', { collections: [col.id] });
var item2 = yield createDataObject('item', { collections: [col.id] });
var item3 = yield createDataObject('item');
it("should add collection items", async function () {
var col = await createDataObject('collection');
var item1 = await createDataObject('item', { collections: [col.id] });
var item2 = await createDataObject('item', { collections: [col.id] });
var item3 = await createDataObject('item');
let getter = new Zotero.Translate.ItemGetter();
getter.setCollection(col);
@ -2430,14 +2430,14 @@ describe("Zotero.Translate.ItemGetter", function() {
});
describe("#_attachmentToArray()", function () {
it("should handle missing attachment files", function* () {
var item = yield importFileAttachment('test.png');
it("should handle missing attachment files", async function () {
var item = await importFileAttachment('test.png');
var path = item.getFilePath();
// Delete attachment file
yield OS.File.remove(path);
await OS.File.remove(path);
var translation = new Zotero.Translate.Export();
var tmpDir = yield getTempDirectory();
var tmpDir = await getTempDirectory();
var exportDir = OS.Path.join(tmpDir, 'export');
translation.setLocation(Zotero.File.pathToFile(exportDir));
translation.setItems([item]);
@ -2445,19 +2445,19 @@ describe("Zotero.Translate.ItemGetter", function() {
translation.setDisplayOptions({
exportFileData: true
});
yield translation.translate();
await translation.translate();
var exportFile = OS.Path.join(exportDir, 'export.rdf');
assert.isAbove((yield OS.File.stat(exportFile)).size, 0);
assert.isAbove(((await OS.File.stat(exportFile))).size, 0);
});
it("should handle empty attachment path", function* () {
var item = yield importFileAttachment('test.png');
it("should handle empty attachment path", async function () {
var item = await importFileAttachment('test.png');
item._attachmentPath = '';
assert.equal(item.attachmentPath, '');
var translation = new Zotero.Translate.Export();
var tmpDir = yield getTempDirectory();
var tmpDir = await getTempDirectory();
var exportDir = OS.Path.join(tmpDir, 'export');
translation.setLocation(Zotero.File.pathToFile(exportDir));
translation.setItems([item]);
@ -2465,10 +2465,10 @@ describe("Zotero.Translate.ItemGetter", function() {
translation.setDisplayOptions({
exportFileData: true
});
yield translation.translate();
await translation.translate();
var exportFile = OS.Path.join(exportDir, 'export.rdf');
assert.isAbove((yield OS.File.stat(exportFile)).size, 0);
assert.isAbove(((await OS.File.stat(exportFile))).size, 0);
});
it("should handle UNC paths", async function () {

View file

@ -123,22 +123,22 @@ describe("Zotero.Translators", function () {
Zotero.Translators.getAllForType.restore();
});
describe("when called from a root document", function() {
it("should return generic translators when not matching any translator `target`", function* () {
var translators = yield Zotero.Translators.getWebTranslatorsForLocation(noMatchURL, noMatchURL);
describe("when called from a root document", function () {
it("should return generic translators when not matching any translator `target`", async function () {
var translators = await Zotero.Translators.getWebTranslatorsForLocation(noMatchURL, noMatchURL);
assert.equal(translators[0].length, 1);
assert.equal(translators[0][0].translatorID, 'generic-translator');
});
it("should return all matching translators without `targetAll` property", function* () {
var translators = yield Zotero.Translators.getWebTranslatorsForLocation(topMatchURL, topMatchURL);
it("should return all matching translators without `targetAll` property", async function () {
var translators = await Zotero.Translators.getWebTranslatorsForLocation(topMatchURL, topMatchURL);
assert.equal(translators[0].length, 2);
assert.equal(translators[0][0].translatorID, 'generic-translator');
assert.equal(translators[0][1].translatorID, 'top-level-translator');
});
it("should return translators that match both `target` and `targetAll` when both properties present", function* () {
var translators = yield Zotero.Translators.getWebTranslatorsForLocation(frameMatchURL, frameMatchURL);
it("should return translators that match both `target` and `targetAll` when both properties present", async function () {
var translators = await Zotero.Translators.getWebTranslatorsForLocation(frameMatchURL, frameMatchURL);
assert.equal(translators[0].length, 2);
assert.equal(translators[0][0].translatorID, 'generic-translator');
assert.equal(translators[0][1].translatorID, 'frame-translator');
@ -146,19 +146,19 @@ describe("Zotero.Translators", function () {
});
describe("when called from an iframe", function() {
it("should not return generic translators or translators without `targetAll` property", function* () {
var translators = yield Zotero.Translators.getWebTranslatorsForLocation(frameMatchURL, noMatchURL);
describe("when called from an iframe", function () {
it("should not return generic translators or translators without `targetAll` property", async function () {
var translators = await Zotero.Translators.getWebTranslatorsForLocation(frameMatchURL, noMatchURL);
assert.equal(translators[0].length, 0);
});
it("should not return translators that match `target` but not `targetAll", function* () {
var translators = yield Zotero.Translators.getWebTranslatorsForLocation(noMatchURL, topMatchURL);
it("should not return translators that match `target` but not `targetAll", async function () {
var translators = await Zotero.Translators.getWebTranslatorsForLocation(noMatchURL, topMatchURL);
assert.equal(translators[0].length, 0);
});
it("should return translators that match both `target` and `targetAll`", function* () {
var translators = yield Zotero.Translators.getWebTranslatorsForLocation(frameMatchURL, topMatchURL);
it("should return translators that match both `target` and `targetAll`", async function () {
var translators = await Zotero.Translators.getWebTranslatorsForLocation(frameMatchURL, topMatchURL);
assert.equal(translators[0].length, 1);
assert.equal(translators[0][0].translatorID, 'frame-translator');
});

View file

@ -1,35 +1,35 @@
describe("Zotero.URI", function() {
describe("Zotero.URI", function () {
describe("#getURIItemLibraryKeyFromDB()", function () {
it("should handle user library", function* () {
it("should handle user library", async function () {
var key = 'ABCD2345';
var uri = `http://zotero.org/users/5/items/${key}`;
var obj = yield Zotero.URI.getURIItemLibraryKeyFromDB(uri);
var obj = await Zotero.URI.getURIItemLibraryKeyFromDB(uri);
assert.propertyVal(obj, 'libraryID', Zotero.Libraries.userLibraryID);
assert.propertyVal(obj, 'key', key);
});
it("should handle user library with local user key", function* () {
it("should handle user library with local user key", async function () {
var key = 'ABCD2345';
var uri = `http://zotero.org/users/local/aaaaaaaa/items/${key}`;
var obj = yield Zotero.URI.getURIItemLibraryKeyFromDB(uri);
var obj = await Zotero.URI.getURIItemLibraryKeyFromDB(uri);
assert.propertyVal(obj, 'libraryID', Zotero.Libraries.userLibraryID);
assert.propertyVal(obj, 'key', key);
});
it("should handle publications URI", function* () {
it("should handle publications URI", async function () {
var key = 'ABCD2345';
var uri = `http://zotero.org/users/5/publications/items/${key}`;
var obj = yield Zotero.URI.getURIItemLibraryKeyFromDB(uri);
var obj = await Zotero.URI.getURIItemLibraryKeyFromDB(uri);
assert.propertyVal(obj, 'libraryID', Zotero.Libraries.userLibraryID);
assert.propertyVal(obj, 'key', key);
});
it("should handle group URI", function* () {
var group = yield getGroup();
it("should handle group URI", async function () {
var group = await getGroup();
var key = 'ABCD2345';
var uri = `http://zotero.org/groups/${group.id}/items/${key}`;
var obj = yield Zotero.URI.getURIItemLibraryKeyFromDB(uri);
var obj = await Zotero.URI.getURIItemLibraryKeyFromDB(uri);
assert.propertyVal(obj, 'libraryID', group.libraryID);
assert.propertyVal(obj, 'key', key);
});

View file

@ -10,7 +10,7 @@ describe("Zotero.Utilities.Internal", function () {
describe("#md5()", function () {
it("should generate hex string given file path", function* () {
it("should generate hex string given file path", async function () {
var file = OS.Path.join(getTestDataDirectory().path, 'test.png');
assert.equal(
Zotero.Utilities.Internal.md5(Zotero.File.pathToFile(file)),
@ -21,28 +21,28 @@ describe("Zotero.Utilities.Internal", function () {
describe("#md5Async()", function () {
it("should generate hex string given file path", function* () {
it("should generate hex string given file path", async function () {
var file = OS.Path.join(getTestDataDirectory().path, 'test.png');
yield assert.eventually.equal(
await assert.eventually.equal(
Zotero.Utilities.Internal.md5Async(file),
'93da8f1e5774c599f0942dcecf64b11c'
);
});
it("should generate hex string given file path for file bigger than chunk size", function* () {
it("should generate hex string given file path for file bigger than chunk size", async function () {
var tmpDir = Zotero.getTempDirectory().path;
var file = OS.Path.join(tmpDir, 'md5Async');
let encoder = new TextEncoder();
let arr = encoder.encode("".padStart(100000, "a"));
yield OS.File.writeAtomic(file, arr);
await OS.File.writeAtomic(file, arr);
yield assert.eventually.equal(
await assert.eventually.equal(
Zotero.Utilities.Internal.md5Async(file),
'1af6d6f2f682f76f80e606aeaaee1680'
);
yield OS.File.remove(file);
await OS.File.remove(file);
});
it("should return false for a nonexistent file", async function () {
@ -66,12 +66,12 @@ describe("Zotero.Utilities.Internal", function () {
describe("#gzip()/gunzip()", function () {
it("should compress and decompress a Unicode text string", function* () {
it("should compress and decompress a Unicode text string", async function () {
var text = "Voilà! \u1F429";
var compstr = yield Zotero.Utilities.Internal.gzip(text);
var compstr = await Zotero.Utilities.Internal.gzip(text);
assert.isAbove(compstr.length, 0);
assert.notEqual(compstr.length, text.length);
var str = yield Zotero.Utilities.Internal.gunzip(compstr);
var str = await Zotero.Utilities.Internal.gunzip(compstr);
assert.equal(str, text);
});
});
@ -119,7 +119,7 @@ describe("Zotero.Utilities.Internal", function () {
spy.restore();
});
it("should delay for given amounts of time without limit", function* () {
it("should delay for given amounts of time without limit", async function () {
var intervals = [1, 2];
var gen = Zotero.Utilities.Internal.delayGenerator(intervals);
@ -128,14 +128,14 @@ describe("Zotero.Utilities.Internal", function () {
testIntervals.push(intervals[intervals.length - 1]);
for (let i of testIntervals) {
let val = yield gen.next().value;
let val = await gen.next().value;
assert.isTrue(val);
assert.isTrue(spy.calledWith(i));
spy.resetHistory();
}
});
it("should return false when maxTime is reached", function* () {
it("should return false when maxTime is reached", async function () {
var intervals = [5, 10];
var gen = Zotero.Utilities.Internal.delayGenerator(intervals, 30);
@ -144,14 +144,14 @@ describe("Zotero.Utilities.Internal", function () {
testIntervals.push(intervals[intervals.length - 1]);
for (let i of testIntervals) {
let val = yield gen.next().value;
let val = await gen.next().value;
assert.isTrue(val);
assert.isTrue(spy.calledWith(i));
spy.resetHistory();
}
// Another interval would put us over maxTime, so return false immediately
let val = yield gen.next().value;
let val = await gen.next().value;
assert.isFalse(val);
assert.isFalse(spy.called);
});

View file

@ -74,7 +74,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
);
})
var setup = Zotero.Promise.coroutine(function* (options = {}) {
var setup = async function (options = {}) {
var engine = new Zotero.Sync.Storage.Engine({
libraryID: options.libraryID || Zotero.Libraries.userLibraryID,
controller,
@ -110,15 +110,15 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
url: "zotero/zotero-test-file.prop",
status: 200
})
yield controller.checkServer();
await controller.checkServer();
yield controller.cacheCredentials();
await controller.cacheCredentials();
}
resetRequestCount();
return engine;
})
}
afterEach(async function () {
await new Promise(request => httpd.stop(request));
@ -136,14 +136,14 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
// Tests
//
describe("Syncing", function () {
it("should skip downloads if not marked as needed", function* () {
var engine = yield setup();
it("should skip downloads if not marked as needed", async function () {
var engine = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
var result = yield engine.start();
var result = await engine.start();
assertRequestCount(0);
@ -154,26 +154,26 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.equal(library.storageVersion, library.libraryVersion);
})
it("should ignore a remotely missing file", function* () {
var engine = yield setup();
it("should ignore a remotely missing file", async function () {
var engine = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
library.storageDownloadNeeded = true;
var item = new Zotero.Item("attachment");
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
await item.saveTx();
setResponse({
method: "GET",
url: `zotero/${item.key}.prop`,
status: 404
});
var result = yield engine.start();
var result = await engine.start();
assertRequestCount(1);
@ -185,19 +185,19 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.equal(library.storageVersion, library.libraryVersion);
})
it("should handle a remotely failing .prop file", function* () {
var engine = yield setup();
it("should handle a remotely failing .prop file", async function () {
var engine = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
library.storageDownloadNeeded = true;
var item = new Zotero.Item("attachment");
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
await item.saveTx();
setResponse({
method: "GET",
@ -207,7 +207,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
// TODO: In stopOnError mode, the promise is rejected.
// This should probably test with stopOnError mode turned off instead.
var e = yield getPromiseError(engine.start());
var e = await getPromiseError(engine.start());
assert.include(
e.message,
Zotero.getString('sync.storage.error.webdav.requestError', [500, "GET"])
@ -222,19 +222,19 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.equal(library.storageVersion, 0);
})
it("should handle a remotely failing .zip file", function* () {
var engine = yield setup();
it("should handle a remotely failing .zip file", async function () {
var engine = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
library.storageDownloadNeeded = true;
var item = new Zotero.Item("attachment");
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
await item.saveTx();
setResponse({
method: "GET",
@ -255,7 +255,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
);
// TODO: In stopOnError mode, the promise is rejected.
// This should probably test with stopOnError mode turned off instead.
var e = yield getPromiseError(engine.start());
var e = await getPromiseError(engine.start());
assert.include(
e.message,
Zotero.getString('sync.storage.error.webdav.requestError', [500, "GET"])
@ -266,12 +266,12 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
})
it("should download a missing file", function* () {
var engine = yield setup();
it("should download a missing file", async function () {
var engine = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
library.storageDownloadNeeded = true;
var fileName = "test.txt";
@ -281,24 +281,24 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
// TODO: Test binary data
var text = Zotero.Utilities.randomString();
item.attachmentSyncState = "to_download";
yield item.saveTx();
await item.saveTx();
// Create ZIP file containing above text file
var tmpPath = Zotero.getTempDirectory().path;
var tmpID = "webdav_download_" + Zotero.Utilities.randomString();
var zipDirPath = OS.Path.join(tmpPath, tmpID);
var zipPath = OS.Path.join(tmpPath, tmpID + ".zip");
yield OS.File.makeDir(zipDirPath);
yield Zotero.File.putContentsAsync(OS.Path.join(zipDirPath, fileName), text);
yield Zotero.File.zipDirectory(zipDirPath, zipPath);
yield OS.File.removeDir(zipDirPath);
yield Zotero.Promise.delay(1000);
var zipContents = yield Zotero.File.getBinaryContentsAsync(zipPath);
await OS.File.makeDir(zipDirPath);
await Zotero.File.putContentsAsync(OS.Path.join(zipDirPath, fileName), text);
await Zotero.File.zipDirectory(zipDirPath, zipPath);
await OS.File.removeDir(zipDirPath);
await Zotero.Promise.delay(1000);
var zipContents = await Zotero.File.getBinaryContentsAsync(zipPath);
var mtime = "1441252524905";
var md5 = yield Zotero.Utilities.Internal.md5Async(zipPath);
var md5 = await Zotero.Utilities.Internal.md5Async(zipPath);
yield OS.File.remove(zipPath);
await OS.File.remove(zipPath);
setResponse({
method: "GET",
@ -319,34 +319,34 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
}
);
var result = yield engine.start();
var result = await engine.start();
assert.isTrue(result.localChanges);
assert.isFalse(result.remoteChanges);
assert.isFalse(result.syncRequired);
var contents = yield Zotero.File.getContentsAsync(yield item.getFilePathAsync());
var contents = await Zotero.File.getContentsAsync(await item.getFilePathAsync());
assert.equal(contents, text);
assert.isFalse(library.storageDownloadNeeded);
assert.equal(library.storageVersion, library.libraryVersion);
})
it("should upload new files", function* () {
var engine = yield setup();
it("should upload new files", async function () {
var engine = await setup();
var file = getTestDataDirectory();
file.append('test.png');
var item = yield Zotero.Attachments.importFromFile({ file });
var item = await Zotero.Attachments.importFromFile({ file });
item.synced = true;
yield item.saveTx();
var mtime = yield item.attachmentModificationTime;
var hash = yield item.attachmentHash;
await item.saveTx();
var mtime = await item.attachmentModificationTime;
var hash = await item.attachmentHash;
var path = item.getFilePath();
var filename = 'test.png';
var size = (yield OS.File.stat(path)).size;
var size = ((await OS.File.stat(path))).size;
var contentType = 'image/png';
var fileContents = yield Zotero.File.getContentsAsync(path);
var fileContents = await Zotero.File.getContentsAsync(path);
var deferreds = [];
@ -367,14 +367,14 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
let deferred = Zotero.Promise.defer();
deferreds.push(deferred);
var reader = new FileReader();
reader.addEventListener("loadend", Zotero.Promise.coroutine(function* () {
reader.addEventListener("loadend", async function () {
try {
let tmpZipPath = OS.Path.join(
Zotero.getTempDirectory().path,
Zotero.Utilities.randomString() + '.zip'
);
let contents = new Uint8Array(reader.result);
yield IOUtils.write(tmpZipPath, contents);
await IOUtils.write(tmpZipPath, contents);
// Make sure ZIP file contains the necessary entries
var zr = Components.classes["@mozilla.org/libjar/zip-reader;1"]
@ -390,14 +390,14 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.sameMembers(entryNames, [filename]);
assert.equal(zr.getEntry(filename).realSize, size);
yield OS.File.remove(tmpZipPath);
await OS.File.remove(tmpZipPath);
deferred.resolve();
}
catch (e) {
deferred.reject(e);
}
}));
});
reader.readAsArrayBuffer(req.requestBody);
req.respond(201, { "Fake-Server-Match": 1 }, "");
@ -416,9 +416,9 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
}
});
var result = yield engine.start();
var result = await engine.start();
yield Zotero.Promise.all(deferreds.map(d => d.promise));
await Promise.all(deferreds.map(d => d.promise));
assertRequestCount(3);
@ -432,24 +432,24 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.isFalse(item.synced);
})
it("should upload an updated file", function* () {
var engine = yield setup();
it("should upload an updated file", async function () {
var engine = await setup();
var file = getTestDataDirectory();
file.append('test.txt');
var item = yield Zotero.Attachments.importFromFile({ file });
var item = await Zotero.Attachments.importFromFile({ file });
item.synced = true;
yield item.saveTx();
await item.saveTx();
var syncedModTime = Date.now() - 10000;
var syncedHash = "3a2f092dd62178eb8bbfda42e07e64da";
item.attachmentSyncedModificationTime = syncedModTime;
item.attachmentSyncedHash = syncedHash;
yield item.saveTx({ skipAll: true });
await item.saveTx({ skipAll: true });
var mtime = yield item.attachmentModificationTime;
var hash = yield item.attachmentHash;
var mtime = await item.attachmentModificationTime;
var hash = await item.attachmentHash;
setResponse({
method: "GET",
@ -475,7 +475,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
status: 204
});
var result = yield engine.start();
var result = await engine.start();
assertRequestCount(4);
assert.isTrue(result.localChanges);
@ -489,16 +489,16 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.isFalse(item.synced);
})
it("should skip upload that already exists on the server", function* () {
var engine = yield setup();
it("should skip upload that already exists on the server", async function () {
var engine = await setup();
var file = getTestDataDirectory();
file.append('test.png');
var item = yield Zotero.Attachments.importFromFile({ file });
var item = await Zotero.Attachments.importFromFile({ file });
item.synced = true;
yield item.saveTx();
var mtime = yield item.attachmentModificationTime;
var hash = yield item.attachmentHash;
await item.saveTx();
var mtime = await item.attachmentModificationTime;
var hash = await item.attachmentHash;
setResponse({
method: "GET",
@ -510,7 +510,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
+ '</properties>'
});
var result = yield engine.start();
var result = await engine.start();
assertRequestCount(1);
@ -578,15 +578,15 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
// this, we just don't store or send any cookies for WebDAV requests.
//
// https://forums.zotero.org/discussion/80429/sync-error-in-5-0-80
it("shouldn't send cookies", function* () {
it("shouldn't send cookies", async function () {
// Make real requests so we can test the internal cookie-handling behavior
Zotero.HTTP.mock = null;
controller.verified = true;
var engine = yield setup();
var engine = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
library.storageDownloadNeeded = true;
var fileName = "test.txt";
@ -595,23 +595,23 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
item.attachmentPath = 'storage:' + fileName;
var text = Zotero.Utilities.randomString();
item.attachmentSyncState = "to_download";
yield item.saveTx();
await item.saveTx();
// Create ZIP file containing above text file
var tmpPath = Zotero.getTempDirectory().path;
var tmpID = "webdav_download_" + Zotero.Utilities.randomString();
var zipDirPath = OS.Path.join(tmpPath, tmpID);
var zipPath = OS.Path.join(tmpPath, tmpID + ".zip");
yield OS.File.makeDir(zipDirPath);
yield Zotero.File.putContentsAsync(OS.Path.join(zipDirPath, fileName), text);
yield Zotero.File.zipDirectory(zipDirPath, zipPath);
yield OS.File.removeDir(zipDirPath);
var zipContents = yield Zotero.File.getBinaryContentsAsync(zipPath);
await OS.File.makeDir(zipDirPath);
await Zotero.File.putContentsAsync(OS.Path.join(zipDirPath, fileName), text);
await Zotero.File.zipDirectory(zipDirPath, zipPath);
await OS.File.removeDir(zipDirPath);
var zipContents = await Zotero.File.getBinaryContentsAsync(zipPath);
var mtime = "1441252524905";
var md5 = yield Zotero.Utilities.Internal.md5Async(zipPath);
var md5 = await Zotero.Utilities.Internal.md5Async(zipPath);
yield OS.File.remove(zipPath);
await OS.File.remove(zipPath);
// OPTIONS request to cache credentials
httpd.registerPathHandler(
@ -690,27 +690,27 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
}
);
yield engine.start();
await engine.start();
assert.equal(library.storageVersion, library.libraryVersion);
});
it("should mark item as in conflict if mod time and hash on storage server don't match synced values", function* () {
var engine = yield setup();
it("should mark item as in conflict if mod time and hash on storage server don't match synced values", async function () {
var engine = await setup();
var file = getTestDataDirectory();
file.append('test.png');
var item = yield Zotero.Attachments.importFromFile({ file });
var item = await Zotero.Attachments.importFromFile({ file });
item.synced = true;
yield item.saveTx();
var mtime = yield item.attachmentModificationTime;
var hash = yield item.attachmentHash;
await item.saveTx();
var mtime = await item.attachmentModificationTime;
var hash = await item.attachmentHash;
var path = item.getFilePath();
var filename = 'test.png';
var size = (yield OS.File.stat(path)).size;
var size = ((await OS.File.stat(path))).size;
var contentType = 'image/png';
var fileContents = yield Zotero.File.getContentsAsync(path);
var fileContents = await Zotero.File.getContentsAsync(path);
var newModTime = mtime + 5000;
var newHash = "4f69f43d8ac8788190b13ff7f4a0a915";
@ -725,7 +725,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
+ '</properties>'
});
var result = yield engine.start();
var result = await engine.start();
assertRequestCount(1);
@ -746,12 +746,12 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
});
describe("Verify Server", function () {
it("should show an error for a connection error", function* () {
it("should show an error for a connection error", async function () {
Zotero.HTTP.mock = null;
Zotero.Prefs.set("sync.storage.url", "127.0.0.1:9999");
// Begin install procedure
var win = yield loadPrefPane('sync');
var win = await loadPrefPane('sync');
var button = win.document.getElementById('storage-verify');
var spy = sinon.spy(win.Zotero_Preferences.Sync, "verifyStorageServer");
@ -762,11 +762,11 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
);
});
button.click();
yield promise1;
await promise1;
var promise2 = spy.returnValues[0];
spy.restore();
yield promise2;
await promise2;
win.close();
});
@ -815,7 +815,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
win.close();
});
it("should show an error for a 403", function* () {
it("should show an error for a 403", async function () {
Zotero.HTTP.mock = null;
httpd.registerPathHandler(
`${davBasePath}zotero/`,
@ -830,7 +830,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
Zotero.Prefs.set("sync.storage.url", davHostPath);
// Begin install procedure
var win = yield loadPrefPane('sync');
var win = await loadPrefPane('sync');
var button = win.document.getElementById('storage-verify');
var spy = sinon.spy(win.Zotero_Preferences.Sync, "verifyStorageServer");
@ -841,17 +841,17 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
);
});
button.click();
yield promise1;
await promise1;
var promise2 = spy.returnValues[0];
spy.restore();
yield promise2;
await promise2;
win.close();
});
it("should show an error for a 404 for the parent directory", function* () {
it("should show an error for a 404 for the parent directory", async function () {
// Use httpd.js instead of sinon so we get a real nsIURL with a channel
Zotero.HTTP.mock = null;
Zotero.Prefs.set("sync.storage.url", davHostPath);
@ -887,7 +887,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
);
// Begin verify procedure
var win = yield loadPrefPane('sync');
var win = await loadPrefPane('sync');
var button = win.document.getElementById('storage-verify');
var spy = sinon.spy(win.Zotero_Preferences.Sync, "verifyStorageServer");
@ -898,11 +898,11 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
);
});
button.click();
yield promise1;
await promise1;
var promise2 = spy.returnValues[0];
spy.restore();
yield promise2;
await promise2;
win.close();
});
@ -970,17 +970,17 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
resetRequestCount();
})
it("should delete files on storage server that were deleted locally", function* () {
it("should delete files on storage server that were deleted locally", async function () {
var libraryID = Zotero.Libraries.userLibraryID;
var file = getTestDataDirectory();
file.append('test.png');
var item = yield Zotero.Attachments.importFromFile({ file });
var item = await Zotero.Attachments.importFromFile({ file });
item.synced = true;
yield item.saveTx();
yield item.eraseTx();
await item.saveTx();
await item.eraseTx();
assert.lengthOf((yield Zotero.Sync.Storage.Local.getDeletedFiles(libraryID)), 1);
assert.lengthOf(((await Zotero.Sync.Storage.Local.getDeletedFiles(libraryID))), 1);
setResponse({
method: "DELETE",
@ -992,7 +992,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
url: `zotero/${item.key}.zip`,
status: 204
});
var results = yield controller.purgeDeletedStorageFiles(libraryID);
var results = await controller.purgeDeletedStorageFiles(libraryID);
assertRequestCount(2);
assert.lengthOf(results.deleted, 2);
@ -1001,7 +1001,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.lengthOf(results.error, 0);
// Storage delete log should be empty
assert.lengthOf((yield Zotero.Sync.Storage.Local.getDeletedFiles(libraryID)), 0);
assert.lengthOf(((await Zotero.Sync.Storage.Local.getDeletedFiles(libraryID))), 0);
})
})
@ -1011,17 +1011,17 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
Zotero.Prefs.clear('lastWebDAVOrphanPurge');
})
it("should delete orphaned files more than a week older than the last sync time", function* () {
it("should delete orphaned files more than a week older than the last sync time", async function () {
var library = Zotero.Libraries.userLibrary;
library.updateLastSyncTime();
yield library.saveTx();
await library.saveTx();
// Create one item
var item1 = yield createDataObject('item');
var item1 = await createDataObject('item');
var item1Key = item1.key;
// Add another item to sync queue
var item2Key = Zotero.DataObjectUtilities.generateKey();
yield Zotero.Sync.Data.Local.addObjectsToSyncQueue('item', library.id, [item2Key]);
await Zotero.Sync.Data.Local.addObjectsToSyncQueue('item', library.id, [item2Key]);
const daysBeforeSyncTime = 7;
@ -1195,7 +1195,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
status: 204
});
var results = yield controller.purgeOrphanedStorageFiles();
var results = await controller.purgeOrphanedStorageFiles();
assertRequestCount(7);
assert.sameMembers(
@ -1213,17 +1213,17 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.lengthOf(results.error, 0);
})
it("shouldn't purge if purged recently", function* () {
it("shouldn't purge if purged recently", async function () {
Zotero.Prefs.set("lastWebDAVOrphanPurge", Math.round(new Date().getTime() / 1000) - 3600);
yield assert.eventually.equal(controller.purgeOrphanedStorageFiles(), false);
await assert.eventually.equal(controller.purgeOrphanedStorageFiles(), false);
assertRequestCount(0);
});
it("should handle unnormalized Unicode characters", function* () {
it("should handle unnormalized Unicode characters", async function () {
var library = Zotero.Libraries.userLibrary;
library.updateLastSyncTime();
yield library.saveTx();
await library.saveTx();
const daysBeforeSyncTime = 7;
@ -1285,7 +1285,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
});
Zotero.Prefs.set("sync.storage.url", davHostPath + strC + "/");
yield controller.purgeOrphanedStorageFiles();
await controller.purgeOrphanedStorageFiles();
})
})
})

View file

@ -69,14 +69,13 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
resetRequestCount();
})
var setup = Zotero.Promise.coroutine(function* (options = {}) {
var setup = async function (options = {}) {
const { ConcurrentCaller } = ChromeUtils.importESModule("resource://zotero/concurrentCaller.mjs");
var stopOnError = options.stopOnError !== undefined ? options.stopOnError : true;
var caller = new ConcurrentCaller(1);
caller.setLogger(msg => Zotero.debug(msg));
caller.stopOnError = stopOnError;
Components.utils.import("resource://zotero/config.js");
var client = new Zotero.Sync.APIClient({
baseURL,
apiVersion: options.apiVersion || ZOTERO_CONFIG.API_VERSION,
@ -96,7 +95,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
});
return { engine, client, caller };
})
}
afterEach(function* () {
var defer = Zotero.Promise.defer();
@ -114,14 +113,14 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
describe("Syncing", function () {
it("should skip downloads if not marked as needed", function* () {
var { engine, client, caller } = yield setup();
it("should skip downloads if not marked as needed", async function () {
var { engine, client, caller } = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
var result = yield engine.start();
var result = await engine.start();
assertRequestCount(0);
@ -132,19 +131,19 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
assert.equal(library.storageVersion, library.libraryVersion);
})
it("should ignore download for a remotely missing file", function* () {
var { engine, client, caller } = yield setup();
it("should ignore download for a remotely missing file", async function () {
var { engine, client, caller } = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
library.storageDownloadNeeded = true;
var item = new Zotero.Item("attachment");
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
await item.saveTx();
httpd.registerPathHandler(
`/users/1/items/${item.key}/file`,
@ -154,7 +153,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
}
}
);
var result = yield engine.start();
var result = await engine.start();
assert.isFalse(result.localChanges);
assert.isFalse(result.remoteChanges);
@ -164,12 +163,12 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
assert.equal(library.storageVersion, library.libraryVersion);
})
it("shouldn't update storageVersion if stopped", function* () {
var { engine, client, caller } = yield setup();
it("shouldn't update storageVersion if stopped", async function () {
var { engine, client, caller } = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
library.storageDownloadNeeded = true;
var items = [];
@ -178,7 +177,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
await item.saveTx();
items.push(item);
}
@ -191,26 +190,26 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
return new Zotero.Sync.Storage.Result;
});
var result = yield engine.start();
var result = await engine.start();
stub.restore();
assert.equal(library.storageVersion, 0);
});
it("should handle a remotely failing file", function* () {
var { engine, client, caller } = yield setup();
it("should handle a remotely failing file", async function () {
var { engine, client, caller } = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
library.storageDownloadNeeded = true;
var item = new Zotero.Item("attachment");
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
await item.saveTx();
Zotero.HTTP.disableErrorRetry = true;
httpd.registerPathHandler(
@ -223,19 +222,19 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
);
// TODO: In stopOnError mode, this the promise is rejected.
// This should probably test with stopOnError mode turned off instead.
var e = yield getPromiseError(engine.start());
var e = await getPromiseError(engine.start());
assert.equal(e.message, Zotero.Sync.Storage.defaultError);
assert.isTrue(library.storageDownloadNeeded);
assert.equal(library.storageVersion, 0);
})
it("should download a missing file", function* () {
var { engine, client, caller } = yield setup();
it("should download a missing file", async function () {
var { engine, client, caller } = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
library.storageDownloadNeeded = true;
var item = new Zotero.Item("attachment");
@ -244,7 +243,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
// TODO: Test binary data
var text = Zotero.Utilities.randomString();
item.attachmentSyncState = "to_download";
yield item.saveTx();
await item.saveTx();
var mtime = "1441252524905";
var md5 = Zotero.Utilities.Internal.md5(text)
@ -280,13 +279,13 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
}
}
);
var result = yield engine.start();
var result = await engine.start();
assert.isTrue(result.localChanges);
assert.isFalse(result.remoteChanges);
assert.isFalse(result.syncRequired);
var contents = yield Zotero.File.getContentsAsync(yield item.getFilePathAsync());
var contents = await Zotero.File.getContentsAsync(await item.getFilePathAsync());
assert.equal(contents, text);
assert.isFalse(library.storageDownloadNeeded);
@ -337,7 +336,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
var deferred = Zotero.Promise.defer();
var observerID = Zotero.Notifier.registerObserver({
notify: async function (event, type, ids, extraData) {
if (event == 'download' && ids[0] == item.id && await item.getFilePathAsync()) {
if (event == 'download' && ids[0] == item.id && (await item.getFilePathAsync())) {
deferred.resolve();
}
}
@ -348,18 +347,18 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
Zotero.Notifier.unregisterObserver(observerID);
});
it("should upload new files", function* () {
var { engine, client, caller } = yield setup();
it("should upload new files", async function () {
var { engine, client, caller } = await setup();
// Single file
var file1 = getTestDataDirectory();
file1.append('test.png');
var item1 = yield Zotero.Attachments.importFromFile({ file: file1 });
var mtime1 = yield item1.attachmentModificationTime;
var hash1 = yield item1.attachmentHash;
var item1 = await Zotero.Attachments.importFromFile({ file: file1 });
var mtime1 = await item1.attachmentModificationTime;
var hash1 = await item1.attachmentHash;
var path1 = item1.getFilePath();
var filename1 = 'test.png';
var size1 = (yield OS.File.stat(path1)).size;
var size1 = ((await OS.File.stat(path1))).size;
var contentType1 = 'image/png';
var prefix1 = Zotero.Utilities.randomString();
var suffix1 = Zotero.Utilities.randomString();
@ -367,13 +366,13 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
let file1Blob = File.createFromFileName ? File.createFromFileName(file1.path) : new File(file1);
if (file1Blob.then) {
file1Blob = yield file1Blob;
file1Blob = await file1Blob;
}
// HTML file with auxiliary image
var file2 = OS.Path.join(getTestDataDirectory().path, 'snapshot', 'index.html');
var parentItem = yield createDataObject('item');
var item2 = yield Zotero.Attachments.importSnapshotFromFile({
var parentItem = await createDataObject('item');
var item2 = await Zotero.Attachments.importSnapshotFromFile({
file: file2,
url: 'http://example.com/',
parentItemID: parentItem.id,
@ -381,11 +380,11 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
contentType: 'text/html',
charset: 'utf-8'
});
var mtime2 = yield item2.attachmentModificationTime;
var hash2 = yield item2.attachmentHash;
var mtime2 = await item2.attachmentModificationTime;
var hash2 = await item2.attachmentHash;
var path2 = item2.getFilePath();
var filename2 = 'index.html';
var size2 = (yield OS.File.stat(path2)).size;
var size2 = ((await OS.File.stat(path2))).size;
var contentType2 = 'text/html';
var charset2 = 'utf-8';
var prefix2 = Zotero.Utilities.randomString();
@ -512,11 +511,11 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
let deferred = Zotero.Promise.defer();
deferreds.push(deferred);
var reader = new FileReader();
reader.addEventListener("loadend", Zotero.Promise.coroutine(function* () {
reader.addEventListener("loadend", async function () {
try {
let contents = new Uint8Array(reader.result);
contents = contents.slice(prefix2.length, suffix2.length * -1);
yield IOUtils.write(tmpZipPath, contents);
await IOUtils.write(tmpZipPath, contents);
var zr = Components.classes["@mozilla.org/libjar/zip-reader;1"]
.createInstance(Components.interfaces.nsIZipReader);
@ -537,7 +536,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
catch (e) {
deferred.reject(e);
}
}));
});
reader.readAsArrayBuffer(req.requestBody);
req.respond(201, {}, "");
@ -639,9 +638,9 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
req.respond(201, {}, "");
}
})*/
var result = yield engine.start();
var result = await engine.start();
yield Zotero.Promise.all(deferreds.map(d => d.promise));
await Promise.all(deferreds.map(d => d.promise));
assert.isTrue(result.localChanges);
assert.isTrue(result.remoteChanges);
@ -656,25 +655,25 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
assert.equal(item2.version, 15);
})
it("should update local info for remotely updated file that matches local file", function* () {
var { engine, client, caller } = yield setup();
it("should update local info for remotely updated file that matches local file", async function () {
var { engine, client, caller } = await setup();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
await library.saveTx();
library.storageDownloadNeeded = true;
var file = getTestDataDirectory();
file.append('test.txt');
var item = yield Zotero.Attachments.importFromFile({ file });
var item = await Zotero.Attachments.importFromFile({ file });
item.version = 5;
item.attachmentSyncState = "to_download";
yield item.saveTx();
var path = yield item.getFilePathAsync();
yield OS.File.setDates(path, null, new Date() - 100000);
await item.saveTx();
var path = await item.getFilePathAsync();
await OS.File.setDates(path, null, new Date() - 100000);
var json = item.toJSON();
yield Zotero.Sync.Data.Local.saveCacheObject('item', item.libraryID, json);
await Zotero.Sync.Data.Local.saveCacheObject('item', item.libraryID, json);
var mtime = (Math.floor(new Date().getTime() / 1000) * 1000) + "";
var md5 = Zotero.Utilities.Internal.md5(file)
@ -701,31 +700,31 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
}
}
);
var result = yield engine.start();
var result = await engine.start();
assert.equal(item.attachmentSyncedModificationTime, mtime);
yield assert.eventually.equal(item.attachmentModificationTime, mtime);
await assert.eventually.equal(item.attachmentModificationTime, mtime);
assert.isTrue(result.localChanges);
assert.isFalse(result.remoteChanges);
assert.isFalse(result.syncRequired);
})
it("should update local info for file that already exists on the server", function* () {
var { engine, client, caller } = yield setup();
it("should update local info for file that already exists on the server", async function () {
var { engine, client, caller } = await setup();
var file = getTestDataDirectory();
file.append('test.png');
var item = yield Zotero.Attachments.importFromFile({ file: file });
var item = await Zotero.Attachments.importFromFile({ file: file });
item.version = 5;
yield item.saveTx();
await item.saveTx();
var json = item.toJSON();
yield Zotero.Sync.Data.Local.saveCacheObject('item', item.libraryID, json);
await Zotero.Sync.Data.Local.saveCacheObject('item', item.libraryID, json);
var mtime = yield item.attachmentModificationTime;
var hash = yield item.attachmentHash;
var mtime = await item.attachmentModificationTime;
var hash = await item.attachmentHash;
var path = item.getFilePath();
var filename = 'test.png';
var size = (yield OS.File.stat(path)).size;
var size = ((await OS.File.stat(path))).size;
var contentType = 'image/png';
var newVersion = 10;
@ -757,7 +756,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
})
// TODO: One-step uploads
var result = yield engine.start();
var result = await engine.start();
assert.isTrue(result.localChanges);
assert.isTrue(result.remoteChanges);
@ -770,20 +769,20 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
})
it("should retry with If-None-Match on 412 with missing remote hash", function* () {
var { engine, client, caller } = yield setup();
it("should retry with If-None-Match on 412 with missing remote hash", async function () {
var { engine, client, caller } = await setup();
var zfs = new Zotero.Sync.Storage.Mode.ZFS({
apiClient: client
})
var file = getTestDataDirectory();
file.append('test.png');
var item = yield Zotero.Attachments.importFromFile({ file });
var item = await Zotero.Attachments.importFromFile({ file });
item.version = 5;
item.synced = true;
item.attachmentSyncedModificationTime = Date.now();
item.attachmentSyncedHash = 'bd4c33e03798a7e8bc0b46f8bda74fac'
yield item.saveTx();
await item.saveTx();
var contentType = 'image/png';
var prefix = Zotero.Utilities.randomString();
@ -849,7 +848,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
}
});
var result = yield engine.start();
var result = await engine.start();
assert.equal(called, 4);
});
@ -949,7 +948,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
var request = { name: item.libraryKey };
var stub = sinon.stub(zfs, '_processUploadFile').returns(Zotero.Promise.resolve());
var stub = sinon.stub(zfs, '_processUploadFile').returns(Promise.resolve());
await zfs.uploadFile(request);
var zipFile = OS.Path.join(Zotero.getTempDirectory().path, item.key + '.zip');
@ -963,21 +962,21 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
describe("#_processUploadFile()", function () {
it("should handle 404 from upload authorization request", function* () {
var { engine, client, caller } = yield setup();
it("should handle 404 from upload authorization request", async function () {
var { engine, client, caller } = await setup();
var zfs = new Zotero.Sync.Storage.Mode.ZFS({
apiClient: client
})
var filePath = OS.Path.join(getTestDataDirectory().path, 'test.png');
var item = yield Zotero.Attachments.importFromFile({ file: filePath });
var item = await Zotero.Attachments.importFromFile({ file: filePath });
item.version = 5;
item.synced = true;
yield item.saveTx();
await item.saveTx();
var itemJSON = item.toResponseJSON();
itemJSON.data.mtime = yield item.attachmentModificationTime;
itemJSON.data.md5 = yield item.attachmentHash;
itemJSON.data.mtime = await item.attachmentModificationTime;
itemJSON.data.md5 = await item.attachmentHash;
server.respond(function (req) {
if (req.method == "POST"
@ -993,27 +992,27 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
}
})
var result = yield zfs._processUploadFile({
var result = await zfs._processUploadFile({
name: item.libraryKey
});
assert.isTrue(result.syncRequired);
});
it("should handle 412 with matching version and hash matching local file", function* () {
var { engine, client, caller } = yield setup();
it("should handle 412 with matching version and hash matching local file", async function () {
var { engine, client, caller } = await setup();
var zfs = new Zotero.Sync.Storage.Mode.ZFS({
apiClient: client
})
var filePath = OS.Path.join(getTestDataDirectory().path, 'test.png');
var item = yield Zotero.Attachments.importFromFile({ file: filePath });
var item = await Zotero.Attachments.importFromFile({ file: filePath });
item.version = 5;
item.synced = true;
yield item.saveTx();
await item.saveTx();
var itemJSON = item.toResponseJSON();
itemJSON.data.mtime = yield item.attachmentModificationTime;
itemJSON.data.md5 = yield item.attachmentHash;
itemJSON.data.mtime = await item.attachmentModificationTime;
itemJSON.data.md5 = await item.attachmentHash;
// Set saved hash to a different value, which should be overwritten
//
@ -1022,7 +1021,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
// never downloaded), but there's no difference in behavior
var dbHash = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
item.attachmentSyncedHash = dbHash;
yield item.saveTx({ skipAll: true });
await item.saveTx({ skipAll: true });
server.respond(function (req) {
if (req.method == "POST"
@ -1046,29 +1045,29 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
text: JSON.stringify([itemJSON])
});
var result = yield zfs._processUploadFile({
var result = await zfs._processUploadFile({
name: item.libraryKey
});
assert.equal(item.attachmentSyncedHash, (yield item.attachmentHash));
assert.equal(item.attachmentSyncedHash, ((await item.attachmentHash)));
assert.isFalse(result.localChanges);
assert.isFalse(result.remoteChanges);
assert.isFalse(result.syncRequired);
assert.isFalse(result.fileSyncRequired);
})
it("should handle 412 with matching version and hash not matching local file", function* () {
var { engine, client, caller } = yield setup();
it("should handle 412 with matching version and hash not matching local file", async function () {
var { engine, client, caller } = await setup();
var zfs = new Zotero.Sync.Storage.Mode.ZFS({
apiClient: client
})
var filePath = OS.Path.join(getTestDataDirectory().path, 'test.png');
var item = yield Zotero.Attachments.importFromFile({ file: filePath });
var item = await Zotero.Attachments.importFromFile({ file: filePath });
item.version = 5;
item.synced = true;
yield item.saveTx();
await item.saveTx();
var fileHash = yield item.attachmentHash;
var fileHash = await item.attachmentHash;
var itemJSON = item.toResponseJSON();
itemJSON.data.md5 = 'aaaaaaaaaaaaaaaaaaaaaaaa'
@ -1094,7 +1093,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
text: JSON.stringify([itemJSON])
});
var result = yield zfs._processUploadFile({
var result = await zfs._processUploadFile({
name: item.libraryKey
});
assert.isNull(item.attachmentSyncedHash);
@ -1105,18 +1104,18 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
assert.isTrue(result.fileSyncRequired);
})
it("should handle 412 with greater version", function* () {
var { engine, client, caller } = yield setup();
it("should handle 412 with greater version", async function () {
var { engine, client, caller } = await setup();
var zfs = new Zotero.Sync.Storage.Mode.ZFS({
apiClient: client
})
var file = getTestDataDirectory();
file.append('test.png');
var item = yield Zotero.Attachments.importFromFile({ file });
var item = await Zotero.Attachments.importFromFile({ file });
item.version = 5;
item.synced = true;
yield item.saveTx();
await item.saveTx();
server.respond(function (req) {
if (req.method == "POST"
@ -1134,7 +1133,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
}
})
var result = yield zfs._processUploadFile({
var result = await zfs._processUploadFile({
name: item.libraryKey
});
assert.equal(item.version, 5);
@ -1143,23 +1142,23 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
assert.isFalse(result.remoteChanges);
assert.isTrue(result.syncRequired);
// Item should be marked for redownloading
var versions = yield Zotero.Sync.Data.Local.getObjectsToTryFromSyncQueue('item', item.libraryID);
var versions = await Zotero.Sync.Data.Local.getObjectsToTryFromSyncQueue('item', item.libraryID);
assert.include(versions, item.key);
});
it("should handle 413 on quota limit", function* () {
var { engine, client, caller } = yield setup();
it("should handle 413 on quota limit", async function () {
var { engine, client, caller } = await setup();
var zfs = new Zotero.Sync.Storage.Mode.ZFS({
apiClient: client
})
var file = getTestDataDirectory();
file.append('test.png');
var item = yield Zotero.Attachments.importFromFile({ file });
var item = await Zotero.Attachments.importFromFile({ file });
item.version = 5;
item.synced = true;
yield item.saveTx();
await item.saveTx();
var responses = 0;
server.respond(function (req) {
@ -1181,7 +1180,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
}
})
var e = yield getPromiseError(zfs._processUploadFile({
var e = await getPromiseError(zfs._processUploadFile({
name: item.libraryKey
}));
assert.ok(e);
@ -1191,7 +1190,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
assert.equal(responses, 1);
// Try again
var e = yield getPromiseError(zfs.uploadFile({
var e = await getPromiseError(zfs.uploadFile({
name: item.libraryKey,
engine
}));

View file

@ -1,6 +1,6 @@
"use strict";
describe("ZoteroPane", function() {
describe("ZoteroPane", function () {
var win, doc, zp, userLibraryID;
// Load Zotero pane and select library
@ -41,38 +41,38 @@ describe("ZoteroPane", function() {
});
describe("#newItem", function () {
it("should create an item and focus the title field", function* () {
yield zp.newItem(Zotero.ItemTypes.getID('book'), {}, null, true);
it("should create an item and focus the title field", async function () {
await zp.newItem(Zotero.ItemTypes.getID('book'), {}, null, true);
assert.equal(doc.activeElement.closest("editable-text").id, "itembox-field-value-title");
doc.activeElement.blur();
yield Zotero.Promise.delay(1);
await Zotero.Promise.delay(1);
})
it("should save an entered value when New Item is used", function* () {
it("should save an entered value when New Item is used", async function () {
var value = "Test";
var item = yield zp.newItem(Zotero.ItemTypes.getID('book'), {}, null, true);
var item = await zp.newItem(Zotero.ItemTypes.getID('book'), {}, null, true);
let header = doc.getElementById('zotero-item-pane-header');
let title = header.querySelector("editable-text");
title.value = value;
yield header.save();
item = yield Zotero.Items.getAsync(item.id);
await header.save();
item = await Zotero.Items.getAsync(item.id);
assert.equal(item.getField('title'), value);
})
});
describe("#newNote()", function () {
it("should create a child note and select it", function* () {
var item = yield createDataObject('item');
var noteID = yield zp.newNote(false, item.key, "Test");
it("should create a child note and select it", async function () {
var item = await createDataObject('item');
var noteID = await zp.newNote(false, item.key, "Test");
var selected = zp.itemsView.getSelectedItems(true);
assert.lengthOf(selected, 1);
assert.equal(selected, noteID);
})
it("should create a standalone note within a collection and select it", function* () {
var collection = yield createDataObject('collection');
yield select(win, collection);
var noteID = yield zp.newNote(false, false, "Test");
it("should create a standalone note within a collection and select it", async function () {
var collection = await createDataObject('collection');
await select(win, collection);
var noteID = await zp.newNote(false, false, "Test");
assert.equal(zp.collectionsView.getSelectedCollection(), collection);
var selected = zp.itemsView.getSelectedItems(true);
assert.lengthOf(selected, 1);
@ -81,42 +81,42 @@ describe("ZoteroPane", function() {
})
describe("#newCollection()", function () {
it("should create a collection", function* () {
it("should create a collection", async function () {
var promise = waitForDialog(
null,
'accept',
'chrome://zotero/content/newCollectionDialog.xhtml'
);
var id = yield zp.newCollection();
yield promise;
var id = await zp.newCollection();
await promise;
var collection = Zotero.Collections.get(id);
assert.isTrue(collection.name.startsWith(Zotero.getString('pane.collections.untitled')));
});
});
describe("#newSearch()", function () {
it("should create a saved search", function* () {
it("should create a saved search", async function () {
var promise = waitForDialog(
// TODO: Test changing a condition
function (dialog) {},
'accept',
'chrome://zotero/content/searchDialog.xhtml'
);
var id = yield zp.newSearch();
yield promise;
var id = await zp.newSearch();
await promise;
var search = Zotero.Searches.get(id);
assert.ok(search);
assert.isTrue(search.name.startsWith(Zotero.getString('pane.collections.untitled')));
});
it("should handle clicking Cancel in the search window", function* () {
it("should handle clicking Cancel in the search window", async function () {
var promise = waitForDialog(
function (dialog) {},
'cancel',
'chrome://zotero/content/searchDialog.xhtml'
);
var id = yield zp.newSearch();
yield promise;
var id = await zp.newSearch();
await promise;
assert.isFalse(id);
});
});
@ -244,9 +244,9 @@ describe("ZoteroPane", function() {
Zotero.HTTP.mock = null;
});
it("should download an attachment on-demand in as-needed mode", function* () {
it("should download an attachment on-demand in as-needed mode", async function () {
Zotero.Sync.Storage.Local.downloadAsNeeded(Zotero.Libraries.userLibraryID, true);
yield downloadOnDemand();
await downloadOnDemand();
});
// As noted in viewAttachment(), this is only necessary for files modified before 5.0.85
@ -341,9 +341,9 @@ describe("ZoteroPane", function() {
assert.equal(await Zotero.File.getContentsAsync(path), text);
});
it("should download an attachment on-demand in at-sync-time mode", function* () {
it("should download an attachment on-demand in at-sync-time mode", async function () {
Zotero.Sync.Storage.Local.downloadOnSync(Zotero.Libraries.userLibraryID, true);
yield downloadOnDemand();
await downloadOnDemand();
});
it("should update a PDF with a blank MIME type", async function () {
@ -758,7 +758,7 @@ describe("ZoteroPane", function() {
});
});
it("should not copy abstracts", async function() {
it("should not copy abstracts", async function () {
await selectLibrary(win);
var bookItem = await createDataObject('item', { itemType: 'book', title: "Book Title" });
bookItem.setField('abstractNote', 'An abstract');
@ -777,13 +777,13 @@ describe("ZoteroPane", function() {
await selectLibrary(win);
});
it("should remove an item from My Publications", function* () {
it("should remove an item from My Publications", async function () {
var item = createUnsavedDataObject('item');
item.inPublications = true;
yield item.saveTx();
await item.saveTx();
yield zp.collectionsView.selectByID("P" + userLibraryID);
yield waitForItemsLoad(win);
await zp.collectionsView.selectByID("P" + userLibraryID);
await waitForItemsLoad(win);
var iv = zp.itemsView;
var selected = iv.selectItem(item.id);
@ -792,7 +792,7 @@ describe("ZoteroPane", function() {
var tree = doc.getElementById(iv.id);
tree.focus();
yield Zotero.Promise.delay(1);
await Zotero.Promise.delay(1);
var promise = waitForDialog();
var modifyPromise = waitForItemEvent('modify');
@ -808,20 +808,20 @@ describe("ZoteroPane", function() {
}
);
tree.dispatchEvent(event);
yield promise;
yield modifyPromise;
await promise;
await modifyPromise;
assert.isFalse(item.inPublications);
assert.isFalse(item.deleted);
});
it("should move My Publications item to trash with prompt for modified Delete", function* () {
it("should move My Publications item to trash with prompt for modified Delete", async function () {
var item = createUnsavedDataObject('item');
item.inPublications = true;
yield item.saveTx();
await item.saveTx();
yield zp.collectionsView.selectByID("P" + userLibraryID);
yield waitForItemsLoad(win);
await zp.collectionsView.selectByID("P" + userLibraryID);
await waitForItemsLoad(win);
var iv = zp.itemsView;
var selected = iv.selectItem(item.id);
@ -830,7 +830,7 @@ describe("ZoteroPane", function() {
var tree = doc.getElementById(iv.id);
tree.focus();
yield Zotero.Promise.delay(1);
await Zotero.Promise.delay(1);
var promise = waitForDialog();
var modifyPromise = waitForItemEvent('modify');
@ -848,8 +848,8 @@ describe("ZoteroPane", function() {
}
);
tree.dispatchEvent(event);
yield promise;
yield modifyPromise;
await promise;
await modifyPromise;
assert.isTrue(item.inPublications);
assert.isTrue(item.deleted);
@ -958,23 +958,23 @@ describe("ZoteroPane", function() {
});
describe("#deleteSelectedCollection()", function () {
it("should move collection to trash but not descendant items by default", function* () {
var collection = yield createDataObject('collection');
yield select(win, collection);
var item = yield createDataObject('item', { collections: [collection.id] });
it("should move collection to trash but not descendant items by default", async function () {
var collection = await createDataObject('collection');
await select(win, collection);
var item = await createDataObject('item', { collections: [collection.id] });
var promise = waitForDialog();
yield zp.deleteSelectedCollection();
await zp.deleteSelectedCollection();
assert.isTrue(collection.deleted);
assert.isTrue(Zotero.Items.exists(item.id));
assert.isFalse(item.deleted);
});
it("should move to trash collection and descendant items when deleteItems=true", function* () {
var collection = yield createDataObject('collection');
yield select(win, collection);
var item = yield createDataObject('item', { collections: [collection.id] });
it("should move to trash collection and descendant items when deleteItems=true", async function () {
var collection = await createDataObject('collection');
await select(win, collection);
var item = await createDataObject('item', { collections: [collection.id] });
var promise = waitForDialog();
yield zp.deleteSelectedCollection(true);
await zp.deleteSelectedCollection(true);
assert.isTrue(collection.deleted);
assert.isTrue(Zotero.Items.exists(item.id));
assert.isTrue(item.deleted);
@ -994,21 +994,21 @@ describe("ZoteroPane", function() {
return selectLibrary(win);
})
it("should show a hidden virtual collection in My Library", function* () {
it("should show a hidden virtual collection in My Library", async function () {
// Create unfiled, duplicate items
var title = Zotero.Utilities.randomString();
var item1 = yield createDataObject('item', { title });
var item2 = yield createDataObject('item', { title });
var item1 = await createDataObject('item', { title });
var item2 = await createDataObject('item', { title });
// Start hidden (tested in collectionTreeViewTest)
Zotero.Prefs.set('duplicateLibraries', `{"${userLibraryID}": false}`);
Zotero.Prefs.set('unfiledLibraries', `{"${userLibraryID}": false}`);
yield cv.refresh();
await cv.refresh();
// Show Duplicate Items
var id = "D" + userLibraryID;
assert.isFalse(cv.getRowIndexByID(id));
yield zp.setVirtual(userLibraryID, 'duplicates', true, true);
await zp.setVirtual(userLibraryID, 'duplicates', true, true);
// Duplicate Items should be selected
assert.equal(zp.getCollectionTreeRow().id, id);
// Should be missing from pref
@ -1018,73 +1018,73 @@ describe("ZoteroPane", function() {
var row = cv.getRowIndexByID(id);
assert.ok(row);
assert.equal(cv.selection.pivot, row);
yield waitForItemsLoad(win);
await waitForItemsLoad(win);
var iv = zp.itemsView;
row = iv.getRowIndexByID(item1.id);
assert.isNumber(row);
var promise = iv.waitForSelect();
clickOnItemsRow(win, iv, row);
assert.equal(iv.selection.count, 2);
yield promise;
await promise;
// Show Unfiled Items
id = "U" + userLibraryID;
assert.isFalse(cv.getRowIndexByID(id));
yield zp.setVirtual(userLibraryID, 'unfiled', true, true);
await zp.setVirtual(userLibraryID, 'unfiled', true, true);
// Unfiled Items should be selected
assert.equal(zp.getCollectionTreeRow().id, id);
// Should be missing from pref
assert.isUndefined(JSON.parse(Zotero.Prefs.get('unfiledLibraries'))[userLibraryID])
});
it("should expand library if collapsed when showing virtual collection", function* () {
it("should expand library if collapsed when showing virtual collection", async function () {
// Start hidden (tested in collectionTreeViewTest)
Zotero.Prefs.set('duplicateLibraries', `{"${userLibraryID}": false}`);
yield cv.refresh();
await cv.refresh();
var libraryRow = cv.getRowIndexByID(Zotero.Libraries.userLibrary.treeViewID);
if (cv.isContainerOpen(libraryRow)) {
yield cv.toggleOpenState(libraryRow);
await cv.toggleOpenState(libraryRow);
cv._saveOpenStates();
}
// Show Duplicate Items
var id = "D" + userLibraryID;
yield zp.setVirtual(userLibraryID, 'duplicates', true, true);
await zp.setVirtual(userLibraryID, 'duplicates', true, true);
// Library should have been expanded and Duplicate Items selected
assert.ok(cv.getRowIndexByID(id));
assert.equal(zp.getCollectionTreeRow().id, id);
});
it("should hide a virtual collection in My Library", function* () {
yield cv.refresh();
it("should hide a virtual collection in My Library", async function () {
await cv.refresh();
// Hide Duplicate Items
var id = "D" + userLibraryID;
assert.ok(yield cv.selectByID(id));
yield zp.setVirtual(userLibraryID, 'duplicates', false);
assert.ok(await cv.selectByID(id));
await zp.setVirtual(userLibraryID, 'duplicates', false);
assert.isFalse(cv.getRowIndexByID(id));
assert.isFalse(JSON.parse(Zotero.Prefs.get('duplicateLibraries'))[userLibraryID])
// Hide Unfiled Items
id = "U" + userLibraryID;
assert.ok(yield cv.selectByID(id));
yield zp.setVirtual(userLibraryID, 'unfiled', false);
assert.ok(await cv.selectByID(id));
await zp.setVirtual(userLibraryID, 'unfiled', false);
assert.isFalse(cv.getRowIndexByID(id));
assert.isFalse(JSON.parse(Zotero.Prefs.get('unfiledLibraries'))[userLibraryID])
});
it("should hide a virtual collection in a group", function* () {
yield cv.refresh();
it("should hide a virtual collection in a group", async function () {
await cv.refresh();
var group = yield createGroup();
var group = await createGroup();
var groupRow = cv.getRowIndexByID(group.treeViewID);
var rowCount = cv._rows.length;
// Make sure group is open
if (!cv.isContainerOpen(groupRow)) {
yield cv.toggleOpenState(groupRow);
await cv.toggleOpenState(groupRow);
}
// Make sure Duplicate Items is showing
@ -1092,8 +1092,8 @@ describe("ZoteroPane", function() {
assert.ok(cv.getRowIndexByID(id));
// Hide Duplicate Items
assert.ok(yield cv.selectByID(id));
yield zp.setVirtual(group.libraryID, 'duplicates', false);
assert.ok(await cv.selectByID(id));
await zp.setVirtual(group.libraryID, 'duplicates', false);
// Row should have been removed
assert.isFalse(cv.getRowIndexByID(id));
// Pref should have been updated
@ -1108,9 +1108,9 @@ describe("ZoteroPane", function() {
// Hide Unfiled Items
id = "U" + group.libraryID;
assert.ok(yield cv.selectByID(id));
assert.ok(await cv.selectByID(id));
// Hide Unfiled Items
yield zp.setVirtual(group.libraryID, 'unfiled', false);
await zp.setVirtual(group.libraryID, 'unfiled', false);
// Row should have been removed
assert.isFalse(cv.getRowIndexByID(id));
// Pref should have been updated
@ -1125,9 +1125,9 @@ describe("ZoteroPane", function() {
});
describe("#editSelectedCollection()", function () {
it("should edit a saved search", function* () {
var search = yield createDataObject('search');
yield select(win, search);
it("should edit a saved search", async function () {
var search = await createDataObject('search');
await select(win, search);
var promise = waitForWindow('chrome://zotero/content/searchDialog.xhtml', function (win) {
let searchBox = win.document.getElementById('search-box');
var c = searchBox.search.getCondition(
@ -1136,16 +1136,16 @@ describe("ZoteroPane", function() {
searchBox.addCondition(c);
win.document.querySelector('dialog').acceptDialog();
});
yield zp.editSelectedCollection();
yield promise;
await zp.editSelectedCollection();
await promise;
var conditions = search.getConditions();
assert.lengthOf(Object.keys(conditions), 3);
});
it("should edit a saved search in a group", function* () {
var group = yield getGroup();
var search = yield createDataObject('search', { libraryID: group.libraryID });
yield select(win, search);
it("should edit a saved search in a group", async function () {
var group = await getGroup();
var search = await createDataObject('search', { libraryID: group.libraryID });
await select(win, search);
var promise = waitForWindow('chrome://zotero/content/searchDialog.xhtml', function (win) {
let searchBox = win.document.getElementById('search-box');
var c = searchBox.search.getCondition(
@ -1154,8 +1154,8 @@ describe("ZoteroPane", function() {
searchBox.addCondition(c);
win.document.querySelector('dialog').acceptDialog();
});
yield zp.editSelectedCollection();
yield promise;
await zp.editSelectedCollection();
await promise;
var conditions = search.getConditions();
assert.lengthOf(Object.keys(conditions), 3);
});
@ -1804,7 +1804,7 @@ describe("ZoteroPane", function() {
});
});
describe("#changeParentItem", function () {
it("should update the parent of selected items", async function() {
it("should update the parent of selected items", async function () {
// One item has 2 children and the other one - none
let oldParent = await createDataObject('item');
let newParent = await createDataObject('item');
@ -1835,7 +1835,7 @@ describe("ZoteroPane", function() {
assert.notInclude(oldParent.getAttachments(), attachment.id);
});
it("should allow converting attachments to standalone when applicable", async function() {
it("should allow converting attachments to standalone when applicable", async function () {
let collection = await createDataObject('collection');
let parent = await createDataObject('item', { collections: [collection.id] });
var attachment = await importPDFAttachment(parent);