Remove retraction flag from items that no longer match

This commit is contained in:
Dan Stillman 2019-06-19 06:41:33 -04:00
parent a6d7b623ac
commit 50a4308514
2 changed files with 128 additions and 5 deletions

View file

@ -498,10 +498,11 @@ Zotero.Retractions = {
// TODO: Diff list and remove existing retractions that are missing
let possibleMatches = await this._downloadPossibleMatches([...prefixesToSend]);
await this._addPossibleMatches(possibleMatches);
await this._addPossibleMatches(possibleMatches, true);
}
else {
Zotero.debug("No possible retractions");
await this._addPossibleMatches([], true);
}
await this._saveCacheFile(list, etag, doiPrefixLength, pmidPrefixLength);
@ -530,12 +531,16 @@ Zotero.Retractions = {
},
/**
* @param {Object[]} - Results from API search
* @param {Object[]} possibleMatches - Results from API search
* @param {Boolean} [removeExisting = false] - Remove retracted flag from all items that don't
* match the results. This should only be true if possibleMatches includes all possible
* matches in the database.
* @return {Number[]} - Array of added item ids
*/
_addPossibleMatches: async function (possibleMatches) {
_addPossibleMatches: async function (possibleMatches, removeExisting) {
// Look in the key mappings for local items that match and add them as retractions
var addedItemIDs = new Set();
var allItemIDs = new Set();
for (let row of possibleMatches) {
if (row.doi) {
let ids = this._keyItems[this.TYPE_DOI].get(row.doi);
@ -544,6 +549,7 @@ Zotero.Retractions = {
if (!this._retractedItems.has(id)) {
addedItemIDs.add(id);
}
allItemIDs.add(id);
await this._addEntry(id, row);
}
}
@ -555,14 +561,31 @@ Zotero.Retractions = {
if (!this._retractedItems.has(id)) {
addedItemIDs.add(id);
}
allItemIDs.add(id);
await this._addEntry(id, row);
}
}
}
}
Zotero.debug(`Found ${addedItemIDs.size} retracted `
+ Zotero.Utilities.pluralize(addedItemIDs.size, 'item'));
// Remove existing retracted items that no longer match
var removed = 0;
if (removeExisting) {
for (let itemID of this._retractedItems) {
if (!allItemIDs.has(itemID)) {
let item = await Zotero.Items.getAsync(itemID);
await this._removeEntry(itemID, item.libraryID);
removed++;
}
}
}
var msg = `Found ${addedItemIDs.size} retracted `
+ Zotero.Utilities.pluralize(addedItemIDs.size, 'item');
if (removed) {
msg += " and removed " + removed;
}
Zotero.debug(msg);
addedItemIDs = [...addedItemIDs];
if (addedItemIDs.length) {
this._showAlert(addedItemIDs); // async

View file

@ -74,6 +74,106 @@ describe("Retractions", function() {
}
describe("#updateFromServer()", function () {
var server;
var baseURL;
before(function () {
Zotero.HTTP.mock = sinon.FakeXMLHttpRequest;
baseURL = ZOTERO_CONFIG.API_URL + 'retractions/';
});
beforeEach(function () {
server = sinon.fakeServer.create();
server.autoRespond = true;
});
after(async function () {
Zotero.HTTP.mock = null;
// Restore the real list from the server. We could just mock it as part of the suite.
await Zotero.Retractions.updateFromServer();
});
/*it("shouldn't show banner or virtual collection for already flagged items on list update", async function () {
await Zotero.Retractions.updateFromServer();
});*/
it("should remove retraction flag from items that no longer match prefix list", async function () {
var doi = '10.1234/abcde';
var hash = Zotero.Utilities.Internal.sha1(doi);
var prefix = hash.substr(0, 5);
var lines = [
Zotero.Retractions.TYPE_DOI + prefix + ' 12345\n',
Zotero.Retractions.TYPE_DOI + 'aaaaa 23456\n'
];
var listCount = 0;
var searchCount = 0;
server.respond(function (req) {
if (req.method == 'GET' && req.url == baseURL + 'list') {
listCount++;
if (listCount == 1) {
req.respond(
200,
{
'Content-Type': 'text/plain',
'ETag': 'abcdefg'
},
lines.join('')
);
}
else if (listCount == 2) {
req.respond(
200,
{
'Content-Type': 'text/plain',
'ETag': 'bcdefgh'
},
lines[1]
);
}
}
else if (req.method == 'POST' && req.url == baseURL + 'search') {
searchCount++;
if (searchCount == 1) {
req.respond(
200,
{
'Content-Type': 'application/json'
},
JSON.stringify([
{
doi: hash,
retractionDOI: '10.1234/bcdef',
date: '2019-01-02'
}
])
);
}
}
});
await Zotero.Retractions.updateFromServer();
// Create item with DOI from list
var promise = waitForItemEvent('refresh');
var item = createUnsavedDataObject('item', { itemType: 'journalArticle' });
item.setField('DOI', doi);
await item.saveTx();
await promise;
assert.isTrue(Zotero.Retractions.isRetracted(item));
// Make a second request, with the entry removed
promise = waitForItemEvent('refresh');
await Zotero.Retractions.updateFromServer();
await promise;
assert.isFalse(Zotero.Retractions.isRetracted(item));
});
});
describe("#getRetractionsFromJSON()", function () {
it("should identify object with retracted DOI", async function () {
var spy = sinon.spy(Zotero.HTTP, 'request');