Various feeds changes

- Change sort order for feed items to natural order
- Remove display of dates in itembox
- Trim html tags from creators in FeedReader parser
This commit is contained in:
Adomas Venčkauskas 2016-02-05 18:29:15 +00:00 committed by Dan Stillman
parent 5e706c31ad
commit e206b0af5e
14 changed files with 118 additions and 192 deletions

View file

@ -341,7 +341,9 @@
fieldNames.push(Zotero.ItemFields.getName(fields[i]));
}
fieldNames.push("dateAdded", "dateModified");
if (! (this.item instanceof Zotero.FeedItem)) {
fieldNames.push("dateAdded", "dateModified");
}
}
for (var i=0; i<fieldNames.length; i++) {

View file

@ -85,7 +85,7 @@ Zotero.defineProperty(Zotero.Feed, '_unreadCountSQL', {
Zotero.defineProperty(Zotero.Feed, '_dbColumns', {
value: Object.freeze(['name', 'url', 'lastUpdate', 'lastCheck',
'lastCheckError', 'cleanupAfter', 'refreshInterval'])
'lastCheckError', 'lastGUID', 'cleanupAfter', 'refreshInterval'])
});
Zotero.defineProperty(Zotero.Feed, '_primaryDataSQLParts');
@ -130,7 +130,7 @@ for (let i=0; i<accessors.length; i++) {
set: function(v) this._set(prop, v)
})
}
let getters = ['lastCheck', 'lastUpdate', 'lastCheckError'];
let getters = ['lastCheck', 'lastUpdate', 'lastCheckError', 'lastGUID'];
for (let i=0; i<getters.length; i++) {
let name = getters[i];
let prop = Zotero.Feed._colToProp(name);
@ -212,6 +212,7 @@ Zotero.Feed.prototype._loadDataFromRow = function(row) {
this._feedLastCheckError = row._feedLastCheckError || null;
this._feedLastCheck = row._feedLastCheck || null;
this._feedLastUpdate = row._feedLastUpdate || null;
this._feedLastGUID = row._feedLastGUID || null;
this._feedCleanupAfter = parseInt(row._feedCleanupAfter) || null;
this._feedRefreshInterval = parseInt(row._feedRefreshInterval) || null;
this._feedUnreadCount = parseInt(row._feedUnreadCount);
@ -328,6 +329,7 @@ Zotero.Feed.prototype.clearExpiredItems = Zotero.Promise.coroutine(function* ()
Zotero.Feed.prototype._updateFeed = Zotero.Promise.coroutine(function* () {
var toAdd = [];
var createNew = true;
if (this._updating) {
return this._updating;
}
@ -343,20 +345,16 @@ Zotero.Feed.prototype._updateFeed = Zotero.Promise.coroutine(function* () {
let itemIterator = new fr.ItemIterator();
let item, processedGUIDs = [];
while (item = yield itemIterator.next().value) {
// NOTE: Might cause issues with feeds that set pubDate for publication date of the item
// rather than the date the item was added to the feed.
if (item.dateModified && this.lastUpdate
&& item.dateModified < this.lastUpdate
) {
Zotero.debug("Item modification date before last update date (" + this.lastCheck + ")");
// Append id at the end to prevent same item collisions from different feeds
// when to terminate item retrieval.
item.guid += ":" + this.id;
if (item.guid == this.lastGUID) {
Zotero.debug("Feed#update: last seen item reached (" + this.lastGUID + ")");
Zotero.debug(item);
// We can stop now
fr.terminate();
break;
// Don't create new items (expired and deleted), but update existing ones
createNew = false;
}
// Append id at the end to prevent same item collisions from different feeds
item.guid += ":" + this.id;
if (processedGUIDs.indexOf(item.guid) != -1) {
Zotero.debug("Feed item " + item.guid + " already processed from feed.");
continue;
@ -367,30 +365,29 @@ Zotero.Feed.prototype._updateFeed = Zotero.Promise.coroutine(function* () {
Zotero.debug(item, 5);
let feedItem = yield Zotero.FeedItems.getAsyncByGUID(item.guid);
if (!feedItem) {
if (!feedItem && createNew) {
feedItem = new Zotero.FeedItem();
feedItem.guid = item.guid;
feedItem.libraryID = this.id;
} else {
} else if(! feedItem.isTranslated) {
Zotero.debug("Feed item " + item.guid + " already in library.");
if (!item.dateModified ||
(feedItem.dateModified && feedItem.dateModified == item.dateModified)
) {
Zotero.debug("Modification date has not changed. Skipping update.");
continue;
}
Zotero.debug("Updating metadata");
yield feedItem.loadItemData();
yield feedItem.loadCreators();
feedItem.isRead = false;
} else {
// Either has been translated or beyond lastGUID
continue;
}
// Delete invalid data
delete item.guid;
delete item.dateAdded;
feedItem.fromJSON(item);
if (!feedItem.hasChanged()) {
Zotero.debug("Feed item " + feedItem.guid + " has not changed");
continue
}
feedItem.isRead = false;
toAdd.push(feedItem);
}
}
@ -411,6 +408,7 @@ Zotero.Feed.prototype._updateFeed = Zotero.Promise.coroutine(function* () {
}
});
this._set('_feedLastUpdate', Zotero.Date.dateToSQL(new Date(), true));
this._set('_feedLastGUID', toAdd[0].guid);
}
this._set('_feedLastCheck', Zotero.Date.dateToSQL(new Date(), true));
yield this.saveTx();

View file

@ -31,6 +31,7 @@ Zotero.FeedItem = function(itemTypeOrID, params = {}) {
Zotero.FeedItem._super.call(this, itemTypeOrID);
this._feedItemReadTime = null;
this._feedItemTranslatedTime = null;
Zotero.Utilities.assignProps(this, params, ['guid']);
};
@ -70,21 +71,21 @@ Zotero.defineProperty(Zotero.FeedItem.prototype, 'isRead', {
}
});
//
//Zotero.defineProperty(Zotero.FeedItem.prototype, 'isTranslated', {
// get: function() {
// return !!this._feedItemTranslationTime;
// },
// set: function(state) {
// if (state != !!this._feedItemTranslationTime) {
// if (state) {
// this._feedItemTranslationTime = Zotero.Date.dateToSQL(new Date(), true);
// } else {
// this._feedItemTranslationTime = null;
// }
// this._changed.feedItemData = true;
// }
// }
//});
Zotero.defineProperty(Zotero.FeedItem.prototype, 'isTranslated', {
get: function() {
return !!this._feedItemTranslatedTime;
},
set: function(state) {
if (state != !!this._feedItemTranslatedTime) {
if (state) {
this._feedItemTranslatedTime = Zotero.Date.dateToSQL(new Date(), true);
} else {
this._feedItemTranslatedTime = null;
}
this._changed.feedItemData = true;
}
}
});
Zotero.FeedItem.prototype.loadPrimaryData = Zotero.Promise.coroutine(function* (reload, failOnMissing) {
if (this.guid && !this.id) {
@ -166,17 +167,12 @@ Zotero.FeedItem.prototype.forceSaveTx = function(options) {
return this.saveTx(newOptions);
}
Zotero.FeedItem.prototype.save = function(options = {}) {
options.skipDateModifiedUpdate = true;
return Zotero.FeedItem._super.prototype.save.apply(this, arguments)
}
Zotero.FeedItem.prototype._saveData = Zotero.Promise.coroutine(function* (env) {
yield Zotero.FeedItem._super.prototype._saveData.apply(this, arguments);
if (this._changed.feedItemData || env.isNew) {
var sql = "REPLACE INTO feedItems VALUES (?,?,?)";
yield Zotero.DB.queryAsync(sql, [env.id, this.guid, this._feedItemReadTime]);
var sql = "REPLACE INTO feedItems VALUES (?,?,?,?)";
yield Zotero.DB.queryAsync(sql, [env.id, this.guid, this._feedItemReadTime, this._feedItemTranslatedTime]);
this._clearChanged('feedItemData');
}
@ -262,6 +258,7 @@ Zotero.FeedItem.prototype.translate = Zotero.Promise.coroutine(function* (librar
// TODO: handle no items like the ones in french history studies feed
// set new translated data for item
this.fromJSON(itemData);
this.isTranslated = true;
this.forceSaveTx();
return this;

View file

@ -40,6 +40,7 @@ Zotero.FeedItems = new Proxy(function() {
let obj = zi_primaryDataSQLParts.call(this);
obj.feedItemGUID = "FeI.guid AS feedItemGUID";
obj.feedItemReadTime = "FeI.readTime AS feedItemReadTime";
obj.feedItemTranslatedTime = "FeI.translatedTime AS feedItemTranslatedTime";
return obj;
}
}, {lazy: true});

View file

@ -289,7 +289,7 @@ Zotero.FeedReader._processCreators = function(feedEntry, field, role) {
let person = personArr.queryElementAt(i, Components.interfaces.nsIFeedPerson);
if (!person || !person.name) continue;
let name = Zotero.Utilities.trimInternal(person.name);
let name = Zotero.Utilities.cleanTags(Zotero.Utilities.trimInternal(person.name));
if (!name) continue;
let commas = name.split(',').length - 1,
@ -336,6 +336,10 @@ Zotero.FeedReader._processCreators = function(feedEntry, field, role) {
if (!creator.firstName) {
creator.fieldMode = 1;
}
// Sometimes these end up empty when parsing really nasty HTML based fields, so just skip.
if (!creator.firstName && !creator.lastName) {
continue;
}
creators.push(creator);
}
@ -376,43 +380,6 @@ Zotero.FeedReader._getFeedItem = function(feedEntry, feedInfo) {
if (feedEntry.link) item.url = feedEntry.link.spec;
if (feedEntry.updated) item.dateModified = new Date(feedEntry.updated);
if (feedEntry.published) {
var date = new Date(feedEntry.published);
if (!date.getUTCSeconds() && !(date.getUTCHours() && date.getUTCMinutes())) {
// There was probably no time, but there may have been a a date range,
// so something could have ended up in the hour _or_ minute field
date = getFeedField(feedEntry, 'pubDate')
/* In case it was magically pulled from some other field */
|| ( date.getUTCFullYear() + '-'
+ (date.getUTCMonth() + 1) + '-'
+ date.getUTCDate() );
}
else {
date = Zotero.Date.dateToSQL(date, true);
}
item.dateAdded = date;
if (!item.dateModified) {
items.dateModified = date;
}
}
if (!item.dateModified) {
// When there's no reliable modification date, we can assume that item doesn't get updated
Zotero.debug("FeedReader: Feed item missing a modification date (" + item.guid + ")");
} else {
// Convert date modified to string, since those are directly comparable
item.dateModified = Zotero.Date.dateToSQL(item.dateModified, true);
}
if (!item.dateAdded && item.dateModified) {
// Use lastModified date
item.dateAdded = item.dateModified;
}
if (feedEntry.rights) item.rights = Zotero.FeedReader._getRichText(feedEntry.rights, 'rights');
item.creators = Zotero.FeedReader._processCreators(feedEntry, 'authors', 'author');
@ -429,8 +396,11 @@ Zotero.FeedReader._getFeedItem = function(feedEntry, feedInfo) {
/** Done with basic metadata, now look for better data **/
date = Zotero.FeedReader._getFeedField(feedEntry, 'publicationDate', 'prism')
|| Zotero.FeedReader._getFeedField(feedEntry, 'date', 'dc');
let date = Zotero.FeedReader._getFeedField(feedEntry, 'publicationDate', 'prism')
|| Zotero.FeedReader._getFeedField(feedEntry, 'date', 'dc')
|| Zotero.FeedReader._getFeedField(feedEntry, 'pubDate') // RSS
|| Zotero.FeedReader._getFeedField(feedEntry, 'published') // Atom
|| Zotero.FeedReader._getFeedField(feedEntry, 'updated'); // Atom
if (date) item.date = date;
let publicationTitle = Zotero.FeedReader._getFeedField(feedEntry, 'publicationName', 'prism')

View file

@ -98,7 +98,6 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (tree
}
this._treebox = treebox;
this.setSortColumn();
if (this._ownerDocument.defaultView.ZoteroPane_Local) {
this._ownerDocument.defaultView.ZoteroPane_Local.setItemsPaneMessage(Zotero.getString('pane.items.loading'));
@ -260,48 +259,6 @@ Zotero.ItemTreeView.prototype.setTree = Zotero.Promise.coroutine(function* (tree
});
Zotero.ItemTreeView.prototype.setSortColumn = function() {
var dir, col, currentCol, currentDir;
for (let i=0, len=this._treebox.columns.count; i<len; i++) {
let column = this._treebox.columns.getColumnAt(i);
if (column.element.getAttribute('sortActive')) {
currentCol = column;
currentDir = column.element.getAttribute('sortDirection');
column.element.removeAttribute('sortActive');
column.element.removeAttribute('sortDirection');
break;
}
}
let colId = Zotero.Prefs.get('itemTree.sortColumnId');
// Restore previous sort setting (feed -> non-feed)
if (! this.collectionTreeRow.isFeed() && colId) {
col = this._treebox.columns.getNamedColumn(colId);
dir = Zotero.Prefs.get('itemTree.sortDirection');
Zotero.Prefs.clear('itemTree.sortColumnId');
Zotero.Prefs.clear('itemTree.sortDirection');
// Sort Feeds by dateAdded (anything -> feed)
} else if (this.collectionTreeRow.isFeed()) {
col = this._treebox.columns.getNamedColumn("zotero-items-column-dateAdded");
dir = 'descending';
// No previous sort setting stored, so store it (non-feed -> feed)
if (!colId && currentCol) {
Zotero.Prefs.set('itemTree.sortColumnId', currentCol.id);
Zotero.Prefs.set('itemTree.sortDirection', currentDir);
}
// Retain current sort setting (non-feed -> non-feed)
} else {
col = currentCol;
dir = currentDir;
}
if (col) {
col.element.setAttribute('sortActive', true);
col.element.setAttribute('sortDirection', dir);
}
}
/**
* Reload the rows from the data access methods
* (doesn't call the tree.invalidate methods, etc.)
@ -2130,9 +2087,12 @@ Zotero.ItemTreeView.prototype.getSortedItems = function(asIDs) {
Zotero.ItemTreeView.prototype.getSortField = function() {
var column = this._treebox.columns.getSortedColumn()
if (this.collectionTreeRow.isFeed()) {
return 'id';
}
var column = this._treebox.columns.getSortedColumn();
if (!column) {
column = this._treebox.columns.getFirstColumn()
column = this._treebox.columns.getFirstColumn();
}
// zotero-items-column-_________
return column.id.substring(20);
@ -2176,6 +2136,9 @@ Zotero.ItemTreeView.prototype.getSortFields = function () {
* Returns 'ascending' or 'descending'
*/
Zotero.ItemTreeView.prototype.getSortDirection = function() {
if (this.collectionTreeRow.isFeed) {
return Zotero.Prefs.get('feedSortAsc') ? 'asc' : 'desc';
}
var column = this._treebox.columns.getSortedColumn();
if (!column) {
return 'ascending';

View file

@ -2188,9 +2188,6 @@ Zotero.Schema = new function(){
yield Zotero.DB.queryAsync("DROP TABLE tagsOld");
yield Zotero.DB.queryAsync("DROP TABLE librariesOld");
// Feeds
yield Zotero.DB.queryAsync("CREATE TABLE feeds (\n libraryID INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n url TEXT NOT NULL UNIQUE,\n lastUpdate TIMESTAMP,\n lastCheck TIMESTAMP,\n lastCheckError TEXT,\n cleanupAfter INT,\n refreshInterval INT,\n FOREIGN KEY (libraryID) REFERENCES libraries(libraryID) ON DELETE CASCADE\n)");
yield Zotero.DB.queryAsync("CREATE TABLE feedItems (\n itemID INTEGER PRIMARY KEY,\n guid TEXT NOT NULL UNIQUE,\n readTime TIMESTAMP,\n FOREIGN KEY (itemID) REFERENCES items(itemID) ON DELETE CASCADE\n)");
}
if (i == 81) {
@ -2214,6 +2211,14 @@ Zotero.Schema = new function(){
yield Zotero.DB.queryAsync("INSERT INTO itemTypeFields VALUES (17, 98, NULL, 8)");
yield Zotero.DB.queryAsync("INSERT INTO itemTypeFields VALUES (17, 42, NULL, 9)");
}
if (i == 83) {
// Feeds
yield Zotero.DB.queryAsync("DROP TABLE IF EXISTS feeds");
yield Zotero.DB.queryAsync("DROP TABLE IF EXISTS feedItems");
yield Zotero.DB.queryAsync("CREATE TABLE feeds (\n libraryID INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n url TEXT NOT NULL UNIQUE,\n lastUpdate TIMESTAMP,\n lastCheck TIMESTAMP,\n lastCheckError TEXT,\n lastGUID TEXT,\n cleanupAfter INT,\n refreshInterval INT,\n FOREIGN KEY (libraryID) REFERENCES libraries(libraryID) ON DELETE CASCADE\n)");
yield Zotero.DB.queryAsync("CREATE TABLE feedItems (\n itemID INTEGER PRIMARY KEY,\n guid TEXT NOT NULL UNIQUE,\n readTime TIMESTAMP,\n translatedTime TIMESTAMP,\n FOREIGN KEY (itemID) REFERENCES items(itemID) ON DELETE CASCADE\n)");
}
}
yield _updateDBVersion('userdata', toVersion);

View file

@ -1376,7 +1376,9 @@ var ZoteroPane = new function()
}
if (item.isFeedItem) {
item.translate();
if (! item.isTranslated) {
item.translate();
}
this.startItemReadTimeout(item.id);
}
}

View file

@ -62,6 +62,7 @@ pref("extensions.zotero.lastLongTagMode", 0);
pref("extensions.zotero.lastLongTagDelimiter", ";");
pref("extensions.zotero.fallbackSort", 'firstCreator,date,title,dateAdded');
pref("extensions.zotero.feedSortAsc", false);
pref("extensions.zotero.sortCreatorAsString", false);
//Tag Cloud

View file

@ -1,4 +1,4 @@
-- 82
-- 83
-- Copyright (c) 2009 Center for History and New Media
-- George Mason University, Fairfax, Virginia, USA
@ -203,6 +203,7 @@ CREATE TABLE feeds (
lastUpdate TIMESTAMP,
lastCheck TIMESTAMP,
lastCheckError TEXT,
lastGUID TEXT,
cleanupAfter INT,
refreshInterval INT,
FOREIGN KEY (libraryID) REFERENCES libraries(libraryID) ON DELETE CASCADE
@ -212,6 +213,7 @@ CREATE TABLE feedItems (
itemID INTEGER PRIMARY KEY,
guid TEXT NOT NULL UNIQUE,
readTime TIMESTAMP,
translatedTime TIMESTAMP,
FOREIGN KEY (itemID) REFERENCES items(itemID) ON DELETE CASCADE
);

View file

@ -19,11 +19,6 @@
<pubDate>Tue, 03 Jun 2003 09:39:21 GMT</pubDate>
<guid>http://liftoff.msfc.nasa.gov/2003/06/03.html#item573</guid>
</item>
<item>
<description>Sky watchers in Europe, Asia, and parts of Alaska and Canada will experience a &lt;a href="http://science.nasa.gov/headlines/y2003/30may_solareclipse.htm"&gt;partial eclipse of the Sun&lt;/a&gt; on Saturday, May 31st.</description>
<pubDate>Fri, 30 May 2003 11:06:42 GMT</pubDate>
<guid>http://liftoff.msfc.nasa.gov/2003/05/30.html#item572</guid>
</item>
<item>
<title>The Engine That Does More</title>
<link>http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp</link>

View file

@ -13,17 +13,17 @@
<managingEditor>editor@example.com</managingEditor>
<webMaster>webmaster@example.com</webMaster>
<item>
<title>Star City</title>
<description>Sky watchers in Europe, Asia, and parts of Alaska and Canada will experience a &lt;a href="http://science.nasa.gov/headlines/y2003/30may_solareclipse.htm"&gt;partial eclipse of the Sun&lt;/a&gt; on Saturday, May 31st.</description>
<pubDate>Fri, 30 May 2003 11:06:42 GMT</pubDate>
<guid>http://liftoff.msfc.nasa.gov/2003/05/30.html#item572</guid>
</item>
<item>
<title>Star City (Updated)</title>
<link>http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp</link>
<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 &lt;a href="http://howe.iki.rssi.ru/GCTC/gctc_e.htm"&gt;Star City&lt;/a&gt;.</description>
<pubDate>Tue, 03 Jun 2037 09:39:21 GMT</pubDate>
<guid>http://liftoff.msfc.nasa.gov/2003/06/03.html#item573</guid>
</item>
<item>
<description>Sky watchers in Europe, Asia, and parts of Alaska and Canada will experience a &lt;a href="http://science.nasa.gov/headlines/y2003/30may_solareclipse.htm"&gt;partial eclipse of the Sun&lt;/a&gt; on Saturday, May 31st.</description>
<pubDate>Fri, 30 May 2003 11:06:42 GMT</pubDate>
<guid>http://liftoff.msfc.nasa.gov/2003/05/30.html#item572</guid>
</item>
<item>
<title>The Engine That Does More</title>
<link>http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp</link>

View file

@ -111,14 +111,13 @@ describe("Zotero.FeedReader", function () {
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',
dateModified: '2003-06-03 09:39:21',
dateAdded: '2003-06-03 09:39:21',
creators: [{
firstName: '',
lastName: 'editor@example.com',
creatorType: 'author',
fieldMode: 1
}],
date: 'Tue, 03 Jun 2003 09:39:21 GMT',
language: 'en-us',
itemType: 'journalArticle'
};
@ -136,8 +135,6 @@ describe("Zotero.FeedReader", function () {
title: 'Title 1',
abstractNote: 'Description 1',
url: 'http://www.example.com/item1',
dateModified: '2016-01-07 00:00:00',
dateAdded: '2016-01-07 00:00:00',
creators: [
{ firstName: 'Author1 A. T.', lastName: 'Rohtua', creatorType: 'author' },
{ firstName: 'Author2 A.', lastName: 'Auth', creatorType: 'author' },

View file

@ -206,9 +206,16 @@ describe("Zotero.Feed", function() {
});
describe('#updateFeed()', function() {
var feed;
var feedUrl = getTestDataItemUrl("feed.rss");
var modifiedFeedUrl = getTestDataItemUrl("feedModified.rss");
beforeEach(function* (){
feed = yield createFeed();
feed._feedUrl = feedUrl;
yield feed.updateFeed();
});
afterEach(function* () {
yield clearFeeds();
});
@ -225,15 +232,11 @@ describe("Zotero.Feed", function() {
});
it('should add new feed items', function* () {
let feed = yield createFeed();
feed._feedUrl = feedUrl;
yield feed.updateFeed();
let feedItems = yield Zotero.FeedItems.getAll(feed.id);
assert.equal(feedItems.length, 4);
assert.equal(feedItems.length, 3);
});
it('should set lastCheck and lastUpdated values', function* () {
it('should set lastCheck, lastUpdated and lastGUID values', function* () {
let feed = yield createFeed();
feed._feedUrl = feedUrl;
@ -244,61 +247,36 @@ describe("Zotero.Feed", function() {
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);
});
it('should update modified items and set unread', function* () {
let feed = yield createFeed();
feed._feedUrl = feedUrl;
yield feed.updateFeed();
let feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573:"+feed.id);
feedItem.isRead = true;
yield feedItem.forceSaveTx();
feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573:"+feed.id);
assert.isTrue(feedItem.isRead);
let oldDateModified = feedItem.dateModified;
let oldDateModified = feedItem.getField('date');
feed._feedUrl = modifiedFeedUrl;
yield feed.updateFeed();
feedItem = yield Zotero.FeedItems.getAsyncByGUID("http://liftoff.msfc.nasa.gov/2003/06/03.html#item573:"+feed.id);
assert.notEqual(oldDateModified, feedItem.dateModified);
assert.notEqual(oldDateModified, feedItem.getField('date'));
assert.isFalse(feedItem.isRead)
});
it('should skip items that are not modified', function* () {
let feed = yield createFeed();
feed._feedUrl = feedUrl;
yield feed.updateFeed();
let feedItems = yield Zotero.FeedItems.getAll(feed.id);
let datesAdded = [], datesModified = [];
for(let feedItem of feedItems) {
datesAdded.push(feedItem.dateAdded);
datesModified.push(feedItem.dateModified);
}
let save = sinon.spy(Zotero.FeedItem.prototype, 'save');
feed._feedUrl = modifiedFeedUrl;
yield feed.updateFeed();
feedItems = yield Zotero.FeedItems.getAll(feed.id);
let changedCount = 0;
for (let i = 0; i < feedItems.length; i++) {
assert.equal(feedItems[i].dateAdded, datesAdded[i]);
if (feedItems[i].dateModified != datesModified[i]) {
changedCount++;
}
}
assert.equal(changedCount, 1);
assert.equal(save.thisValues[0].guid, "http://liftoff.msfc.nasa.gov/2003/06/03.html#item573:"+feed.id);
save.restore();
});
it('should update unread count', function* () {
let feed = yield createFeed();
feed._feedUrl = feedUrl;
yield feed.updateFeed();
assert.equal(feed.unreadCount, 4);
assert.equal(feed.unreadCount, 3);
let feedItems = yield Zotero.FeedItems.getAll(feed.id);
for (let feedItem of feedItems) {
@ -309,7 +287,22 @@ describe("Zotero.Feed", function() {
feed._feedUrl = modifiedFeedUrl;
yield feed.updateFeed();
assert.equal(feed.unreadCount, 1);
assert.equal(feed.unreadCount, 2);
});
it('should not re-add deleted items, but add new ones', function* () {
let feedItems = yield Zotero.FeedItems.getAll(feed.id);
yield feedItems[1].forceEraseTx();
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);
});
});