Various feeds changes
- Hide notes, tags and related for feed items in itembox - Add feed support for <enclosure> elements - Add feed syncing methods for synced settings (additional work is needed on the sync architecture to download synced settings from the server) - Change feed item clear policy to be less aggressive - Adjust for deasyncification - Disable translate-on-select - Close adomasven/zotero#7, Remove context menu items from feeds
This commit is contained in:
parent
0d4025e9fb
commit
12fc6cfbe8
42 changed files with 894 additions and 379 deletions
|
@ -385,11 +385,7 @@ function createUnsavedDataObject(objectType, params = {}) {
|
|||
|
||||
var createDataObject = Zotero.Promise.coroutine(function* (objectType, params = {}, saveOptions) {
|
||||
var obj = createUnsavedDataObject(objectType, params);
|
||||
if (objectType == 'feedItem') {
|
||||
yield obj.forceSaveTx(saveOptions);
|
||||
} else {
|
||||
yield obj.saveTx(saveOptions);
|
||||
}
|
||||
yield obj.saveTx(saveOptions);
|
||||
return obj;
|
||||
});
|
||||
|
||||
|
@ -453,8 +449,12 @@ function getTestDataDirectory() {
|
|||
QueryInterface(Components.interfaces.nsIFileURL).file;
|
||||
}
|
||||
|
||||
function getTestDataItemUrl(path) {
|
||||
return OS.Path.join("resource://zotero-unit-tests/data", path);
|
||||
function getTestDataUrl(path) {
|
||||
path = path.split('/');
|
||||
if (path[0].length == 0) {
|
||||
path.splice(0, 1);
|
||||
}
|
||||
return "resource://zotero-unit-tests/data/" + path.join('/');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -682,10 +682,10 @@ describe("Zotero.CollectionTreeView", function() {
|
|||
it('should add a translated feed item recovered from an URL', function* (){
|
||||
var feed = yield createFeed();
|
||||
var collection = yield createDataObject('collection', false, { skipSelect: true });
|
||||
var url = getTestDataItemUrl('metadata/journalArticle-single.html');
|
||||
var url = getTestDataUrl('metadata/journalArticle-single.html');
|
||||
var feedItem = yield createDataObject('feedItem', {libraryID: feed.libraryID}, { skipSelect: true });
|
||||
feedItem.setField('url', url);
|
||||
yield feedItem.forceSaveTx();
|
||||
yield feedItem.saveTx();
|
||||
var translateFn = sinon.spy(feedItem, 'translate');
|
||||
|
||||
// Add observer to wait for collection add
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<description>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 href="http://howe.iki.rssi.ru/GCTC/gctc_e.htm">Star City</a>.</description>
|
||||
<pubDate>Tue, 03 Jun 2003 09:39:21 GMT</pubDate>
|
||||
<guid>http://liftoff.msfc.nasa.gov/2003/06/03.html#item573</guid>
|
||||
<enclosure url="http://www.example.com/example.pdf" type="application/pdf" />
|
||||
</item>
|
||||
<item>
|
||||
<title>The Engine That Does More</title>
|
||||
|
|
|
@ -23,11 +23,11 @@ describe("Zotero.FeedItem", function () {
|
|||
it("should accept required fields as arguments", function* () {
|
||||
let guid = Zotero.randomString();
|
||||
let feedItem = new Zotero.FeedItem();
|
||||
yield assert.isRejected(feedItem.forceSaveTx());
|
||||
yield assert.isRejected(feedItem.saveTx());
|
||||
|
||||
feedItem = new Zotero.FeedItem('book', { guid });
|
||||
feedItem.libraryID = libraryID;
|
||||
yield assert.isFulfilled(feedItem.forceSaveTx());
|
||||
yield assert.isFulfilled(feedItem.saveTx());
|
||||
|
||||
assert.equal(feedItem.itemTypeID, Zotero.ItemTypes.getID('book'));
|
||||
assert.equal(feedItem.guid, guid);
|
||||
|
@ -83,7 +83,7 @@ describe("Zotero.FeedItem", function () {
|
|||
expectedTimestamp = Date.now();
|
||||
feedItem.isRead = true;
|
||||
yield Zotero.Promise.delay(2001);
|
||||
yield feedItem.forceSaveTx();
|
||||
yield feedItem.saveTx();
|
||||
|
||||
readTime = yield Zotero.DB.valueQueryAsync('SELECT readTime FROM feedItems WHERE itemID=?', feedItem.id);
|
||||
readTime = Zotero.Date.sqlToDate(readTime, true).getTime();
|
||||
|
@ -107,41 +107,36 @@ describe("Zotero.FeedItem", function () {
|
|||
})
|
||||
});
|
||||
describe("#save()", function() {
|
||||
it("should require edit check override", function* () {
|
||||
let feedItem = new Zotero.FeedItem('book', { guid: Zotero.randomString() });
|
||||
feedItem.libraryID = feed.libraryID;
|
||||
yield assert.isRejected(feedItem.saveTx(), /^Error: Cannot edit feedItem in read-only library/);
|
||||
});
|
||||
it("should require feed being set", function* () {
|
||||
let feedItem = new Zotero.FeedItem('book', { guid: Zotero.randomString() });
|
||||
// Defaults to user library ID
|
||||
yield assert.isRejected(feedItem.forceSaveTx(), /^Error: Cannot add /);
|
||||
yield assert.isRejected(feedItem.saveTx(), /^Error: Cannot add /);
|
||||
});
|
||||
it("should require GUID being set", function* () {
|
||||
let feedItem = new Zotero.FeedItem('book');
|
||||
feedItem.libraryID = feed.libraryID;
|
||||
yield assert.isRejected(feedItem.forceSaveTx(), /^Error: GUID must be set before saving FeedItem$/);
|
||||
yield assert.isRejected(feedItem.saveTx(), /^Error: GUID must be set before saving FeedItem$/);
|
||||
});
|
||||
it("should require a unique GUID", function* () {
|
||||
let guid = Zotero.randomString();
|
||||
let feedItem1 = yield createDataObject('feedItem', { libraryID, guid });
|
||||
|
||||
let feedItem2 = createUnsavedDataObject('feedItem', { libraryID, guid });
|
||||
yield assert.isRejected(feedItem2.forceSaveTx());
|
||||
yield assert.isRejected(feedItem2.saveTx());
|
||||
|
||||
// But we should be able to save it after deleting the original feed
|
||||
yield feedItem1.forceEraseTx();
|
||||
yield assert.isFulfilled(feedItem2.forceSaveTx());
|
||||
yield feedItem1.eraseTx();
|
||||
yield assert.isFulfilled(feedItem2.saveTx());
|
||||
});
|
||||
it("should require item type being set", function* () {
|
||||
let feedItem = new Zotero.FeedItem(null, { guid: Zotero.randomString() });
|
||||
feedItem.libraryID = feed.libraryID;
|
||||
yield assert.isRejected(feedItem.forceSaveTx(), /^Error: Item type must be set before saving$/);
|
||||
yield assert.isRejected(feedItem.saveTx(), /^Error: Item type must be set before saving$/);
|
||||
});
|
||||
it("should save feed item", function* () {
|
||||
let guid = Zotero.randomString();
|
||||
let feedItem = createUnsavedDataObject('feedItem', { libraryID, guid });
|
||||
yield assert.isFulfilled(feedItem.forceSaveTx());
|
||||
yield assert.isFulfilled(feedItem.saveTx());
|
||||
|
||||
feedItem = yield Zotero.FeedItems.getAsync(feedItem.id);
|
||||
assert.ok(feedItem);
|
||||
|
@ -155,7 +150,7 @@ describe("Zotero.FeedItem", function () {
|
|||
let feedItem = new Zotero.FeedItem(null, type, feed.libraryID);
|
||||
feedItem.fromJSON(allTypesAndFields[type]);
|
||||
|
||||
yield feedItem.forceSaveTx();
|
||||
yield feedItem.saveTx();
|
||||
|
||||
feedItems.push(feedItem);
|
||||
}
|
||||
|
@ -172,7 +167,7 @@ describe("Zotero.FeedItem", function () {
|
|||
let feedItem = yield createDataObject('feedItem', { libraryID });
|
||||
|
||||
feedItem.setField('title', 'bar');
|
||||
yield assert.isFulfilled(feedItem.forceSaveTx());
|
||||
yield assert.isFulfilled(feedItem.saveTx());
|
||||
assert.equal(feedItem.getField('title'), 'bar');
|
||||
});
|
||||
});
|
||||
|
@ -180,15 +175,22 @@ describe("Zotero.FeedItem", function () {
|
|||
it("should erase an existing feed item", function* () {
|
||||
let feedItem = yield createDataObject('feedItem', { libraryID });
|
||||
|
||||
yield feedItem.forceEraseTx();
|
||||
yield feedItem.eraseTx();
|
||||
assert.isFalse(yield Zotero.FeedItems.getAsync(feedItem.id));
|
||||
|
||||
//yield assert.isRejected(feedItem.forceEraseTx(), "does not allow erasing twice");
|
||||
//yield assert.isRejected(feedItem.EraseTx(), "does not allow erasing twice");
|
||||
});
|
||||
it("should require edit check override to erase", function* () {
|
||||
let feedItem = yield createDataObject('feedItem', { libraryID });
|
||||
it("should remove synced setting if exists", function* () {
|
||||
let item = yield createDataObject('feedItem', { libraryID });
|
||||
|
||||
yield assert.isRejected(feedItem.eraseTx(), /^Error: Cannot edit feedItem in read-only library/);
|
||||
yield item.toggleRead();
|
||||
let syncedSettings = feed.getSyncedSettings();
|
||||
assert.ok(syncedSettings.markedAsRead[item.guid]);
|
||||
|
||||
yield item.eraseTx();
|
||||
|
||||
syncedSettings = feed.getSyncedSettings();
|
||||
assert.notOk(syncedSettings.markedAsRead[item.guid]);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -196,7 +198,7 @@ describe("Zotero.FeedItem", function () {
|
|||
it('should toggle state', function* () {
|
||||
let item = yield createDataObject('feedItem', { libraryID });
|
||||
item.isRead = false;
|
||||
yield item.forceSaveTx();
|
||||
yield item.saveTx();
|
||||
|
||||
yield item.toggleRead();
|
||||
assert.isTrue(item.isRead, "item is toggled to read state");
|
||||
|
@ -204,7 +206,7 @@ describe("Zotero.FeedItem", function () {
|
|||
it('should save if specified state is different from current', function* (){
|
||||
let item = yield createDataObject('feedItem', { libraryID });
|
||||
item.isRead = false;
|
||||
yield item.forceSaveTx();
|
||||
yield item.saveTx();
|
||||
sinon.spy(item, 'save');
|
||||
|
||||
yield item.toggleRead(true);
|
||||
|
@ -215,6 +217,17 @@ describe("Zotero.FeedItem", function () {
|
|||
yield item.toggleRead(true);
|
||||
assert.isFalse(item.save.called, "item was not saved on toggle read to same state");
|
||||
});
|
||||
it('should set relevant synced settings', function* () {
|
||||
let item = yield createDataObject('feedItem', { libraryID });
|
||||
item.isRead = false;
|
||||
yield item.saveTx();
|
||||
|
||||
yield item.toggleRead();
|
||||
|
||||
let feed = Zotero.Feeds.get(item.libraryID);
|
||||
let syncedSettings = feed.getSyncedSettings();
|
||||
assert.ok(syncedSettings.markedAsRead[item.guid], "item marked as read stored in synced settings");
|
||||
});
|
||||
});
|
||||
|
||||
describe('#translate()', function() {
|
||||
|
@ -224,9 +237,9 @@ describe("Zotero.FeedItem", function () {
|
|||
});
|
||||
it('translates and saves items', function* () {
|
||||
var feedItem = yield createDataObject('feedItem', {libraryID});
|
||||
var url = getTestDataItemUrl('metadata/journalArticle-single.html');
|
||||
var url = getTestDataUrl('metadata/journalArticle-single.html');
|
||||
feedItem.setField('url', url);
|
||||
yield feedItem.forceSaveTx();
|
||||
yield feedItem.saveTx();
|
||||
|
||||
yield feedItem.translate();
|
||||
|
||||
|
@ -237,9 +250,9 @@ describe("Zotero.FeedItem", function () {
|
|||
let collection = yield createDataObject('collection', {libraryID: group.libraryID});
|
||||
|
||||
var feedItem = yield createDataObject('feedItem', {libraryID});
|
||||
var url = getTestDataItemUrl('metadata/journalArticle-single.html');
|
||||
var url = getTestDataUrl('metadata/journalArticle-single.html');
|
||||
feedItem.setField('url', url);
|
||||
yield feedItem.forceSaveTx();
|
||||
yield feedItem.saveTx();
|
||||
|
||||
yield feedItem.translate(group.libraryID, collection.id);
|
||||
|
||||
|
|
|
@ -7,6 +7,51 @@ describe("Zotero.FeedItems", function () {
|
|||
return clearFeeds();
|
||||
});
|
||||
|
||||
describe("#getMarkedAsRead", function() {
|
||||
var items = [];
|
||||
var result;
|
||||
before(function* () {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
let f = yield createDataObject('feedItem', {libraryID: feed.libraryID, guid: 'http://www.example.com/' + i});
|
||||
items.push(f);
|
||||
}
|
||||
yield items[0].toggleRead();
|
||||
yield items[2].toggleRead();
|
||||
result = yield Zotero.FeedItems.getMarkedAsRead(feed.libraryID);
|
||||
});
|
||||
it('should get all marked as read items', function() {
|
||||
assert.include(result, items[0]);
|
||||
assert.include(result, items[2]);
|
||||
});
|
||||
it('should not include items that were not marked', function() {
|
||||
assert.notInclude(result, items[1]);
|
||||
assert.notInclude(result, items[3]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#markAsReadByGUID", function() {
|
||||
var items = [];
|
||||
var result;
|
||||
before(function* () {
|
||||
for (let i = 0; i < 4; i++) {
|
||||
let f = yield createDataObject('feedItem', {
|
||||
libraryID: feed.libraryID,
|
||||
guid: 'http://' + Zotero.Utilities.randomString() + '.com/feed.rss'
|
||||
});
|
||||
items.push(f);
|
||||
}
|
||||
yield Zotero.FeedItems.markAsReadByGUID([items[0].guid, items[2].guid]);
|
||||
});
|
||||
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() {
|
||||
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());
|
||||
|
@ -14,7 +59,7 @@ describe("Zotero.FeedItems", function () {
|
|||
});
|
||||
it("should return feed item id from GUID", function* () {
|
||||
let feedItem = yield createDataObject('feedItem', { libraryID: feed.libraryID });
|
||||
yield feedItem.forceSaveTx();
|
||||
yield feedItem.saveTx();
|
||||
|
||||
let id2 = yield Zotero.FeedItems.getIDFromGUID(feedItem.guid);
|
||||
assert.equal(id2, feedItem.id);
|
||||
|
@ -24,7 +69,7 @@ describe("Zotero.FeedItems", function () {
|
|||
it("should return feed item from GUID", function* () {
|
||||
let guid = Zotero.randomString();
|
||||
let feedItem = yield createDataObject('feedItem', { guid, libraryID: feed.libraryID });
|
||||
yield feedItem.forceSaveTx();
|
||||
yield feedItem.saveTx();
|
||||
|
||||
let feedItem2 = yield Zotero.FeedItems.getAsyncByGUID(guid);
|
||||
assert.equal(feedItem2.id, feedItem.id);
|
||||
|
@ -48,7 +93,7 @@ describe("Zotero.FeedItems", function () {
|
|||
for (let i = 0; i < 10; i++) {
|
||||
let item = yield createDataObject('feedItem', { guid: Zotero.randomString(), libraryID: feed.id });
|
||||
item.isRead = true;
|
||||
yield item.forceSaveTx();
|
||||
yield item.saveTx();
|
||||
items.push(item);
|
||||
}
|
||||
ids = Array.map(items, (i) => i.id);
|
||||
|
@ -66,7 +111,7 @@ describe("Zotero.FeedItems", function () {
|
|||
|
||||
it('should toggle all items read if at least one unread', function* () {
|
||||
items[0].isRead = false;
|
||||
yield items[0].forceSaveTx();
|
||||
yield items[0].saveTx();
|
||||
|
||||
yield Zotero.FeedItems.toggleReadByID(ids);
|
||||
|
||||
|
@ -85,7 +130,7 @@ describe("Zotero.FeedItems", function () {
|
|||
|
||||
it('should toggle all items unread if unread state specified', function* () {
|
||||
items[0].isRead = false;
|
||||
yield items[0].forceSaveTx();
|
||||
yield items[0].saveTx();
|
||||
|
||||
yield Zotero.FeedItems.toggleReadByID(ids, false);
|
||||
|
||||
|
@ -93,5 +138,15 @@ describe("Zotero.FeedItems", function () {
|
|||
assert.isFalse(save.thisValues[i].isRead, "#toggleRead called with true");
|
||||
}
|
||||
});
|
||||
|
||||
it('should set relevant sync settings', function* () {
|
||||
items[0].isRead = false;
|
||||
yield items[0].saveTx();
|
||||
yield Zotero.FeedItems.toggleReadByID(ids);
|
||||
|
||||
let syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
|
||||
let markedAsRead = Object.keys(syncedFeeds[feed.url].markedAsRead);
|
||||
assert.deepEqual(markedAsRead, Object.keys(items).map((k) => items[k].guid));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
describe("Zotero.FeedReader", function () {
|
||||
|
||||
var htmlUrl = getTestDataItemUrl("test.html");
|
||||
var htmlUrl = getTestDataUrl("test.html");
|
||||
|
||||
var feedUrl = getTestDataItemUrl("feed.rss");
|
||||
var feedUrl = getTestDataUrl("feed.rss");
|
||||
var feedInfo = {
|
||||
title: 'Liftoff News',
|
||||
subtitle: 'Liftoff to Space Exploration.',
|
||||
|
@ -18,7 +18,7 @@ describe("Zotero.FeedReader", function () {
|
|||
language: 'en-us'
|
||||
};
|
||||
|
||||
var detailedFeedUrl = getTestDataItemUrl("feedDetailed.rss");
|
||||
var detailedFeedUrl = getTestDataUrl("feedDetailed.rss");
|
||||
var detailedFeedInfo = {
|
||||
title: 'Feed',
|
||||
subtitle: 'Feed Description',
|
||||
|
@ -106,20 +106,15 @@ describe("Zotero.FeedReader", function () {
|
|||
});
|
||||
|
||||
it('should parse items correctly for a sparse feed', function* () {
|
||||
let expected = {
|
||||
guid: 'http://liftoff.msfc.nasa.gov/2003/06/03.html#item573',
|
||||
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 Star City.',
|
||||
url: 'http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp',
|
||||
creators: [{
|
||||
firstName: '',
|
||||
lastName: 'editor@example.com',
|
||||
creatorType: 'author',
|
||||
fieldMode: 1
|
||||
}],
|
||||
creators: [{ firstName: '', lastName: 'editor@example.com', creatorType: 'author', fieldMode: 1 }],
|
||||
date: 'Tue, 03 Jun 2003 09:39:21 GMT',
|
||||
language: 'en-us',
|
||||
itemType: 'journalArticle'
|
||||
itemType: 'journalArticle',
|
||||
enclosedItems: [{ url: 'http://www.example.com/example.pdf', contentType: 'application/pdf' }]
|
||||
};
|
||||
|
||||
let fr = new Zotero.FeedReader(feedUrl);
|
||||
|
@ -149,7 +144,8 @@ describe("Zotero.FeedReader", function () {
|
|||
publisher: 'Publisher',
|
||||
rights: '©2016 Published by Publisher',
|
||||
language: 'en',
|
||||
itemType: 'journalArticle'
|
||||
itemType: 'journalArticle',
|
||||
enclosedItems: []
|
||||
};
|
||||
|
||||
let fr = new Zotero.FeedReader(detailedFeedUrl);
|
||||
|
|
|
@ -42,12 +42,11 @@ describe("Zotero.Feed", function() {
|
|||
yield feed.saveTx();
|
||||
assert.isFalse(feed.editable);
|
||||
});
|
||||
it("should not allow adding items without editCheck override", function* () {
|
||||
it("should allow adding items without editCheck override", function* () {
|
||||
let feed = yield createFeed();
|
||||
let feedItem = new Zotero.FeedItem('book', { guid: Zotero.randomString() });
|
||||
feedItem.libraryID = feed.libraryID;
|
||||
yield assert.isRejected(feedItem.saveTx(), /^Error: Cannot edit feedItem in read-only library/);
|
||||
yield assert.isFulfilled(feedItem.saveTx({ skipEditCheck: true }));
|
||||
yield assert.isFulfilled(feedItem.saveTx());
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -135,6 +134,31 @@ describe("Zotero.Feed", function() {
|
|||
assert.equal(feed.name, 'bar');
|
||||
assert.equal(dbVal, feed.name);
|
||||
});
|
||||
it("should add a new synced setting after creation", 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});
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
|
||||
assert.notOk(syncedFeeds[oldUrl]);
|
||||
assert.ok(syncedFeeds[feed.url]);
|
||||
});
|
||||
});
|
||||
describe("#erase()", function() {
|
||||
it("should erase a saved feed", function* () {
|
||||
|
@ -160,10 +184,59 @@ describe("Zotero.Feed", function() {
|
|||
|
||||
assert.notOk(yield Zotero.FeedItems.getAsync(feedItem.id));
|
||||
});
|
||||
it("should remove synced settings", function* () {
|
||||
let url = 'http://' + Zotero.Utilities.randomString(10, 'abcde') + '.com/feed.rss';
|
||||
let feed = yield createFeed({url});
|
||||
|
||||
let syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
|
||||
assert.ok(syncedFeeds[feed.url]);
|
||||
|
||||
yield feed.eraseTx();
|
||||
|
||||
syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
|
||||
assert.notOk(syncedFeeds[url]);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe("#getSyncedSettings", function() {
|
||||
it("should return correct synced settings for the feed", 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]);
|
||||
|
||||
let feed = yield createFeed({url});
|
||||
|
||||
syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
|
||||
assert.ok(syncedFeeds[url]);
|
||||
|
||||
let syncedData = feed.getSyncedSettings();
|
||||
|
||||
assert.deepEqual(syncedData, syncedFeeds[url]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#storeSyncedSettings", function() {
|
||||
it("should store updated settings for the feed", function* () {
|
||||
let guid = Zotero.Utilities.randomString();
|
||||
let feed = yield createFeed();
|
||||
|
||||
let syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
|
||||
assert.notOk(syncedFeeds[feed.url].markedAsRead[guid]);
|
||||
|
||||
let syncedData = feed.getSyncedSettings();
|
||||
syncedData.markedAsRead[guid] = true;
|
||||
yield feed.setSyncedSettings(syncedData);
|
||||
yield feed.storeSyncedSettings();
|
||||
|
||||
syncedFeeds = Zotero.SyncedSettings.get(Zotero.Libraries.userLibraryID, 'feeds');
|
||||
|
||||
assert.isTrue(syncedFeeds[feed.url].markedAsRead[guid]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#clearExpiredItems()", function() {
|
||||
var feed, expiredFeedItem, readFeedItem, feedItem, feedItemIDs;
|
||||
var feed, expiredFeedItem, readFeedItem, feedItem, readStillInFeed, feedItemIDs;
|
||||
|
||||
before(function* (){
|
||||
feed = yield createFeed({cleanupAfter: 1});
|
||||
|
@ -173,11 +246,18 @@ describe("Zotero.Feed", function() {
|
|||
expiredFeedItem.isRead = true;
|
||||
expiredFeedItem._feedItemReadTime = Zotero.Date.dateToSQL(
|
||||
new Date(Date.now() - 2 * 24*60*60*1000), true);
|
||||
yield expiredFeedItem.forceSaveTx();
|
||||
yield expiredFeedItem.saveTx();
|
||||
|
||||
readStillInFeed = yield createDataObject('feedItem', { libraryID: feed.libraryID });
|
||||
// Read 2 days ago
|
||||
readStillInFeed.isRead = true;
|
||||
readStillInFeed._feedItemReadTime = Zotero.Date.dateToSQL(
|
||||
new Date(Date.now() - 2 * 24*60*60*1000), true);
|
||||
yield readStillInFeed.saveTx();
|
||||
|
||||
readFeedItem = yield createDataObject('feedItem', { libraryID: feed.libraryID });
|
||||
readFeedItem.isRead = true;
|
||||
yield readFeedItem.forceSaveTx();
|
||||
yield readFeedItem.saveTx();
|
||||
|
||||
feedItem = yield createDataObject('feedItem', { libraryID: feed.libraryID });
|
||||
|
||||
|
@ -186,8 +266,9 @@ describe("Zotero.Feed", function() {
|
|||
assert.include(feedItemIDs, feedItem.id, "feed contains unread feed item");
|
||||
assert.include(feedItemIDs, readFeedItem.id, "feed contains read feed item");
|
||||
assert.include(feedItemIDs, expiredFeedItem.id, "feed contains expired feed item");
|
||||
assert.include(feedItemIDs, readStillInFeed.id, "feed contains expired but still in rss feed item");
|
||||
|
||||
yield feed.clearExpiredItems();
|
||||
yield feed.clearExpiredItems(new Set([readStillInFeed.id]));
|
||||
|
||||
feedItemIDs = yield Zotero.FeedItems.getAll(feed.libraryID).map((row) => row.id);
|
||||
});
|
||||
|
@ -198,7 +279,11 @@ describe("Zotero.Feed", 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() {
|
||||
assert.include(feedItemIDs, readStillInFeed.id, "feed still contains read still in rss feed item");
|
||||
});
|
||||
|
||||
it('should not clear unread items', function() {
|
||||
assert.include(feedItemIDs, feedItem.id, "feed still contains new feed item");
|
||||
|
@ -207,8 +292,8 @@ describe("Zotero.Feed", function() {
|
|||
|
||||
describe('#updateFeed()', function() {
|
||||
var feed;
|
||||
var feedUrl = getTestDataItemUrl("feed.rss");
|
||||
var modifiedFeedUrl = getTestDataItemUrl("feedModified.rss");
|
||||
var feedUrl = getTestDataUrl("feed.rss");
|
||||
var modifiedFeedUrl = getTestDataUrl("feedModified.rss");
|
||||
|
||||
beforeEach(function* (){
|
||||
feed = yield createFeed();
|
||||
|
@ -232,11 +317,12 @@ describe("Zotero.Feed", function() {
|
|||
});
|
||||
|
||||
it('should add new feed items', function* () {
|
||||
let feedItems = yield Zotero.FeedItems.getAll(feed.id);
|
||||
let feedItems = yield Zotero.FeedItems.getAll(feed.id, true);
|
||||
assert.equal(feedItems.length, 3);
|
||||
});
|
||||
|
||||
it('should set lastCheck, lastUpdated and lastGUID values', function* () {
|
||||
it('should set lastCheck and lastUpdated values', function* () {
|
||||
yield clearFeeds();
|
||||
let feed = yield createFeed();
|
||||
feed._feedUrl = feedUrl;
|
||||
|
||||
|
@ -245,15 +331,14 @@ describe("Zotero.Feed", function() {
|
|||
|
||||
yield feed.updateFeed();
|
||||
|
||||
assert.ok(feed.lastCheck >= Zotero.Date.dateToSQL(new Date(Date.now() - 1000*60), true));
|
||||
assert.ok(feed.lastUpdate >= Zotero.Date.dateToSQL(new Date(Date.now() - 1000*60), true));
|
||||
assert.equal(feed.lastGUID, 'http://liftoff.msfc.nasa.gov/2003/06/03.html#item573:'+feed.id);
|
||||
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 and set unread', function* () {
|
||||
let feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573:"+feed.id);
|
||||
let feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
|
||||
feedItem.isRead = true;
|
||||
yield feedItem.forceSaveTx();
|
||||
feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573:"+feed.id);
|
||||
yield feedItem.saveTx();
|
||||
feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
|
||||
assert.isTrue(feedItem.isRead);
|
||||
|
||||
let oldDateModified = feedItem.getField('date');
|
||||
|
@ -261,7 +346,7 @@ describe("Zotero.Feed", function() {
|
|||
feed._feedUrl = modifiedFeedUrl;
|
||||
yield feed.updateFeed();
|
||||
|
||||
feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573:"+feed.id);
|
||||
feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
|
||||
|
||||
assert.notEqual(oldDateModified, feedItem.getField('date'));
|
||||
assert.isFalse(feedItem.isRead)
|
||||
|
@ -272,7 +357,7 @@ describe("Zotero.Feed", function() {
|
|||
feed._feedUrl = modifiedFeedUrl;
|
||||
yield feed.updateFeed();
|
||||
|
||||
assert.equal(save.thisValues[0].guid, "http://liftoff.msfc.nasa.gov/2003/06/03.html#item573:"+feed.id);
|
||||
assert.equal(save.thisValues[0].guid, "http://liftoff.msfc.nasa.gov/2003/06/03.html#item573");
|
||||
save.restore();
|
||||
});
|
||||
it('should update unread count', function* () {
|
||||
|
@ -281,7 +366,7 @@ describe("Zotero.Feed", function() {
|
|||
let feedItems = yield Zotero.FeedItems.getAll(feed.id);
|
||||
for (let feedItem of feedItems) {
|
||||
feedItem.isRead = true;
|
||||
yield feedItem.forceSaveTx();
|
||||
yield feedItem.saveTx();
|
||||
}
|
||||
|
||||
feed._feedUrl = modifiedFeedUrl;
|
||||
|
@ -289,20 +374,11 @@ describe("Zotero.Feed", function() {
|
|||
|
||||
assert.equal(feed.unreadCount, 2);
|
||||
});
|
||||
it('should not re-add deleted items, but add new ones', function* () {
|
||||
let feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/05/20.html#item570:"+feed.id);
|
||||
yield feedItem.forceEraseTx();
|
||||
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]);
|
||||
|
||||
let feedItems = yield Zotero.FeedItems.getAll(feed.id);
|
||||
for (let feedItem of feedItems) {
|
||||
feedItem.isRead = true;
|
||||
yield feedItem.forceSaveTx();
|
||||
}
|
||||
|
||||
feed._feedUrl = modifiedFeedUrl;
|
||||
yield feed.updateFeed();
|
||||
|
||||
assert.equal(feed.unreadCount, 2);
|
||||
assert.equal(pdf.getField('url'), "http://www.example.com/example.pdf");
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -311,11 +387,6 @@ describe("Zotero.Feed", function() {
|
|||
before(function* () {
|
||||
feed = yield createFeed();
|
||||
})
|
||||
it("should not allow adding regular items", function* () {
|
||||
let item = new Zotero.Item('book');
|
||||
item.libraryID = feed.libraryID;
|
||||
yield assert.isRejected(item.saveTx({ skipEditCheck: true }), /^Error: Cannot add /);
|
||||
});
|
||||
it("should not allow adding collections", function* () {
|
||||
let collection = new Zotero.Collection({ name: 'test', libraryID: feed.libraryID });
|
||||
yield assert.isRejected(collection.saveTx({ skipEditCheck: true }), /^Error: Cannot add /);
|
||||
|
@ -327,7 +398,7 @@ describe("Zotero.Feed", function() {
|
|||
it("should allow adding feed item", function* () {
|
||||
let feedItem = new Zotero.FeedItem('book', { guid: Zotero.randomString() });
|
||||
feedItem.libraryID = feed.libraryID;
|
||||
yield assert.isFulfilled(feedItem.forceSaveTx());
|
||||
yield assert.isFulfilled(feedItem.saveTx());
|
||||
});
|
||||
});
|
||||
})
|
||||
|
|
|
@ -3,6 +3,77 @@ describe("Zotero.Feeds", function () {
|
|||
after(function* () {
|
||||
yield clearFeeds();
|
||||
});
|
||||
|
||||
describe("#restoreFromJSON", function() {
|
||||
var json = {};
|
||||
var expiredFeedURL, existingFeedURL;
|
||||
|
||||
before(function() {
|
||||
sinon.stub(Zotero.Feed.prototype, 'updateFeed').resolves();
|
||||
});
|
||||
|
||||
after(function() {
|
||||
Zotero.Feed.prototype.updateFeed.restore();
|
||||
});
|
||||
|
||||
beforeEach(function* () {
|
||||
yield clearFeeds();
|
||||
|
||||
for (let i = 0; i < 2; i++) {
|
||||
let url = "http://" + Zotero.Utilities.randomString(10, 'abcdefgh') + ".com/feed.rss";
|
||||
json[url] = {
|
||||
url,
|
||||
name: Zotero.Utilities.randomString(),
|
||||
refreshInterval: 5,
|
||||
cleanupAfter: 3,
|
||||
markedAsRead: []
|
||||
};
|
||||
if (i == 0) {
|
||||
existingFeedURL = url;
|
||||
yield createFeed({url});
|
||||
}
|
||||
}
|
||||
expiredFeedURL = (yield createFeed()).url;
|
||||
});
|
||||
|
||||
it("restores correctly when merge is true", function* () {
|
||||
let feeds = Zotero.Feeds.getAll();
|
||||
assert.equal(feeds.length, 2);
|
||||
|
||||
yield Zotero.Feeds.restoreFromJSON(json, true);
|
||||
feeds = Zotero.Feeds.getAll();
|
||||
|
||||
for (let url in json) {
|
||||
let feed = Zotero.Feeds.getByURL(url);
|
||||
assert.ok(feed, "new feed created");
|
||||
}
|
||||
|
||||
let expiredFeed = Zotero.Feeds.getByURL(expiredFeedURL);
|
||||
assert.ok(expiredFeed, "does not remove feeds not in JSON");
|
||||
|
||||
let existingFeed = Zotero.Feeds.getByURL(existingFeedURL);
|
||||
assert.ok(existingFeed, "does not remove feeds in database and JSON");
|
||||
});
|
||||
|
||||
it("restores correctly when merge is false", function* () {
|
||||
let feeds = Zotero.Feeds.getAll();
|
||||
assert.equal(feeds.length, 2);
|
||||
|
||||
yield Zotero.Feeds.restoreFromJSON(json);
|
||||
feeds = Zotero.Feeds.getAll();
|
||||
|
||||
for (let url in json) {
|
||||
let feed = Zotero.Feeds.getByURL(url);
|
||||
assert.ok(feed, "new feed created");
|
||||
}
|
||||
|
||||
let expiredFeed = Zotero.Feeds.getByURL(expiredFeedURL);
|
||||
assert.notOk(expiredFeed, "removes feeds not in JSON");
|
||||
|
||||
let existingFeed = Zotero.Feeds.getByURL(existingFeedURL);
|
||||
assert.ok(existingFeed, "does not remove feeds in database and JSON");
|
||||
});
|
||||
});
|
||||
|
||||
describe("#haveFeeds()", function() {
|
||||
it("should return false for a DB without feeds", function* () {
|
||||
|
@ -40,6 +111,23 @@ describe("Zotero.Feeds", function () {
|
|||
assert.sameMembers(feeds, [feed1, feed2]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getByURL', function() {
|
||||
it("should return a feed by url", function* () {
|
||||
let url = 'http://' + Zotero.Utilities.randomString(10, 'abcdefg') + '.com/feed.rss';
|
||||
yield 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* () {
|
||||
var feed;
|
||||
assert.doesNotThrow(function() {
|
||||
feed = Zotero.Feeds.getByURL('doesnotexist');
|
||||
});
|
||||
assert.isUndefined(feed);
|
||||
});
|
||||
});
|
||||
describe('#updateFeeds', function() {
|
||||
var freshFeed, recentFeed, oldFeed;
|
||||
var _updateFeed;
|
||||
|
@ -49,7 +137,7 @@ describe("Zotero.Feeds", function () {
|
|||
|
||||
sinon.stub(Zotero.Feeds, 'scheduleNextFeedCheck');
|
||||
_updateFeed = sinon.stub(Zotero.Feed.prototype, '_updateFeed').resolves();
|
||||
let url = getTestDataItemUrl("feed.rss");
|
||||
let url = getTestDataUrl("feed.rss");
|
||||
|
||||
freshFeed = yield createFeed({refreshInterval: 2});
|
||||
freshFeed._feedUrl = url;
|
||||
|
@ -97,7 +185,7 @@ describe("Zotero.Feeds", function () {
|
|||
break;
|
||||
}
|
||||
// should never reach
|
||||
assert.isOk(null, "does not update feed that did not need updating")
|
||||
assert.ok(null, "does not update feed that did not need updating")
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -131,7 +131,7 @@ describe("Zotero.Items", function () {
|
|||
|
||||
let feedItem = new Zotero.FeedItem('journalArticle', { guid: Zotero.randomString() });
|
||||
feedItem.libraryID = feed.libraryID;
|
||||
let id = yield feedItem.forceSaveTx();
|
||||
let id = yield feedItem.saveTx();
|
||||
|
||||
feedItem = yield Zotero.Items.getAsync(id);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue