zotero/test/tests/notifierTest.js
Dan Stillman 7ace5ea29e Fix unnecessary sync looping after downloading items
An extra sync loop would be performed for every object downloaded, so a
download to an empty database could result in a huge number of
unnecessary loops. This was a regression from 52932b6eb, which started
queuing auto-syncs while a sync was in progress. The fix here is to skip
auto-sync for all objects saved from a sync download.

There are two new mechanisms involved:

- Event-level notifier options that get passed to passed to notify() at
  the top level of extraData rather than being included with every
  object (e.g., because `skipAutoSync` should apply to an entire save
  transaction)
- The ability to pass event-level notifier options when initializing
  a Zotero.Notifier.Queue, such as the one used for sync downloads
2021-05-14 03:49:26 -04:00

115 lines
3.1 KiB
JavaScript

"use strict";
describe("Zotero.Notifier", function () {
describe("#trigger()", function () {
it("should trigger add events before modify events", function* () {
var deferred = Zotero.Promise.defer();
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(function* () {
var item = new Zotero.Item('book');
item.setField('title', 'A');
yield item.save();
item.setField('title', 'B');
yield item.save();
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');
assert.equal(events[2], 'unknown');
Zotero.Notifier.unregisterObserver(id);
});
it("should add events to passed queue", function* () {
var collection = yield createDataObject('collection');
var deferred = Zotero.Promise.defer();
var observer = {
notify: () => deferred.resolve()
};
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({
notifierQueue: queue
});
assert.isTrue(deferred.promise.isPending());
assert.equal(queue.size, 2);
yield Zotero.Notifier.commit(queue);
assert.isTrue(deferred.promise.isResolved());
Zotero.Notifier.unregisterObserver(id);
});
});
describe("#queue", function () {
it("should handle notification after DB timeout from another transaction", async function () {
var promise1 = Zotero.DB.executeTransaction(async function () {
var item = createUnsavedDataObject('item');
await item.save();
await Zotero.Promise.delay(2000);
Zotero.Notifier.queue('refresh', 'item', item.id);
}.bind(this));
var promise2 = Zotero.DB.executeTransaction(async function () {
var item = createUnsavedDataObject('item');
await item.save();
}.bind(this), { waitTimeout: 1000 });
await promise1;
assert.isTrue(promise2.isRejected());
});
});
describe("Queue", function () {
describe("#commit()", function () {
it("should add options from queue to extraData", async function () {
var called = false;
var data;
var notifierID = Zotero.Notifier.registerObserver({
notify: (event, type, ids, extraData) => {
called = true;
data = extraData;
}
});
var notifierQueue = new Zotero.Notifier.Queue({
skipAutoSync: true
});
var item = createUnsavedDataObject('item');
await item.saveTx({
notifierQueue
});
assert.isFalse(called);
await Zotero.Notifier.commit(notifierQueue);
assert.isTrue(called);
assert.propertyVal(data, 'skipAutoSync', true);
Zotero.Notifier.unregisterObserver(notifierID);
});
});
});
});