Merge branch 'deasyncification'

This commit is contained in:
Dan Stillman 2016-03-16 02:02:41 -04:00
commit a949d6bf8d
77 changed files with 2622 additions and 2125 deletions

View file

@ -137,6 +137,8 @@ function Reporter(runner) {
dump("\r" + indentStr
// Dark red X for errors
+ "\033[31;40m" + Mocha.reporters.Base.symbols.err + " [FAIL]\033[0m"
// Trigger bell if interactive
+ (Zotero.noUserInput ? "" : "\007")
+ " " + test.title + "\n"
+ indentStr + " " + err.toString() + " at\n"
+ err.stack.replace(/^/gm, indentStr + " "));

View file

@ -251,6 +251,33 @@ function waitForCallback(cb, interval, timeout) {
}
function clickOnItemsRow(itemsView, row, button = 0) {
var x = {};
var y = {};
var width = {};
var height = {};
itemsView._treebox.getCoordsForCellItem(
row,
itemsView._treebox.columns.getNamedColumn('zotero-items-column-title'),
'text',
x, y, width, height
);
// Select row to trigger multi-select
var tree = itemsView._treebox.treeBody;
var rect = tree.getBoundingClientRect();
var x = rect.left + x.value;
var y = rect.top + y.value;
tree.dispatchEvent(new MouseEvent("mousedown", {
clientX: x,
clientY: y,
button,
detail: 1
}));
}
/**
* Get a default group used by all tests that want one, creating one if necessary
*/
@ -352,10 +379,9 @@ function getNameProperty(objectType) {
return objectType == 'item' ? 'title' : 'name';
}
var modifyDataObject = Zotero.Promise.coroutine(function* (obj, params = {}, saveOptions) {
var modifyDataObject = function (obj, params = {}, saveOptions) {
switch (obj.objectType) {
case 'item':
yield obj.loadItemData();
obj.setField(
'title',
params.title !== undefined ? params.title : Zotero.Utilities.randomString()
@ -366,7 +392,7 @@ var modifyDataObject = Zotero.Promise.coroutine(function* (obj, params = {}, sav
obj.name = params.name !== undefined ? params.name : Zotero.Utilities.randomString();
}
return obj.saveTx(saveOptions);
});
};
/**
* Return a promise for the error thrown by a promise, or false if none
@ -584,7 +610,7 @@ var generateItemJSONData = Zotero.Promise.coroutine(function* generateItemJSONDa
for (let itemName in items) {
let zItem = yield Zotero.Items.getAsync(items[itemName].id);
jsonData[itemName] = yield zItem.toJSON(options);
jsonData[itemName] = zItem.toJSON(options);
// Don't replace some fields that _always_ change (e.g. item keys)
// as long as it follows expected format

@ -1 +1 @@
Subproject commit b369f252432c3486a66a0e93f441e4abb133d229
Subproject commit 775281e138df26101fba1e554c516f47438851b5

@ -1 +1 @@
Subproject commit 2a8594424c73ffeca41ef1668446372160528b4a
Subproject commit 44b0045463907b1d7963a2e9560c24d9552aac5d

View file

@ -152,7 +152,6 @@ describe("Zotero.Collection", function() {
var collection2 = yield createDataObject('collection', { parentID: collection1.id });
yield collection1.saveTx();
yield collection1.loadChildCollections();
var childCollections = collection1.getChildCollections();
assert.lengthOf(childCollections, 1);
assert.equal(childCollections[0].id, collection2.id);
@ -163,8 +162,6 @@ describe("Zotero.Collection", function() {
var collection2 = yield createDataObject('collection', { parentID: collection1.id });
yield collection1.saveTx();
yield collection1.loadChildCollections();
collection2.parentID = false;
yield collection2.save()
@ -180,7 +177,6 @@ describe("Zotero.Collection", function() {
item.addToCollection(collection.key);
yield item.saveTx();
yield collection.loadChildItems();
assert.lengthOf(collection.getChildItems(), 1);
})
@ -191,7 +187,6 @@ describe("Zotero.Collection", function() {
item.addToCollection(collection.key);
yield item.saveTx();
yield collection.loadChildItems();
assert.lengthOf(collection.getChildItems(), 0);
})
@ -202,7 +197,6 @@ describe("Zotero.Collection", function() {
item.addToCollection(collection.key);
yield item.saveTx();
yield collection.loadChildItems();
assert.lengthOf(collection.getChildItems(false, true), 1);
})
})

View file

@ -1,12 +1,13 @@
"use strict";
describe("Zotero.CollectionTreeView", function() {
var win, zp, cv;
var win, zp, cv, userLibraryID;
before(function* () {
win = yield loadZoteroPane();
zp = win.ZoteroPane;
cv = zp.collectionsView;
userLibraryID = Zotero.Libraries.userLibraryID;
});
beforeEach(function () {
// TODO: Add a selectCollection() function and select a collection instead?
@ -16,31 +17,52 @@ describe("Zotero.CollectionTreeView", function() {
win.close();
});
describe("#refresh()", function () {
it("should show Duplicate Items and Unfiled Items in My Library by default", function* () {
Zotero.Prefs.clear('duplicateLibraries');
Zotero.Prefs.clear('unfiledLibraries');
yield cv.refresh();
assert.ok(cv.getRowIndexByID("D" + userLibraryID));
assert.ok(cv.getRowIndexByID("U" + userLibraryID));
assert.equal(Zotero.Prefs.get('duplicateLibraries'), "" + userLibraryID);
assert.equal(Zotero.Prefs.get('unfiledLibraries'), "" + userLibraryID);
});
it("shouldn't show Duplicate Items and Unfiled Items if hidden", function* () {
Zotero.Prefs.set('duplicateLibraries', "");
Zotero.Prefs.set('unfiledLibraries', "");
yield cv.refresh();
assert.isFalse(cv.getRowIndexByID("D" + userLibraryID));
assert.isFalse(cv.getRowIndexByID("U" + userLibraryID));
assert.strictEqual(Zotero.Prefs.get('duplicateLibraries'), "");
assert.strictEqual(Zotero.Prefs.get('unfiledLibraries'), "");
});
});
describe("collapse/expand", function () {
it("should close and open My Library repeatedly", function* () {
var libraryID = Zotero.Libraries.userLibraryID;
yield cv.selectLibrary(libraryID);
yield cv.selectLibrary(userLibraryID);
var row = cv.selection.currentIndex;
cv.collapseLibrary(libraryID);
cv.collapseLibrary(userLibraryID);
var nextRow = cv.getRow(row + 1);
assert.equal(cv.selection.currentIndex, row);
assert.ok(nextRow.isSeparator());
assert.isFalse(cv.isContainerOpen(row));
yield cv.expandLibrary(libraryID);
yield cv.expandLibrary(userLibraryID);
nextRow = cv.getRow(row + 1);
assert.equal(cv.selection.currentIndex, row);
assert.ok(!nextRow.isSeparator());
assert.ok(cv.isContainerOpen(row));
cv.collapseLibrary(libraryID);
cv.collapseLibrary(userLibraryID);
nextRow = cv.getRow(row + 1);
assert.equal(cv.selection.currentIndex, row);
assert.ok(nextRow.isSeparator());
assert.isFalse(cv.isContainerOpen(row));
yield cv.expandLibrary(libraryID);
yield cv.expandLibrary(userLibraryID);
nextRow = cv.getRow(row + 1);
assert.equal(cv.selection.currentIndex, row);
assert.ok(!nextRow.isSeparator());
@ -74,13 +96,13 @@ describe("Zotero.CollectionTreeView", function() {
var row = cv.selection.currentIndex;
var treeRow = cv.getRow(row);
assert.ok(treeRow.isTrash());
assert.equal(treeRow.ref.libraryID, Zotero.Libraries.userLibraryID);
assert.equal(treeRow.ref.libraryID, userLibraryID);
})
})
describe("#selectWait()", function () {
it("shouldn't hang if row is already selected", function* () {
var row = cv.getRowIndexByID("T" + Zotero.Libraries.userLibraryID);
var row = cv.getRowIndexByID("T" + userLibraryID);
cv.selection.select(row);
yield Zotero.Promise.delay(50);
yield cv.selectWait(row);
@ -108,7 +130,7 @@ describe("Zotero.CollectionTreeView", function() {
});
// Library should still be selected
assert.equal(cv.getSelectedLibraryID(), Zotero.Libraries.userLibraryID);
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
});
it("shouldn't select a new collection if skipSelect is passed", function* () {
@ -120,7 +142,7 @@ describe("Zotero.CollectionTreeView", function() {
});
// Library should still be selected
assert.equal(cv.getSelectedLibraryID(), Zotero.Libraries.userLibraryID);
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
});
it("shouldn't select a modified collection", function* () {
@ -135,7 +157,7 @@ describe("Zotero.CollectionTreeView", function() {
yield collection.saveTx();
// Modified collection should not be selected
assert.equal(cv.getSelectedLibraryID(), Zotero.Libraries.userLibraryID);
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
});
it("should maintain selection on a selected modified collection", function* () {
@ -217,8 +239,8 @@ describe("Zotero.CollectionTreeView", function() {
var collectionRow = cv._rowMap["C" + collectionID];
var searchRow = cv._rowMap["S" + searchID];
var duplicatesRow = cv._rowMap["D" + Zotero.Libraries.userLibraryID];
var unfiledRow = cv._rowMap["U" + Zotero.Libraries.userLibraryID];
var duplicatesRow = cv._rowMap["D" + userLibraryID];
var unfiledRow = cv._rowMap["U" + userLibraryID];
assert.isAbove(searchRow, collectionRow);
// If there's a duplicates row or an unfiled row, add before those.
@ -230,7 +252,7 @@ describe("Zotero.CollectionTreeView", function() {
assert.isBelow(searchRow, unfiledRow);
}
else {
var trashRow = cv._rowMap["T" + Zotero.Libraries.userLibraryID];
var trashRow = cv._rowMap["T" + userLibraryID];
assert.isBelow(searchRow, trashRow);
}
})
@ -238,7 +260,7 @@ describe("Zotero.CollectionTreeView", function() {
it("shouldn't select a new group", function* () {
var group = yield createGroup();
// Library should still be selected
assert.equal(cv.getSelectedLibraryID(), Zotero.Libraries.userLibraryID);
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
})
it("should remove a group and all children", function* () {
@ -390,12 +412,6 @@ describe("Zotero.CollectionTreeView", function() {
parentItemID: item.id
});
// Hack to unload relations to test proper loading
//
// Probably need a better method for this
item._loaded.relations = false;
attachment._loaded.relations = false;
var ids = (yield drop('item', 'L' + group.libraryID, [item.id])).ids;
yield cv.selectLibrary(group.libraryID);
@ -413,7 +429,7 @@ describe("Zotero.CollectionTreeView", function() {
// Check attachment
assert.isTrue(itemsView.isContainer(0));
yield itemsView.toggleOpenState(0);
itemsView.toggleOpenState(0);
assert.equal(itemsView.rowCount, 2);
treeRow = itemsView.getRow(1);
assert.equal(treeRow.ref.id, ids[1]);

View file

@ -0,0 +1,21 @@
"use strict";
describe("Zotero.Creators", function() {
describe("#getIDFromData()", function () {
it("should create creator and cache data", function* () {
var data1 = {
firstName: "First",
lastName: "Last"
};
var creatorID;
yield Zotero.DB.executeTransaction(function* () {
creatorID = yield Zotero.Creators.getIDFromData(data1, true);
});
assert.typeOf(creatorID, 'number');
var data2 = Zotero.Creators.get(creatorID);
assert.isObject(data2);
assert.propertyVal(data2, "firstName", data1.firstName);
assert.propertyVal(data2, "lastName", data1.lastName);
});
});
});

View file

@ -56,7 +56,6 @@ describe("Zotero.DataObject", function() {
yield obj.saveTx();
if (type == 'item') {
yield obj.loadItemData();
obj.setField('title', Zotero.Utilities.randomString());
}
else {
@ -131,7 +130,6 @@ describe("Zotero.DataObject", function() {
yield obj.saveTx();
if (type == 'item') {
yield obj.loadItemData();
obj.setField('title', Zotero.Utilities.randomString());
}
else {
@ -294,7 +292,7 @@ describe("Zotero.DataObject", function() {
let obj = yield createDataObject(type);
let libraryID = obj.libraryID;
let key = obj.key;
let json = yield obj.toJSON();
let json = obj.toJSON();
yield Zotero.Sync.Data.Local.saveCacheObjects(type, libraryID, [json]);
yield obj.eraseTx();
let versions = yield Zotero.Sync.Data.Local.getCacheObjectVersions(

View file

@ -25,11 +25,11 @@ describe("Zotero.DataObjectUtilities", function() {
yield Zotero.DB.executeTransaction(function* () {
var item = new Zotero.Item('book');
id1 = yield item.save();
json1 = yield item.toJSON();
json1 = item.toJSON();
var item = new Zotero.Item('book');
id2 = yield item.save();
json2 = yield item.toJSON();
json2 = item.toJSON();
});
var changes = Zotero.DataObjectUtilities.diff(json1, json2);

View file

@ -1,4 +1,33 @@
describe("Zotero.Date", function() {
describe("#sqlToDate()", function () {
it("should convert an SQL local date into a JS Date object", function* () {
var d1 = new Date();
var sqlDate = d1.getFullYear()
+ '-'
+ Zotero.Utilities.lpad(d1.getMonth() + 1, '0', 2)
+ '-'
+ Zotero.Utilities.lpad(d1.getDate(), '0', 2)
+ ' '
+ Zotero.Utilities.lpad(d1.getHours(), '0', 2)
+ ':'
+ Zotero.Utilities.lpad(d1.getMinutes(), '0', 2)
+ ':'
+ Zotero.Utilities.lpad(d1.getSeconds(), '0', 2);
var offset = d1.getTimezoneOffset() * 60 * 1000;
var d2 = Zotero.Date.sqlToDate(sqlDate);
assert.equal(
Zotero.Date.sqlToDate(sqlDate).getTime(),
Math.floor(new Date().getTime() / 1000) * 1000
);
})
it("should convert an SQL UTC date into a JS Date object", function* () {
var date = "2016-02-27 22:00:00";
date = Zotero.Date.sqlToDate(date, true);
assert.equal(date.getTime(), 1456610400000);
})
})
describe("#isISODate()", function () {
it("should determine whether a date is an ISO 8601 date", function () {
assert.ok(Zotero.Date.isISODate("2015"));

View file

@ -0,0 +1,56 @@
"use strict";
describe("Duplicate Items", function () {
var win, zp, cv;
beforeEach(function* () {
Zotero.Prefs.clear('duplicateLibraries');
win = yield loadZoteroPane();
zp = win.ZoteroPane;
cv = zp.collectionsView;
return selectLibrary(win);
})
after(function () {
if (win) {
win.close();
}
});
describe("Merging", function () {
it("should merge two items in duplicates view", function* () {
var item1 = yield createDataObject('item', { setTitle: true });
var item2 = item1.clone();
yield item2.saveTx();
var uri2 = Zotero.URI.getItemURI(item2);
var userLibraryID = Zotero.Libraries.userLibraryID;
var selected = yield cv.selectByID('D' + userLibraryID);
assert.ok(selected);
yield waitForItemsLoad(win);
// Select the first item, which should select both
var iv = zp.itemsView;
var row = iv.getRowIndexByID(item1.id);
assert.isNumber(row);
clickOnItemsRow(iv, row);
assert.equal(iv.selection.count, 2);
// Click merge button
var button = win.document.getElementById('zotero-duplicates-merge-button');
button.click();
yield waitForNotifierEvent('refresh', 'trash');
// Items should be gone
assert.isFalse(iv.getRowIndexByID(item1.id));
assert.isFalse(iv.getRowIndexByID(item2.id));
assert.isTrue(item2.deleted);
var rels = item1.getRelations();
var pred = Zotero.Relations.replacedItemPredicate;
assert.property(rels, pred);
assert.equal(rels[pred], uri2);
});
});
});

View file

@ -21,7 +21,7 @@ describe("Zotero_File_Interface", function() {
let childItems = importedCollection[0].getChildItems();
let savedItems = {};
for (let i=0; i<childItems.length; i++) {
let savedItem = yield childItems[i].toJSON();
let savedItem = childItems[i].toJSON();
delete savedItem.dateAdded;
delete savedItem.dateModified;
delete savedItem.key;

View file

@ -135,13 +135,52 @@ describe("Zotero.Item", function () {
item = yield Zotero.Items.getAsync(id);
assert.equal(item.getField("versionNumber"), "1.0");
});
it("should accept ISO 8601 dates", function* () {
var fields = {
accessDate: "2015-06-07T20:56:00Z",
dateAdded: "2015-06-07T20:57:00Z",
dateModified: "2015-06-07T20:58:00Z",
};
var item = createUnsavedDataObject('item');
for (let i in fields) {
item.setField(i, fields[i]);
}
assert.equal(item.getField('accessDate'), '2015-06-07 20:56:00');
assert.equal(item.dateAdded, '2015-06-07 20:57:00');
assert.equal(item.dateModified, '2015-06-07 20:58:00');
})
it("should accept SQL dates", function* () {
var fields = {
accessDate: "2015-06-07 20:56:00",
dateAdded: "2015-06-07 20:57:00",
dateModified: "2015-06-07 20:58:00",
};
var item = createUnsavedDataObject('item');
for (let i in fields) {
item.setField(i, fields[i]);
item.getField(i, fields[i]);
}
})
it("should ignore unknown accessDate values", function* () {
var fields = {
accessDate: "foo"
};
var item = createUnsavedDataObject('item');
for (let i in fields) {
item.setField(i, fields[i]);
}
assert.strictEqual(item.getField('accessDate'), '');
})
})
describe("#dateAdded", function () {
it("should use current time if value was not given for a new item", function* () {
var item = new Zotero.Item('book');
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
item = Zotero.Items.get(id);
assert.closeTo(Zotero.Date.sqlToDate(item.dateAdded, true).getTime(), Date.now(), 2000);
})
@ -184,10 +223,9 @@ describe("Zotero.Item", function () {
var item = new Zotero.Item('book');
item.dateModified = dateModified;
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
item = Zotero.Items.get(id);
// Save again without changing Date Modified
yield item.loadItemData();
item.setField('title', 'Test');
yield item.saveTx()
@ -199,10 +237,9 @@ describe("Zotero.Item", function () {
var item = new Zotero.Item('book');
item.dateModified = dateModified;
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
item = Zotero.Items.get(id);
// Set Date Modified to existing value
yield item.loadItemData();
item.setField('title', 'Test');
item.dateModified = dateModified;
yield item.saveTx()
@ -223,10 +260,9 @@ describe("Zotero.Item", function () {
var item = new Zotero.Item('book');
item.dateModified = dateModified;
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
item = Zotero.Items.get(id);
// Resave with skipDateModifiedUpdate
yield item.loadItemData();
item.setField('title', 'Test');
yield item.saveTx({
skipDateModifiedUpdate: true
@ -353,8 +389,7 @@ describe("Zotero.Item", function () {
var item = new Zotero.Item("journalArticle");
item.setCreators(creators);
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
yield item.loadCreators();
item = Zotero.Items.get(id);
assert.sameDeepMembers(item.getCreatorsJSON(), creators);
})
@ -377,8 +412,7 @@ describe("Zotero.Item", function () {
var item = new Zotero.Item("journalArticle");
item.setCreators(creators);
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
yield item.loadCreators();
item = Zotero.Items.get(id);
assert.sameDeepMembers(item.getCreators(), creators);
})
})
@ -614,11 +648,8 @@ describe("Zotero.Item", function () {
// File should be flagged for upload
// DEBUG: Is this necessary?
assert.equal(
(yield Zotero.Sync.Storage.Local.getSyncState(item.id)),
Zotero.Sync.Storage.Local.SYNC_STATE_TO_UPLOAD
);
assert.isNull(yield Zotero.Sync.Storage.Local.getSyncedHash(item.id));
assert.equal(item.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_TO_UPLOAD);
assert.isNull(item.attachmentSyncedHash);
})
})
@ -686,8 +717,7 @@ describe("Zotero.Item", function () {
var item = new Zotero.Item('journalArticle');
item.setTags(tags);
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
yield item.loadTags();
item = Zotero.Items.get(id);
assert.sameDeepMembers(item.getTags(tags), tags);
})
@ -703,8 +733,7 @@ describe("Zotero.Item", function () {
var item = new Zotero.Item('journalArticle');
item.setTags(tags);
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
yield item.loadTags();
item = Zotero.Items.get(id);
item.setTags(tags);
assert.isFalse(item.hasChanged());
})
@ -721,8 +750,7 @@ describe("Zotero.Item", function () {
var item = new Zotero.Item('journalArticle');
item.setTags(tags);
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
yield item.loadTags();
item = Zotero.Items.get(id);
item.setTags(tags.slice(0));
yield item.saveTx();
assert.sameDeepMembers(item.getTags(tags), tags.slice(0));
@ -825,6 +853,38 @@ describe("Zotero.Item", function () {
})
})
describe("#multiDiff", function () {
it("should return set of alternatives for differing fields in other items", function* () {
var type = 'item';
var dates = ['2016-03-08 17:44:45'];
var accessDates = ['2016-03-08T18:44:45Z'];
var urls = ['http://www.example.com', 'http://example.net'];
var obj1 = createUnsavedDataObject(type);
obj1.setField('date', '2016-03-07 12:34:56'); // different in 1 and 3, not in 2
obj1.setField('url', 'http://example.com'); // different in all three
obj1.setField('title', 'Test'); // only in 1
var obj2 = createUnsavedDataObject(type);
obj2.setField('url', urls[0]);
obj2.setField('accessDate', accessDates[0]); // only in 2
var obj3 = createUnsavedDataObject(type);
obj3.setField('date', dates[0]);
obj3.setField('url', urls[1]);
var alternatives = obj1.multiDiff([obj2, obj3]);
assert.sameMembers(Object.keys(alternatives), ['url', 'date', 'accessDate']);
assert.sameMembers(alternatives.url, urls);
assert.sameMembers(alternatives.date, dates);
assert.sameMembers(alternatives.accessDate, accessDates);
});
});
describe("#clone()", function () {
// TODO: Expand to other data
it("should copy creators", function* () {
@ -837,7 +897,7 @@ describe("Zotero.Item", function () {
}
]);
yield item.saveTx();
var newItem = yield item.clone();
var newItem = item.clone();
assert.sameDeepMembers(item.getCreators(), newItem.getCreators());
})
})
@ -851,8 +911,8 @@ describe("Zotero.Item", function () {
var item = new Zotero.Item(itemType);
item.setField("title", title);
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
var json = yield item.toJSON();
item = Zotero.Items.get(id);
var json = item.toJSON();
assert.equal(json.itemType, itemType);
assert.equal(json.title, title);
@ -868,13 +928,13 @@ describe("Zotero.Item", function () {
item.setField("title", title);
item.deleted = true;
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
var json = yield item.toJSON();
item = Zotero.Items.get(id);
var json = item.toJSON();
assert.strictEqual(json.deleted, 1);
})
it("should output attachment fields from file", function* () {
it.skip("should output attachment fields from file", function* () {
var file = getTestDataDirectory();
file.append('test.png');
var item = yield Zotero.Attachments.importFromFile({ file });
@ -888,7 +948,7 @@ describe("Zotero.Item", function () {
);
});
var json = yield item.toJSON();
var json = item.toJSON();
assert.equal(json.linkMode, 'imported_file');
assert.equal(json.filename, 'test.png');
assert.isUndefined(json.path);
@ -905,24 +965,23 @@ describe("Zotero.Item", function () {
var mtime = new Date().getTime();
var md5 = 'b32e33f529942d73bea4ed112310f804';
yield Zotero.DB.executeTransaction(function* () {
yield Zotero.Sync.Storage.Local.setSyncedModificationTime(item.id, mtime);
yield Zotero.Sync.Storage.Local.setSyncedHash(item.id, md5);
});
item.attachmentSyncedModificationTime = mtime;
item.attachmentSyncedHash = md5;
yield item.saveTx({ skipAll: true });
var json = yield item.toJSON({
var json = item.toJSON({
syncedStorageProperties: true
});
assert.equal(json.mtime, mtime);
assert.equal(json.md5, md5);
})
it("should output unset storage properties as null", function* () {
it.skip("should output unset storage properties as null", function* () {
var item = new Zotero.Item('attachment');
item.attachmentLinkMode = 'imported_file';
item.fileName = 'test.txt';
var id = yield item.saveTx();
var json = yield item.toJSON();
var json = item.toJSON();
assert.isNull(json.mtime);
assert.isNull(json.md5);
@ -938,7 +997,7 @@ describe("Zotero.Item", function () {
item.setField("title", title);
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
var json = yield item.toJSON({ mode: 'full' });
var json = item.toJSON({ mode: 'full' });
assert.equal(json.title, title);
assert.equal(json.date, "");
assert.equal(json.numPages, "");
@ -955,11 +1014,11 @@ describe("Zotero.Item", function () {
item.setField("title", title);
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
var patchBase = yield item.toJSON();
var patchBase = item.toJSON();
item.setField("date", date);
yield item.saveTx();
var json = yield item.toJSON({
var json = item.toJSON({
patchBase: patchBase
})
assert.isUndefined(json.itemType);
@ -978,10 +1037,10 @@ describe("Zotero.Item", function () {
item.deleted = true;
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
var patchBase = yield item.toJSON();
var patchBase = item.toJSON();
item.deleted = false;
var json = yield item.toJSON({
var json = item.toJSON({
patchBase: patchBase
})
assert.isUndefined(json.title);
@ -992,10 +1051,10 @@ describe("Zotero.Item", function () {
item.deleted = false;
var id = yield item.saveTx();
item = yield Zotero.Items.getAsync(id);
var patchBase = yield item.toJSON();
var patchBase = item.toJSON();
item.deleted = true;
var json = yield item.toJSON({
var json = item.toJSON({
patchBase: patchBase
})
assert.isUndefined(json.title);

View file

@ -1,31 +1,31 @@
"use strict";
describe("Zotero.ItemTreeView", function() {
var win, zp, itemsView, existingItemID;
var win, zp, cv, itemsView, existingItemID;
// Load Zotero pane and select library
before(function* () {
win = yield loadZoteroPane();
zp = win.ZoteroPane;
cv = zp.collectionsView;
var item = new Zotero.Item('book');
existingItemID = yield item.saveTx();
});
beforeEach(function* () {
yield zp.collectionsView.selectLibrary();
yield waitForItemsLoad(win)
yield selectLibrary(win);
itemsView = zp.itemsView;
})
after(function () {
win.close();
});
it("shouldn't show items in trash", function* () {
it("shouldn't show items in trash in library root", function* () {
var item = yield createDataObject('item', { title: "foo" });
var itemID = item.id;
item.deleted = true;
yield item.saveTx();
assert.notOk(itemsView.getRowIndexByID(itemID));
assert.isFalse(itemsView.getRowIndexByID(itemID));
})
describe("#selectItem()", function () {
@ -45,6 +45,17 @@ describe("Zotero.ItemTreeView", function() {
});
})
describe("#getCellText()", function () {
it("should return new value after edit", function* () {
var str = Zotero.Utilities.randomString();
var item = yield createDataObject('item', { title: str });
var row = itemsView.getRowIndexByID(item.id);
assert.equal(itemsView.getCellText(row, { id: 'zotero-items-column-title' }), str);
yield modifyDataObject(item);
assert.notEqual(itemsView.getCellText(row, { id: 'zotero-items-column-title' }), str);
})
})
describe("#notify()", function () {
beforeEach(function () {
sinon.spy(win.ZoteroPane, "itemSelected");
@ -220,6 +231,22 @@ describe("Zotero.ItemTreeView", function() {
yield Zotero.Items.erase(items.map(item => item.id));
})
it("should remove items from Unfiled Items when added to a collection", function* () {
var userLibraryID = Zotero.Libraries.userLibraryID;
var collection = yield createDataObject('collection');
var item = yield createDataObject('item', { title: "Unfiled Item" });
yield zp.setVirtual(userLibraryID, 'unfiled', true);
var selected = yield cv.selectByID("U" + userLibraryID);
assert.ok(selected);
yield waitForItemsLoad(win);
assert.isNumber(zp.itemsView.getRowIndexByID(item.id));
yield Zotero.DB.executeTransaction(function* () {
yield collection.addItem(item.id);
});
assert.isFalse(zp.itemsView.getRowIndexByID(item.id));
});
})
describe("#drop()", function () {

View file

@ -150,6 +150,11 @@ describe("Zotero.Library", function() {
yield library.saveTx();
assert.isFalse(Zotero.Libraries.isEditable(library.libraryID));
});
it("should initialize library after creation", function* () {
let library = yield createGroup({});
Zotero.SyncedSettings.get(library.libraryID, "tagColors");
});
});
describe("#erase()", function() {
it("should erase a group library", function* () {

View file

@ -148,7 +148,7 @@ describe("Sync Preferences", function () {
var cont = yield win.Zotero_Preferences.Sync.checkUser(1, "A");
assert.isTrue(cont);
var json = yield item1.toJSON();
var json = item1.toJSON();
var uri = json.relations[Zotero.Relations.linkedObjectPredicate][0];
assert.notInclude(uri, 'users/local');
assert.include(uri, 'users/1/publications');

View file

@ -71,12 +71,10 @@ describe("Related Box", function () {
var item1 = yield createDataObject('item');
var item2 = yield createDataObject('item');
yield item1.loadRelations();
item1.addRelatedItem(item2);
yield item1.save();
yield item2.loadRelations();
yield item1.saveTx();
item2.addRelatedItem(item1);
yield item2.save();
yield item2.saveTx();
// Select the Related pane
var tabbox = doc.getElementById('zotero-view-tabbox');

View file

@ -14,16 +14,20 @@ describe("Zotero.Search", function() {
var s = new Zotero.Search;
s.name = "Test";
s.addCondition('title', 'is', 'test');
Zotero.debug("BEFORE SAVING");
Zotero.debug(s._conditions);
var id = yield s.saveTx();
Zotero.debug("DONE SAVING");
Zotero.debug(s._conditions);
assert.typeOf(id, 'number');
// Check saved search
s = yield Zotero.Searches.getAsync(id);
s = Zotero.Searches.get(id);
assert.ok(s);
assert.instanceOf(s, Zotero.Search);
assert.equal(s.libraryID, Zotero.Libraries.userLibraryID);
assert.equal(s.name, "Test");
yield s.loadConditions();
Zotero.debug("GETTING CONDITIONS");
var conditions = s.getConditions();
assert.lengthOf(Object.keys(conditions), 1);
assert.property(conditions, "0");
@ -45,14 +49,12 @@ describe("Zotero.Search", function() {
// Add condition
s = yield Zotero.Searches.getAsync(id);
yield s.loadConditions();
s.addCondition('title', 'contains', 'foo');
var saved = yield s.saveTx();
assert.isTrue(saved);
// Check saved search
s = yield Zotero.Searches.getAsync(id);
yield s.loadConditions();
var conditions = s.getConditions();
assert.lengthOf(Object.keys(conditions), 2);
});
@ -69,14 +71,12 @@ describe("Zotero.Search", function() {
// Remove condition
s = yield Zotero.Searches.getAsync(id);
yield s.loadConditions();
s.removeCondition(0);
var saved = yield s.saveTx();
assert.isTrue(saved);
// Check saved search
s = yield Zotero.Searches.getAsync(id);
yield s.loadConditions();
var conditions = s.getConditions();
assert.lengthOf(Object.keys(conditions), 1);
assert.property(conditions, "0");

View file

@ -28,11 +28,10 @@ describe("Zotero.Sync.Storage.Local", function () {
yield OS.File.setDates((yield item.getFilePathAsync()), null, mtime);
// Mark as synced, so it will be checked
yield Zotero.DB.executeTransaction(function* () {
yield Zotero.Sync.Storage.Local.setSyncedHash(item.id, hash);
yield Zotero.Sync.Storage.Local.setSyncedModificationTime(item.id, mtime);
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "in_sync");
});
item.attachmentSyncedModificationTime = mtime;
item.attachmentSyncedHash = hash;
item.attachmentSyncState = "in_sync";
yield item.saveTx({ skipAll: true });
// Update mtime and contents
var path = yield item.getFilePathAsync();
@ -46,10 +45,7 @@ describe("Zotero.Sync.Storage.Local", function () {
yield item.eraseTx();
assert.equal(changed, true);
assert.equal(
(yield Zotero.Sync.Storage.Local.getSyncState(item.id)),
Zotero.Sync.Storage.Local.SYNC_STATE_TO_UPLOAD
);
assert.equal(item.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_TO_UPLOAD);
})
it("should skip a file if mod time hasn't changed", function* () {
@ -59,15 +55,14 @@ describe("Zotero.Sync.Storage.Local", function () {
var mtime = yield item.attachmentModificationTime;
// Mark as synced, so it will be checked
yield Zotero.DB.executeTransaction(function* () {
yield Zotero.Sync.Storage.Local.setSyncedHash(item.id, hash);
yield Zotero.Sync.Storage.Local.setSyncedModificationTime(item.id, mtime);
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "in_sync");
});
item.attachmentSyncedModificationTime = mtime;
item.attachmentSyncedHash = hash;
item.attachmentSyncState = "in_sync";
yield item.saveTx({ skipAll: true });
var libraryID = Zotero.Libraries.userLibraryID;
var changed = yield Zotero.Sync.Storage.Local.checkForUpdatedFiles(libraryID);
var syncState = yield Zotero.Sync.Storage.Local.getSyncState(item.id);
var syncState = item.attachmentSyncState;
yield item.eraseTx();
@ -84,11 +79,10 @@ describe("Zotero.Sync.Storage.Local", function () {
yield OS.File.setDates((yield item.getFilePathAsync()), null, mtime);
// Mark as synced, so it will be checked
yield Zotero.DB.executeTransaction(function* () {
yield Zotero.Sync.Storage.Local.setSyncedHash(item.id, hash);
yield Zotero.Sync.Storage.Local.setSyncedModificationTime(item.id, mtime);
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "in_sync");
});
item.attachmentSyncedModificationTime = mtime;
item.attachmentSyncedHash = hash;
item.attachmentSyncState = "in_sync";
yield item.saveTx({ skipAll: true });
// Update mtime, but not contents
var path = yield item.getFilePathAsync();
@ -96,8 +90,8 @@ describe("Zotero.Sync.Storage.Local", function () {
var libraryID = Zotero.Libraries.userLibraryID;
var changed = yield Zotero.Sync.Storage.Local.checkForUpdatedFiles(libraryID);
var syncState = yield Zotero.Sync.Storage.Local.getSyncState(item.id);
var syncedModTime = yield Zotero.Sync.Storage.Local.getSyncedModificationTime(item.id);
var syncState = item.attachmentSyncState;
var syncedModTime = item.attachmentSyncedModificationTime;
var newModTime = yield item.attachmentModificationTime;
yield item.eraseTx();
@ -202,8 +196,8 @@ describe("Zotero.Sync.Storage.Local", function () {
item3.version = 11;
yield item3.saveTx();
var json1 = yield item1.toJSON();
var json3 = yield item3.toJSON();
var json1 = item1.toJSON();
var json3 = item3.toJSON();
// Change remote mtimes
// Round to nearest second because OS X doesn't support ms resolution
var now = Math.round(new Date().getTime() / 1000) * 1000;
@ -211,8 +205,10 @@ describe("Zotero.Sync.Storage.Local", function () {
json3.mtime = now - 20000;
yield Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json1, json3]);
yield Zotero.Sync.Storage.Local.setSyncState(item1.id, "in_conflict");
yield Zotero.Sync.Storage.Local.setSyncState(item3.id, "in_conflict");
item1.attachmentSyncState = "in_conflict";
yield item1.saveTx({ skipAll: true });
item3.attachmentSyncState = "in_conflict";
yield item3.saveTx({ skipAll: true });
var conflicts = yield Zotero.Sync.Storage.Local.getConflicts(libraryID);
assert.lengthOf(conflicts, 2);
@ -251,19 +247,17 @@ describe("Zotero.Sync.Storage.Local", function () {
item3.version = 11;
yield item3.saveTx();
var json1 = yield item1.toJSON();
var json3 = yield item3.toJSON();
var json1 = item1.toJSON();
var json3 = item3.toJSON();
// Change remote mtimes
json1.mtime = new Date().getTime() + 10000;
json3.mtime = new Date().getTime() - 10000;
yield Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json1, json3]);
yield Zotero.Sync.Storage.Local.setSyncState(
item1.id, "in_conflict"
);
yield Zotero.Sync.Storage.Local.setSyncState(
item3.id, "in_conflict"
);
item1.attachmentSyncState = "in_conflict";
yield item1.saveTx({ skipAll: true });
item3.attachmentSyncState = "in_conflict";
yield item3.saveTx({ skipAll: true });
var promise = waitForWindow('chrome://zotero/content/merge.xul', function (dialog) {
var doc = dialog.document;
@ -305,14 +299,8 @@ describe("Zotero.Sync.Storage.Local", function () {
yield Zotero.Sync.Storage.Local.resolveConflicts(libraryID);
yield promise;
yield assert.eventually.equal(
Zotero.Sync.Storage.Local.getSyncState(item1.id),
Zotero.Sync.Storage.Local.SYNC_STATE_FORCE_UPLOAD
);
yield assert.eventually.equal(
Zotero.Sync.Storage.Local.getSyncState(item3.id),
Zotero.Sync.Storage.Local.SYNC_STATE_FORCE_DOWNLOAD
);
assert.equal(item1.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_FORCE_UPLOAD);
assert.equal(item3.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_FORCE_DOWNLOAD);
})
})

View file

@ -239,10 +239,10 @@ describe("Zotero.Sync.Data.Engine", function () {
assert.equal(Zotero.Libraries.getVersion(userLibraryID), 3);
// Make sure local objects exist
var setting = yield Zotero.SyncedSettings.get(userLibraryID, "tagColors");
var setting = Zotero.SyncedSettings.get(userLibraryID, "tagColors");
assert.lengthOf(setting, 1);
assert.equal(setting[0].name, 'A');
var settingMetadata = yield Zotero.SyncedSettings.getMetadata(userLibraryID, "tagColors");
var settingMetadata = Zotero.SyncedSettings.getMetadata(userLibraryID, "tagColors");
assert.equal(settingMetadata.version, 2);
assert.isTrue(settingMetadata.synced);
@ -283,7 +283,7 @@ describe("Zotero.Sync.Data.Engine", function () {
for (let type of types) {
objects[type] = [yield createDataObject(type, { setTitle: true })];
objectVersions[type] = {};
objectResponseJSON[type] = yield Zotero.Promise.all(objects[type].map(o => o.toResponseJSON()));
objectResponseJSON[type] = objects[type].map(o => o.toResponseJSON());
}
server.respond(function (req) {
@ -457,12 +457,11 @@ describe("Zotero.Sync.Data.Engine", function () {
var mtime = new Date().getTime();
var md5 = '57f8a4fda823187b91e1191487b87fe6';
yield Zotero.DB.executeTransaction(function* () {
yield Zotero.Sync.Storage.Local.setSyncedModificationTime(item.id, mtime);
yield Zotero.Sync.Storage.Local.setSyncedHash(item.id, md5);
});
item.attachmentSyncedModificationTime = mtime;
item.attachmentSyncedHash = md5;
yield item.saveTx({ skipAll: true });
var itemResponseJSON = yield item.toResponseJSON();
var itemResponseJSON = item.toResponseJSON();
itemResponseJSON.version = itemResponseJSON.data.version = lastLibraryVersion;
itemResponseJSON.data.mtime = mtime;
itemResponseJSON.data.md5 = md5;
@ -520,7 +519,7 @@ describe("Zotero.Sync.Data.Engine", function () {
for (let type of types) {
objects[type] = [yield createDataObject(type, { setTitle: true })];
objectNames[type] = {};
objectResponseJSON[type] = yield Zotero.Promise.all(objects[type].map(o => o.toResponseJSON()));
objectResponseJSON[type] = objects[type].map(o => o.toResponseJSON());
}
server.respond(function (req) {
@ -569,7 +568,6 @@ describe("Zotero.Sync.Data.Engine", function () {
let version = o.version;
let name = objectNames[type][key];
if (type == 'item') {
yield o.loadItemData();
assert.equal(name, o.getField('title'));
}
else {
@ -675,7 +673,7 @@ describe("Zotero.Sync.Data.Engine", function () {
{
key: obj.key,
version: obj.version,
data: (yield obj.toJSON())
data: obj.toJSON()
}
]
);
@ -814,7 +812,7 @@ describe("Zotero.Sync.Data.Engine", function () {
yield engine._startDownload();
// Make sure objects were deleted
assert.isFalse(yield Zotero.SyncedSettings.get(userLibraryID, 'tagColors'));
assert.isNull(Zotero.SyncedSettings.get(userLibraryID, 'tagColors'));
assert.isFalse(Zotero.Collections.exists(collectionID));
assert.isFalse(Zotero.Searches.exists(searchID));
assert.isFalse(Zotero.Items.exists(itemID));
@ -903,7 +901,7 @@ describe("Zotero.Sync.Data.Engine", function () {
yield engine._startDownload();
// Make sure objects weren't deleted
assert.ok(yield Zotero.SyncedSettings.get(userLibraryID, 'tagColors'));
assert.ok(Zotero.SyncedSettings.get(userLibraryID, 'tagColors'));
assert.ok(Zotero.Collections.exists(collectionID));
assert.ok(Zotero.Searches.exists(searchID));
})
@ -1214,10 +1212,10 @@ describe("Zotero.Sync.Data.Engine", function () {
yield engine._fullSync();
// Check settings
var setting = yield Zotero.SyncedSettings.get(userLibraryID, "tagColors");
var setting = Zotero.SyncedSettings.get(userLibraryID, "tagColors");
assert.lengthOf(setting, 1);
assert.equal(setting[0].name, 'A');
var settingMetadata = yield Zotero.SyncedSettings.getMetadata(userLibraryID, "tagColors");
var settingMetadata = Zotero.SyncedSettings.getMetadata(userLibraryID, "tagColors");
assert.equal(settingMetadata.version, 2);
assert.isTrue(settingMetadata.synced);

View file

@ -105,7 +105,7 @@ describe("Zotero.Sync.Data.Local", function() {
for (let type of types) {
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
let obj = yield createDataObject(type);
let data = yield obj.toJSON();
let data = obj.toJSON();
data.key = obj.key;
data.version = 10;
let json = {
@ -130,7 +130,7 @@ describe("Zotero.Sync.Data.Local", function() {
var type = 'item';
let obj = yield createDataObject(type, { version: 5 });
let data = yield obj.toJSON();
let data = obj.toJSON();
yield Zotero.Sync.Data.Local.saveCacheObjects(
type, libraryID, [data]
);
@ -165,7 +165,7 @@ describe("Zotero.Sync.Data.Local", function() {
for (let type of types) {
let obj = yield createDataObject(type, { version: 5 });
let data = yield obj.toJSON();
let data = obj.toJSON();
yield Zotero.Sync.Data.Local.saveCacheObjects(
type, libraryID, [data]
);
@ -175,7 +175,7 @@ describe("Zotero.Sync.Data.Local", function() {
let objectsClass = Zotero.DataObjectUtilities.getObjectsClassForObjectType(type);
let obj = yield createDataObject(type, { version: 10 });
let data = yield obj.toJSON();
let data = obj.toJSON();
yield Zotero.Sync.Data.Local.saveCacheObjects(
type, libraryID, [data]
);
@ -222,11 +222,8 @@ describe("Zotero.Sync.Data.Local", function() {
yield Zotero.Sync.Data.Local.processSyncCacheForObjectType(
libraryID, 'item', { stopOnError: true }
);
var id = Zotero.Items.getIDFromLibraryAndKey(libraryID, key);
assert.equal(
(yield Zotero.Sync.Storage.Local.getSyncState(id)),
Zotero.Sync.Storage.Local.SYNC_STATE_TO_DOWNLOAD
);
var item = Zotero.Items.getByLibraryAndKey(libraryID, key);
assert.equal(item.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_TO_DOWNLOAD);
})
it("should mark updated attachment items for download", function* () {
@ -239,18 +236,13 @@ describe("Zotero.Sync.Data.Local", function() {
yield item.saveTx();
// Set file as synced
yield Zotero.DB.executeTransaction(function* () {
yield Zotero.Sync.Storage.Local.setSyncedModificationTime(
item.id, (yield item.attachmentModificationTime)
);
yield Zotero.Sync.Storage.Local.setSyncedHash(
item.id, (yield item.attachmentHash)
);
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "in_sync");
});
item.attachmentSyncedModificationTime = yield item.attachmentModificationTime;
item.attachmentSyncedHash = yield item.attachmentHash;
item.attachmentSyncState = "in_sync";
yield item.saveTx({ skipAll: true });
// Simulate download of version with updated attachment
var json = yield item.toResponseJSON();
var json = item.toResponseJSON();
json.version = 10;
json.data.version = 10;
json.data.md5 = '57f8a4fda823187b91e1191487b87fe6';
@ -263,10 +255,7 @@ describe("Zotero.Sync.Data.Local", function() {
libraryID, 'item', { stopOnError: true }
);
assert.equal(
(yield Zotero.Sync.Storage.Local.getSyncState(item.id)),
Zotero.Sync.Storage.Local.SYNC_STATE_TO_DOWNLOAD
);
assert.equal(item.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_TO_DOWNLOAD);
})
it("should ignore attachment metadata when resolving metadata conflict", function* () {
@ -276,19 +265,14 @@ describe("Zotero.Sync.Data.Local", function() {
var item = yield importFileAttachment('test.png');
item.version = 5;
yield item.saveTx();
var json = yield item.toResponseJSON();
var json = item.toResponseJSON();
yield Zotero.Sync.Data.Local.saveCacheObjects('item', libraryID, [json]);
// Set file as synced
yield Zotero.DB.executeTransaction(function* () {
yield Zotero.Sync.Storage.Local.setSyncedModificationTime(
item.id, (yield item.attachmentModificationTime)
);
yield Zotero.Sync.Storage.Local.setSyncedHash(
item.id, (yield item.attachmentHash)
);
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "in_sync");
});
item.attachmentSyncedModificationTime = yield item.attachmentModificationTime;
item.attachmentSyncedHash = yield item.attachmentHash;
item.attachmentSyncState = "in_sync";
yield item.saveTx({ skipAll: true });
// Modify title locally, leaving item unsynced
var newTitle = Zotero.Utilities.randomString();
@ -307,10 +291,7 @@ describe("Zotero.Sync.Data.Local", function() {
);
assert.equal(item.getField('title'), newTitle);
assert.equal(
(yield Zotero.Sync.Storage.Local.getSyncState(item.id)),
Zotero.Sync.Storage.Local.SYNC_STATE_TO_DOWNLOAD
);
assert.equal(item.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_TO_DOWNLOAD);
})
})
@ -348,7 +329,7 @@ describe("Zotero.Sync.Data.Local", function() {
)
}
);
let jsonData = yield obj.toJSON();
let jsonData = obj.toJSON();
jsonData.key = obj.key;
jsonData.version = 10;
let json = {
@ -426,7 +407,7 @@ describe("Zotero.Sync.Data.Local", function() {
)
}
);
let jsonData = yield obj.toJSON();
let jsonData = obj.toJSON();
jsonData.key = obj.key;
jsonData.version = 10;
let json = {
@ -496,7 +477,7 @@ describe("Zotero.Sync.Data.Local", function() {
// Create object, generate JSON, and delete
var obj = yield createDataObject(type, { version: 10 });
var jsonData = yield obj.toJSON();
var jsonData = obj.toJSON();
var key = jsonData.key = obj.key;
jsonData.version = 10;
let json = {
@ -544,7 +525,7 @@ describe("Zotero.Sync.Data.Local", function() {
// Create object, generate JSON, and delete
var obj = yield createDataObject(type, { version: 10 });
var jsonData = yield obj.toJSON();
var jsonData = obj.toJSON();
var key = jsonData.key = obj.key;
jsonData.version = 10;
let json = {
@ -576,7 +557,6 @@ describe("Zotero.Sync.Data.Local", function() {
obj = objectsClass.getByLibraryAndKey(libraryID, key);
assert.ok(obj);
yield obj.loadItemData();
assert.equal(obj.getField('title'), jsonData.title);
})
@ -594,7 +574,7 @@ describe("Zotero.Sync.Data.Local", function() {
obj.setNote("");
obj.version = 10;
yield obj.saveTx();
var jsonData = yield obj.toJSON();
var jsonData = obj.toJSON();
var key = jsonData.key = obj.key;
let json = {
key: obj.key,
@ -626,7 +606,6 @@ describe("Zotero.Sync.Data.Local", function() {
obj = objectsClass.getByLibraryAndKey(libraryID, key);
assert.ok(obj);
yield obj.loadNote();
assert.equal(obj.getNote(), noteText2);
})
})

View file

@ -4,7 +4,7 @@ describe("Tag Selector", function () {
var win, doc, collectionsView;
var clearTagColors = Zotero.Promise.coroutine(function* (libraryID) {
var tagColors = yield Zotero.Tags.getColors(libraryID);
var tagColors = Zotero.Tags.getColors(libraryID);
for (let name of tagColors.keys()) {
yield Zotero.Tags.setColor(libraryID, name, false);
}
@ -155,6 +155,18 @@ describe("Tag Selector", function () {
assert.equal(getRegularTags().length, 1);
})
it("should show a colored tag at the top of the list even when linked to no items", function* () {
var libraryID = Zotero.Libraries.userLibraryID;
var tagSelector = doc.getElementById('zotero-tag-selector');
var tagElems = tagSelector.id('tags-box').childNodes;
var count = tagElems.length;
yield Zotero.Tags.setColor(libraryID, "Top", '#AAAAAA');
assert.equal(tagElems.length, count + 1);
});
it("shouldn't re-insert a new tag that matches an existing color", function* () {
var libraryID = Zotero.Libraries.userLibraryID;

View file

@ -64,4 +64,38 @@ describe("Zotero.Tags", function () {
assert.isFalse(yield Zotero.Tags.getName(tagID));
})
})
describe("#setColor()", function () {
var libraryID;
before(function* () {
libraryID = Zotero.Libraries.userLibraryID;
// Clear library tag colors
var colors = Zotero.Tags.getColors(libraryID);
for (let color of colors.keys()) {
yield Zotero.Tags.setColor(libraryID, color);
}
});
it("should set color for a tag", function* () {
var aColor = '#ABCDEF';
var bColor = '#BCDEF0';
yield Zotero.Tags.setColor(libraryID, "A", aColor);
yield Zotero.Tags.setColor(libraryID, "B", bColor);
var o = Zotero.Tags.getColor(libraryID, "A")
assert.equal(o.color, aColor);
assert.equal(o.position, 0);
var o = Zotero.Tags.getColor(libraryID, "B")
assert.equal(o.color, bColor);
assert.equal(o.position, 1);
var o = Zotero.SyncedSettings.get(libraryID, 'tagColors');
assert.isArray(o);
assert.lengthOf(o, 2);
assert.sameMembers(o.map(c => c.color), [aColor, bColor]);
});
});
})

View file

@ -14,17 +14,6 @@ describe("Item Tags Box", function () {
win.close();
});
function waitForTagsBox() {
var deferred = Zotero.Promise.defer();
var tagsbox = doc.getElementById('zotero-editpane-tags');
var onRefresh = function (event) {
tagsbox.removeEventListener('refresh', onRefresh);
deferred.resolve();
}
tagsbox.addEventListener('refresh', onRefresh);
return deferred.promise;
}
describe("#notify()", function () {
it("should update an existing tag on rename", function* () {
var tag = Zotero.Utilities.randomString();
@ -43,7 +32,6 @@ describe("Item Tags Box", function () {
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 2;
yield waitForTagsBox();
var tagsbox = doc.getElementById('zotero-editpane-tags');
var rows = tagsbox.id('tagRows').getElementsByTagName('row');
assert.equal(rows.length, 1);
@ -77,7 +65,6 @@ describe("Item Tags Box", function () {
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 2;
yield waitForTagsBox();
var tagsbox = doc.getElementById('zotero-editpane-tags');
var rows = tagsbox.id('tagRows').getElementsByTagName('row');
@ -108,7 +95,6 @@ describe("Item Tags Box", function () {
var tabbox = doc.getElementById('zotero-view-tabbox');
tabbox.selectedIndex = 2;
yield waitForTagsBox();
var tagsbox = doc.getElementById('zotero-editpane-tags');
var rows = tagsbox.id('tagRows').getElementsByTagName('row');
assert.equal(rows.length, 1);

View file

@ -64,13 +64,13 @@ function saveItemsThroughTranslator(translatorType, items) {
* Convert an array of items to an object in which they are indexed by
* their display titles
*/
var itemsArrayToObject = Zotero.Promise.coroutine(function* itemsArrayToObject(items) {
function itemsArrayToObject(items) {
var obj = {};
for (let item of items) {
obj[yield item.loadDisplayTitle(true)] = item;
obj[item.getDisplayTitle()] = item;
}
return obj;
});
}
const TEST_TAGS = [
"manual tag as string",
@ -175,7 +175,7 @@ describe("Zotero.Translate", function() {
let newItems = yield saveItemsThroughTranslator("import", saveItems);
let savedItems = {};
for (let i=0; i<newItems.length; i++) {
let savedItem = yield newItems[i].toJSON();
let savedItem = newItems[i].toJSON();
savedItems[Zotero.ItemTypes.getName(newItems[i].itemTypeID)] = savedItem;
delete savedItem.dateAdded;
delete savedItem.dateModified;
@ -223,7 +223,7 @@ describe("Zotero.Translate", function() {
}
];
let newItems = yield itemsArrayToObject(yield saveItemsThroughTranslator("import", myItems));
let newItems = itemsArrayToObject(yield saveItemsThroughTranslator("import", myItems));
let noteIDs = newItems["Test Item"].getNotes();
let note1 = yield Zotero.Items.getAsync(noteIDs[0]);
assert.equal(Zotero.ItemTypes.getName(note1.itemTypeID), "note");
@ -261,7 +261,7 @@ describe("Zotero.Translate", function() {
'}'));
let newItems = yield translate.translate();
assert.equal(newItems.length, 3);
newItems = yield itemsArrayToObject(newItems);
newItems = itemsArrayToObject(newItems);
assert.equal(newItems["Not in Collection"].getCollections().length, 0);
let parentCollection = newItems["In Parent Collection"].getCollections();
@ -313,7 +313,7 @@ describe("Zotero.Translate", function() {
"attachments":childAttachments
});
let newItems = yield itemsArrayToObject(yield saveItemsThroughTranslator("import", myItems));
let newItems = itemsArrayToObject(yield saveItemsThroughTranslator("import", myItems));
let containedAttachments = yield Zotero.Items.getAsync(newItems["Container Item"].getAttachments());
assert.equal(containedAttachments.length, 3);
@ -447,7 +447,7 @@ describe("Zotero.Translate", function() {
let newItems = yield saveItemsThroughTranslator("web", myItems);
assert.equal(newItems.length, 1);
let containedAttachments = yield itemsArrayToObject(yield Zotero.Items.getAsync(newItems[0].getAttachments()));
let containedAttachments = itemsArrayToObject(yield Zotero.Items.getAsync(newItems[0].getAttachments()));
let link = containedAttachments["Link to zotero.org"];
assert.equal(link.getField("url"), "http://www.zotero.org/");

View file

@ -179,7 +179,7 @@ describe("Zotero.Utilities", function() {
let fromZoteroItem;
try {
fromZoteroItem = yield Zotero.Utilities.itemToCSLJSON(item);
fromZoteroItem = Zotero.Utilities.itemToCSLJSON(item);
} catch(e) {
assert.fail(e, null, 'accepts Zotero Item');
}
@ -190,7 +190,7 @@ describe("Zotero.Utilities", function() {
let fromExportItem;
try {
fromExportItem = Zotero.Utilities.itemToCSLJSON(
yield Zotero.Utilities.Internal.itemToExportFormat(item)
Zotero.Utilities.Internal.itemToExportFormat(item)
);
} catch(e) {
assert.fail(e, null, 'accepts Zotero export item');
@ -205,7 +205,7 @@ describe("Zotero.Utilities", function() {
note.setNote('Some note longer than 50 characters, which will become the title.');
yield note.saveTx();
let cslJSONNote = yield Zotero.Utilities.itemToCSLJSON(note);
let cslJSONNote = Zotero.Utilities.itemToCSLJSON(note);
assert.equal(cslJSONNote.type, 'article', 'note is exported as "article"');
assert.equal(cslJSONNote.title, note.getNoteTitle(), 'note title is set to Zotero pseudo-title');
}));
@ -221,7 +221,7 @@ describe("Zotero.Utilities", function() {
yield attachment.saveTx();
let cslJSONAttachment = yield Zotero.Utilities.itemToCSLJSON(attachment);
let cslJSONAttachment = Zotero.Utilities.itemToCSLJSON(attachment);
assert.equal(cslJSONAttachment.type, 'article', 'attachment is exported as "article"');
assert.equal(cslJSONAttachment.title, 'Empty', 'attachment title is correct');
assert.deepEqual(cslJSONAttachment.accessed, {"date-parts":[["2001",2,3]]}, 'attachment access date is mapped correctly');
@ -240,27 +240,27 @@ describe("Zotero.Utilities", function() {
item.setField('extra', 'PMID: 12345\nPMCID:123456');
yield item.saveTx();
let cslJSON = yield Zotero.Utilities.itemToCSLJSON(item);
let cslJSON = Zotero.Utilities.itemToCSLJSON(item);
assert.equal(cslJSON.PMID, '12345', 'PMID from Extra is mapped to PMID');
assert.equal(cslJSON.PMCID, '123456', 'PMCID from Extra is mapped to PMCID');
item.setField('extra', 'PMID: 12345');
yield item.saveTx();
cslJSON = yield Zotero.Utilities.itemToCSLJSON(item);
cslJSON = Zotero.Utilities.itemToCSLJSON(item);
assert.equal(cslJSON.PMID, '12345', 'single-line entry is extracted correctly');
item.setField('extra', 'some junk: note\nPMID: 12345\nstuff in-between\nPMCID: 123456\nlast bit of junk!');
yield item.saveTx();
cslJSON = yield Zotero.Utilities.itemToCSLJSON(item);
cslJSON = Zotero.Utilities.itemToCSLJSON(item);
assert.equal(cslJSON.PMID, '12345', 'PMID from mixed Extra field is mapped to PMID');
assert.equal(cslJSON.PMCID, '123456', 'PMCID from mixed Extra field is mapped to PMCID');
item.setField('extra', 'a\n PMID: 12345\nfoo PMCID: 123456');
yield item.saveTx();
cslJSON = yield Zotero.Utilities.itemToCSLJSON(item);
cslJSON = Zotero.Utilities.itemToCSLJSON(item);
assert.isUndefined(cslJSON.PMCID, 'field label must not be preceded by other text');
assert.isUndefined(cslJSON.PMID, 'field label must not be preceded by a space');
@ -268,7 +268,7 @@ describe("Zotero.Utilities", function() {
item.setField('extra', 'something\npmid: 12345\n');
yield item.saveTx();
cslJSON = yield Zotero.Utilities.itemToCSLJSON(item);
cslJSON = Zotero.Utilities.itemToCSLJSON(item);
assert.isUndefined(cslJSON.PMID, 'field labels are case-sensitive');
}));
@ -347,7 +347,7 @@ describe("Zotero.Utilities", function() {
});
let item = Zotero.Items.get(data.item.id);
let cslCreators = (yield Zotero.Utilities.itemToCSLJSON(item)).author;
let cslCreators = Zotero.Utilities.itemToCSLJSON(item).author;
assert.deepEqual(cslCreators[0], creators[0].expect, 'simple name is not parsed');
assert.deepEqual(cslCreators[1], creators[1].expect, 'name with dropping and non-dropping particles is parsed');
@ -359,6 +359,7 @@ describe("Zotero.Utilities", function() {
});
describe("itemFromCSLJSON", function () {
it("should stably perform itemToCSLJSON -> itemFromCSLJSON -> itemToCSLJSON", function* () {
this.timeout(10000);
let data = loadSampleData('citeProcJSExport');
for (let i in data) {
@ -368,7 +369,7 @@ describe("Zotero.Utilities", function() {
Zotero.Utilities.itemFromCSLJSON(item, json);
yield item.saveTx();
let newJSON = yield Zotero.Utilities.itemToCSLJSON(item);
let newJSON = Zotero.Utilities.itemToCSLJSON(item);
delete newJSON.id;
delete json.id;
@ -382,7 +383,7 @@ describe("Zotero.Utilities", function() {
note.setNote('Some note longer than 50 characters, which will become the title.');
yield note.saveTx();
let jsonNote = yield Zotero.Utilities.itemToCSLJSON(note);
let jsonNote = Zotero.Utilities.itemToCSLJSON(note);
let item = new Zotero.Item();
Zotero.Utilities.itemFromCSLJSON(item, jsonNote);
@ -397,7 +398,7 @@ describe("Zotero.Utilities", function() {
attachment.setNote('Note');
yield attachment.saveTx();
let jsonAttachment = yield Zotero.Utilities.itemToCSLJSON(attachment);
let jsonAttachment = Zotero.Utilities.itemToCSLJSON(attachment);
let item = new Zotero.Item();
Zotero.Utilities.itemFromCSLJSON(item, jsonAttachment);

View file

@ -186,8 +186,8 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
var item = new Zotero.Item("attachment");
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "to_download");
setResponse({
method: "GET",
@ -217,8 +217,8 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
var item = new Zotero.Item("attachment");
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "to_download");
setResponse({
method: "GET",
@ -251,8 +251,8 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
var item = new Zotero.Item("attachment");
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "to_download");
setResponse({
method: "GET",
@ -298,8 +298,8 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
item.attachmentPath = 'storage:' + fileName;
// TODO: Test binary data
var text = Zotero.Utilities.randomString();
item.attachmentSyncState = "to_download";
yield item.saveTx();
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "to_download");
// Create ZIP file containing above text file
var tmpPath = Zotero.getTempDirectory().path;
@ -447,8 +447,8 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.isTrue(result.syncRequired);
// Check local objects
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedModificationTime(item.id)), mtime);
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedHash(item.id)), hash);
assert.equal(item.attachmentSyncedModificationTime, mtime);
assert.equal(item.attachmentSyncedHash, hash);
assert.isFalse(item.synced);
})
@ -464,12 +464,9 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
var syncedModTime = Date.now() - 10000;
var syncedHash = "3a2f092dd62178eb8bbfda42e07e64da";
yield Zotero.DB.executeTransaction(function* () {
// Set an mtime in the past
yield Zotero.Sync.Storage.Local.setSyncedModificationTime(item.id, syncedModTime);
// And a different hash
yield Zotero.Sync.Storage.Local.setSyncedHash(item.id, syncedHash);
});
item.attachmentSyncedModificationTime = syncedModTime;
item.attachmentSyncedHash = syncedHash;
yield item.saveTx({ skipAll: true });
var mtime = yield item.attachmentModificationTime;
var hash = yield item.attachmentHash;
@ -507,8 +504,8 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.isFalse(result.fileSyncRequired);
// Check local objects
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedModificationTime(item.id)), mtime);
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedHash(item.id)), hash);
assert.equal(item.attachmentSyncedModificationTime, mtime);
assert.equal(item.attachmentSyncedHash, hash);
assert.isFalse(item.synced);
})
@ -547,8 +544,8 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
assert.isFalse(result.syncRequired);
// Check local object
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedModificationTime(item.id)), mtime);
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedHash(item.id)), hash);
assert.equal(item.attachmentSyncedModificationTime, mtime);
assert.equal(item.attachmentSyncedHash, hash);
assert.isFalse(item.synced);
})
@ -593,15 +590,10 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
// Check local object
//
// Item should be marked as in conflict
assert.equal(
(yield Zotero.Sync.Storage.Local.getSyncState(item.id)),
Zotero.Sync.Storage.Local.SYNC_STATE_IN_CONFLICT
);
assert.equal(item.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_IN_CONFLICT);
// Synced mod time should have been changed, because that's what's shown in the
// conflict dialog
assert.equal(
(yield Zotero.Sync.Storage.Local.getSyncedModificationTime(item.id)), newModTime
);
assert.equal(item.attachmentSyncedModificationTime, newModTime);
assert.isTrue(item.synced);
})
})

View file

@ -143,8 +143,8 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
var item = new Zotero.Item("attachment");
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "to_download");
this.httpd.registerPathHandler(
`/users/1/items/${item.key}/file`,
@ -175,8 +175,8 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
var item = new Zotero.Item("attachment");
item.attachmentLinkMode = 'imported_file';
item.attachmentPath = 'storage:test.txt';
item.attachmentSyncState = "to_download";
yield item.saveTx();
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "to_download");
this.httpd.registerPathHandler(
`/users/1/items/${item.key}/file`,
@ -208,8 +208,8 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
item.attachmentPath = 'storage:test.txt';
// TODO: Test binary data
var text = Zotero.Utilities.randomString();
item.attachmentSyncState = "to_download";
yield item.saveTx();
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "to_download");
var mtime = "1441252524905";
var md5 = Zotero.Utilities.Internal.md5(text)
@ -553,14 +553,68 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
assert.isFalse(result.syncRequired);
// Check local objects
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedModificationTime(item1.id)), mtime1);
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedHash(item1.id)), hash1);
assert.equal(item1.attachmentSyncedModificationTime, mtime1);
assert.equal(item1.attachmentSyncedHash, hash1);
assert.equal(item1.version, 10);
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedModificationTime(item2.id)), mtime2);
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedHash(item2.id)), hash2);
assert.equal(item2.attachmentSyncedModificationTime, mtime2);
assert.equal(item2.attachmentSyncedHash, hash2);
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();
var library = Zotero.Libraries.userLibrary;
library.libraryVersion = 5;
yield library.saveTx();
library.storageDownloadNeeded = true;
var file = getTestDataDirectory();
file.append('test.txt');
var item = yield 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);
var json = item.toJSON();
yield 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)
var s3Path = `pretend-s3/${item.key}`;
this.httpd.registerPathHandler(
`/users/1/items/${item.key}/file`,
{
handle: function (request, response) {
if (!request.hasHeader('Zotero-API-Key')) {
response.setStatusLine(null, 403, "Forbidden");
return;
}
var key = request.getHeader('Zotero-API-Key');
if (key != apiKey) {
response.setStatusLine(null, 403, "Invalid key");
return;
}
response.setStatusLine(null, 302, "Found");
response.setHeader("Zotero-File-Modification-Time", mtime, false);
response.setHeader("Zotero-File-MD5", md5, false);
response.setHeader("Zotero-File-Compressed", "No", false);
response.setHeader("Location", baseURL + s3Path, false);
}
}
);
var result = yield engine.start();
assert.equal(item.attachmentSyncedModificationTime, mtime);
yield 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();
@ -569,7 +623,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
var item = yield Zotero.Attachments.importFromFile({ file: file });
item.version = 5;
yield item.saveTx();
var json = yield item.toJSON();
var json = item.toJSON();
yield Zotero.Sync.Data.Local.saveCacheObject('item', item.libraryID, json);
var mtime = yield item.attachmentModificationTime;
@ -615,8 +669,8 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
assert.isFalse(result.syncRequired);
// Check local objects
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedModificationTime(item.id)), mtime);
assert.equal((yield Zotero.Sync.Storage.Local.getSyncedHash(item.id)), hash);
assert.equal(item.attachmentSyncedModificationTime, mtime);
assert.equal(item.attachmentSyncedHash, hash);
assert.equal(item.version, newVersion);
})
})
@ -635,7 +689,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
item.synced = true;
yield item.saveTx();
var itemJSON = yield item.toResponseJSON();
var itemJSON = item.toResponseJSON();
itemJSON.data.mtime = yield item.attachmentModificationTime;
itemJSON.data.md5 = yield item.attachmentHash;
@ -645,9 +699,8 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
// storage directory was transferred, the mtime doesn't match, but the file was
// never downloaded), but there's no difference in behavior
var dbHash = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
yield Zotero.DB.executeTransaction(function* () {
yield Zotero.Sync.Storage.Local.setSyncedHash(item.id, dbHash)
});
item.attachmentSyncedHash = dbHash;
yield item.saveTx({ skipAll: true });
server.respond(function (req) {
if (req.method == "POST"
@ -674,10 +727,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
var result = yield zfs._processUploadFile({
name: item.libraryKey
});
yield assert.eventually.equal(
Zotero.Sync.Storage.Local.getSyncedHash(item.id),
(yield item.attachmentHash)
);
assert.equal(item.attachmentSyncedHash, (yield item.attachmentHash));
assert.isFalse(result.localChanges);
assert.isFalse(result.remoteChanges);
assert.isFalse(result.syncRequired);
@ -697,7 +747,7 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
yield item.saveTx();
var fileHash = yield item.attachmentHash;
var itemJSON = yield item.toResponseJSON();
var itemJSON = item.toResponseJSON();
itemJSON.data.md5 = 'aaaaaaaaaaaaaaaaaaaaaaaa'
server.respond(function (req) {
@ -725,11 +775,8 @@ describe("Zotero.Sync.Storage.Mode.ZFS", function () {
var result = yield zfs._processUploadFile({
name: item.libraryKey
});
yield assert.eventually.isNull(Zotero.Sync.Storage.Local.getSyncedHash(item.id));
yield assert.eventually.equal(
Zotero.Sync.Storage.Local.getSyncState(item.id),
Zotero.Sync.Storage.Local.SYNC_STATE_IN_CONFLICT
);
assert.isNull(item.attachmentSyncedHash);
assert.equal(item.attachmentSyncState, Zotero.Sync.Storage.Local.SYNC_STATE_IN_CONFLICT);
assert.isFalse(result.localChanges);
assert.isFalse(result.remoteChanges);
assert.isFalse(result.syncRequired);

View file

@ -1,13 +1,14 @@
"use strict";
describe("ZoteroPane", function() {
var win, doc, zp;
var win, doc, zp, userLibraryID;
// Load Zotero pane and select library
before(function* () {
win = yield loadZoteroPane();
doc = win.document;
zp = win.ZoteroPane;
userLibraryID = Zotero.Libraries.userLibraryID;
});
after(function () {
@ -157,8 +158,8 @@ describe("ZoteroPane", function() {
item.attachmentPath = 'storage:test.txt';
// TODO: Test binary data
var text = Zotero.Utilities.randomString();
item.attachmentSyncState = "to_download";
yield item.saveTx();
yield Zotero.Sync.Storage.Local.setSyncState(item.id, "to_download");
var mtime = "1441252524000";
var md5 = Zotero.Utilities.Internal.md5(text)
@ -201,4 +202,92 @@ describe("ZoteroPane", function() {
assert.equal((yield Zotero.File.getContentsAsync(path)), text);
})
})
describe("#setVirtual()", function () {
var cv;
before(function* () {
cv = zp.collectionsView;
});
beforeEach(function () {
Zotero.Prefs.clear('duplicateLibraries');
Zotero.Prefs.clear('unfiledLibraries');
return selectLibrary(win);
})
it("should show a hidden virtual folder", function* () {
// Create unfiled, duplicate items
var title = Zotero.Utilities.randomString();
var item1 = yield createDataObject('item', { title });
var item2 = yield createDataObject('item', { title });
// Start hidden
Zotero.Prefs.set('duplicateLibraries', "");
Zotero.Prefs.set('unfiledLibraries', "");
yield cv.refresh();
// Show Duplicate Items
var id = "D" + userLibraryID;
assert.isFalse(cv.getRowIndexByID(id));
yield zp.setVirtual(userLibraryID, 'duplicates', true);
// Clicking should select both items
var row = cv.getRowIndexByID(id);
assert.ok(row);
assert.equal(cv.selection.currentIndex, row);
yield waitForItemsLoad(win);
var iv = zp.itemsView;
row = iv.getRowIndexByID(item1.id);
assert.isNumber(row);
clickOnItemsRow(iv, row);
assert.equal(iv.selection.count, 2);
// Show Unfiled Items
id = "U" + userLibraryID;
assert.isFalse(cv.getRowIndexByID(id));
yield zp.setVirtual(userLibraryID, 'unfiled', true);
assert.ok(cv.getRowIndexByID(id));
});
it("should hide a virtual folder shown by default", function* () {
yield cv.refresh();
// Hide Duplicate Items
var id = "D" + userLibraryID;
assert.ok(yield cv.selectByID(id));
yield zp.setVirtual(userLibraryID, 'duplicates', false);
assert.isFalse(cv.getRowIndexByID(id));
// Hide Unfiled Items
id = "U" + userLibraryID;
assert.ok(yield cv.selectByID(id));
yield zp.setVirtual(userLibraryID, 'unfiled', false);
assert.isFalse(cv.getRowIndexByID(id));
});
it("should hide an explicitly shown virtual folder", function* () {
// Start shown
Zotero.Prefs.set('duplicateLibraries', "" + userLibraryID);
Zotero.Prefs.set('unfiledLibraries', "" + userLibraryID);
yield cv.refresh();
// Hide Duplicate Items
var id = "D" + userLibraryID;
assert.ok(yield cv.selectByID(id));
yield waitForItemsLoad(win);
yield zp.setVirtual(userLibraryID, 'duplicates', false);
assert.isFalse(cv.getRowIndexByID(id));
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
// Hide Unfiled Items
id = "U" + userLibraryID;
assert.ok(yield cv.selectByID(id));
yield waitForItemsLoad(win);
yield zp.setVirtual(userLibraryID, 'unfiled', false);
assert.isFalse(cv.getRowIndexByID(id));
assert.equal(cv.getSelectedLibraryID(), userLibraryID);
});
});
})