commit 4f55f28e7dbbcb17ec87b922b386ec6b5074af3e
parent 93b56944205222e8fc5a7aad0b2295dfcd7f9107
Author: Dan Stillman <dstillman@zotero.org>
Date: Sun, 19 Jul 2015 17:17:32 -0400
Honor .synced on data objects in all cases
Previously, if .synced was already true, setting it to true and saving
would result in .synced == false unless skipSyncedUpdate was passed. Now
the value assigned to .synced is always used on the next save. If the
value hasn't changed and no other values have changed, a save will be a
no-op.
Diffstat:
3 files changed, 128 insertions(+), 45 deletions(-)
diff --git a/chrome/content/zotero/xpcom/data/dataObject.js b/chrome/content/zotero/xpcom/data/dataObject.js
@@ -128,7 +128,7 @@ Zotero.DataObject.prototype._set = function (field, value) {
break;
}
- if (this['_' + field] != value) {
+ if (this['_' + field] != value || field == 'synced') {
this._markFieldChange(field, this['_' + field]);
if (!this._changed.primaryData) {
this._changed.primaryData = {};
@@ -905,8 +905,14 @@ Zotero.DataObject.prototype.saveTx = function (options) {
Zotero.DataObject.prototype.hasChanged = function() {
- Zotero.debug(this._changed);
- return !!Object.keys(this._changed).filter(dataType => this._changed[dataType]).length
+ var changed = Object.keys(this._changed).filter(dataType => this._changed[dataType]);
+ if (changed.length == 1
+ && changed[0] == 'primaryData'
+ && this._changed.primaryData.synced
+ && this._previousData.synced == this._synced) {
+ return false;
+ }
+ return !!changed.length;
}
Zotero.DataObject.prototype._initSave = Zotero.Promise.coroutine(function* (env) {
diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js
@@ -685,7 +685,7 @@ Zotero.Item.prototype.setField = function(field, value, loadIn) {
*/
// If field value has changed
- if (this['_' + field] != value) {
+ if (this['_' + field] != value || field == 'synced') {
Zotero.debug("Field '" + field + "' has changed from '" + this['_' + field] + "' to '" + value + "'", 4);
// Save a copy of the field before modifying
diff --git a/test/tests/dataObjectTest.js b/test/tests/dataObjectTest.js
@@ -45,54 +45,131 @@ describe("Zotero.DataObject", function() {
})
describe("#synced", function () {
- it("should be set to false after creating item", function* () {
- var item = new Zotero.Item("book");
- var id = yield item.saveTx();
- assert.isFalse(item.synced);
- yield item.eraseTx();
+ it("should be set to false after creating object", function* () {
+ for (let type of types) {
+ var obj = createUnsavedDataObject(type);
+ var id = yield obj.saveTx();
+ assert.isFalse(obj.synced);
+ yield obj.eraseTx();
+ }
});
- it("should be set to true when changed", function* () {
- var item = new Zotero.Item("book");
- var id = yield item.saveTx();
-
- item.synced = 1;
- yield item.saveTx();
- assert.ok(item.synced);
-
- yield item.eraseTx();
+ it("should be set to false after modifying object", function* () {
+ for (let type of types) {
+ var obj = createUnsavedDataObject(type);
+ var id = yield obj.saveTx();
+
+ obj.synced = true;
+ yield obj.saveTx();
+
+ if (type == 'item') {
+ yield obj.loadItemData();
+ obj.setField('title', Zotero.Utilities.randomString());
+ }
+ else {
+ obj.name = Zotero.Utilities.randomString();
+ }
+ yield obj.saveTx();
+ assert.isFalse(obj.synced);
+
+ yield obj.eraseTx();
+ }
});
- it("should be set to false after modifying item", function* () {
- var item = new Zotero.Item("book");
- var id = yield item.saveTx();
-
- item.synced = 1;
- yield item.saveTx();
-
- yield item.loadItemData();
- item.setField('title', 'test');
- yield item.saveTx();
- assert.isFalse(item.synced);
-
- yield item.eraseTx();
+ it("should be changed to true explicitly with no other changes", function* () {
+ for (let type of types) {
+ var obj = createUnsavedDataObject(type);
+ var id = yield obj.saveTx();
+
+ obj.synced = true;
+ yield obj.saveTx();
+ assert.isTrue(obj.synced);
+
+ yield obj.eraseTx();
+ }
+ });
+
+ it("should be changed to true explicitly with other field changes", function* () {
+ for (let type of types) {
+ var obj = createUnsavedDataObject(type);
+ var id = yield obj.saveTx();
+
+ if (type == 'item') {
+ obj.setField('title', Zotero.Utilities.randomString());
+ }
+ else {
+ obj.name = Zotero.Utilities.randomString();
+ }
+ obj.synced = true;
+ yield obj.saveTx();
+ assert.isTrue(obj.synced);
+
+ yield obj.eraseTx();
+ }
});
+ it("should remain at true if set explicitly", function* () {
+ for (let type of types) {
+ var obj = createUnsavedDataObject(type);
+ obj.synced = true;
+ var id = yield obj.saveTx();
+ assert.isTrue(obj.synced);
+
+ if (type == 'item') {
+ obj.setField('title', 'test');
+ }
+ else {
+ obj.name = Zotero.Utilities.randomString();
+ }
+ obj.synced = true;
+ yield obj.saveTx();
+ assert.isTrue(obj.synced);
+
+ yield obj.eraseTx();
+ }
+ });
+
+ it("shouldn't cause a save if unchanged and nothing else changed", function* () {
+ for (let type of types) {
+ var obj = createUnsavedDataObject(type);
+ obj.synced = true;
+ var id = yield obj.saveTx();
+ assert.isTrue(obj.synced);
+
+ obj.synced = true;
+ assert.isFalse(obj.hasChanged(), type + " shouldn't be changed");
+
+ var obj = createUnsavedDataObject(type);
+ obj.synced = false;
+ var id = yield obj.saveTx();
+ assert.isFalse(obj.synced);
+ obj.synced = false;
+ assert.isFalse(obj.hasChanged(), type + " shouldn't be changed");
+ }
+ })
+
it("should be unchanged if skipSyncedUpdate passed", function* () {
- var item = new Zotero.Item("book");
- var id = yield item.saveTx();
-
- item.synced = 1;
- yield item.saveTx();
-
- yield item.loadItemData();
- item.setField('title', 'test');
- yield item.saveTx({
- skipSyncedUpdate: true
- });
- assert.ok(item.synced);
-
- yield item.eraseTx();
+ for (let type of types) {
+ var obj = createUnsavedDataObject(type);
+ var id = yield obj.saveTx();
+
+ obj.synced = 1;
+ yield obj.saveTx();
+
+ if (type == 'item') {
+ yield obj.loadItemData();
+ obj.setField('title', Zotero.Utilities.randomString());
+ }
+ else {
+ obj.name = Zotero.Utilities.randomString();
+ }
+ yield obj.saveTx({
+ skipSyncedUpdate: true
+ });
+ assert.ok(obj.synced);
+
+ yield obj.eraseTx();
+ }
});
})