Add archived group handling to sync runner

- Archive remotely missing that user chooses to keep
- Ignore archived groups that don't existing remotely
- Unarchive groups that become available again
This commit is contained in:
Dan Stillman 2017-02-24 02:31:08 -05:00
parent 2fe756c1c9
commit 80a0826eb6
2 changed files with 113 additions and 14 deletions

View file

@ -371,9 +371,9 @@ Zotero.Sync.Runner_Module = function (options = {}) {
let group = Zotero.Groups.get(id);
if (syncAllLibraries) {
// If syncing all libraries, mark any that don't exist or are outdated
// locally for update. Group is added to the library list after downloading
if (!group || group.version < remoteGroupVersions[id]) {
// If syncing all libraries, mark any that don't exist, are outdated, or are
// archived locally for update. Group is added to the library list after downloading.
if (!group || group.version < remoteGroupVersions[id] || group.archived) {
groupsToDownload.push(id);
}
// If not outdated, just add to library list
@ -421,6 +421,7 @@ Zotero.Sync.Runner_Module = function (options = {}) {
// TODO: What about explicit deletions?
let removedGroups = [];
let keptGroups = [];
let ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
@ -433,6 +434,12 @@ Zotero.Sync.Runner_Module = function (options = {}) {
//
// TODO: Localize
for (let group of remotelyMissingGroups) {
// Ignore archived groups
if (group.archived) {
groupsToDownload.splice(groupsToDownload.indexOf(group.id), 1);
continue;
}
let msg;
// If all-groups access but group is missing, user left it
if (access.groups && access.groups.all) {
@ -467,18 +474,25 @@ Zotero.Sync.Runner_Module = function (options = {}) {
return [];
}
else if (index == 2) {
// TODO: Mark groups to be ignored
keptGroups.push(group);
}
}
let removedLibraryIDs = [];
for (let group of removedGroups) {
removedLibraryIDs.push(group.libraryID);
yield Zotero.DB.executeTransaction(function* () {
return group.erase();
});
yield group.eraseTx();
}
libraries = Zotero.Utilities.arrayDiff(libraries, removedLibraryIDs);
let keptLibraryIDs = [];
for (let group of keptGroups) {
keptLibraryIDs.push(group.libraryID);
group.editable = false;
group.archived = true;
yield group.saveTx();
}
libraries = Zotero.Utilities.arrayDiff(libraries, keptLibraryIDs);
}
// Update metadata and permissions on missing or outdated groups
@ -508,6 +522,7 @@ Zotero.Sync.Runner_Module = function (options = {}) {
group.id = groupID;
}
group.version = info.version;
group.archived = false;
group.fromJSON(info.data, Zotero.Users.getCurrentUserID());
yield group.saveTx();
@ -515,6 +530,8 @@ Zotero.Sync.Runner_Module = function (options = {}) {
libraries.push(group.libraryID);
}
// Note: If any non-group library types become archivable, they'll need to be unarchived here.
return [...new Set(libraries)];
});

View file

@ -296,6 +296,64 @@ describe("Zotero.Sync.Runner", function () {
assert.equal(skippedGroup.version, responses.groups.memberGroup.json.version - 1);
});
it("should filter out remotely missing archived libraries if library list not provided", function* () {
var syncedGroupID = responses.groups.ownerGroup.json.id;
var archivedGroupID = 162512451; // nonexistent group id
var syncedGroup = yield createGroup({
id: syncedGroupID,
version: responses.groups.ownerGroup.json.version - 1
});
var archivedGroup = yield createGroup({
id: archivedGroupID,
editable: false,
archived: true
});
setResponse('userGroups.groupVersions');
setResponse('groups.ownerGroup');
var libraries = yield runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json
);
assert.lengthOf(libraries, 3);
assert.sameMembers(libraries, [userLibraryID, publicationsLibraryID, syncedGroup.libraryID]);
});
it("should unarchive library if available remotely", function* () {
var syncedGroupID = responses.groups.ownerGroup.json.id;
var archivedGroupID = responses.groups.memberGroup.json.id;
var syncedGroup = yield createGroup({
id: syncedGroupID,
version: responses.groups.ownerGroup.json.version
});
var archivedGroup = yield createGroup({
id: archivedGroupID,
version: responses.groups.memberGroup.json.version - 1,
editable: false,
archived: true
});
setResponse('userGroups.groupVersions');
setResponse('groups.ownerGroup');
setResponse('groups.memberGroup');
var libraries = yield runner.checkLibraries(
runner.getAPIClient({ apiKey }),
false,
responses.keyInfo.fullAccess.json
);
assert.lengthOf(libraries, 4);
assert.sameMembers(
libraries,
[userLibraryID, publicationsLibraryID, syncedGroup.libraryID, archivedGroup.libraryID]
);
assert.isFalse(archivedGroup.archived);
});
it("shouldn't filter out skipped libraries if library list is provided", function* () {
var groupData = responses.groups.memberGroup;
var group = yield createGroup({
@ -453,21 +511,45 @@ describe("Zotero.Sync.Runner", function () {
assert.isTrue(Zotero.Groups.exists(groupData2.json.id));
})
it.skip("should keep remotely missing groups", function* () {
var groupData = responses.groups.ownerGroup;
var group = yield createGroup({ id: groupData.json.id, version: groupData.json.version });
it("should keep remotely missing groups", function* () {
var group1 = yield createGroup({ editable: true, filesEditable: true });
var group2 = yield createGroup({ editable: true, filesEditable: true });
setResponse('userGroups.groupVersionsEmpty');
var called = 0;
var otherGroup;
waitForDialog(function (dialog) {
called++;
var text = dialog.document.documentElement.textContent;
assert.include(text, group.name);
if (text.includes(group1.name)) {
otherGroup = group2;
}
else if (text.includes(group2.name)) {
otherGroup = group1;
}
else {
throw new Error("Dialog text does not include either group name");
}
waitForDialog(function (dialog) {
called++;
var text = dialog.document.documentElement.textContent;
assert.include(text, otherGroup.name);
}, "extra1");
}, "extra1");
var libraries = yield runner.checkLibraries(
runner.getAPIClient({ apiKey }), false, responses.keyInfo.fullAccess.json
);
assert.lengthOf(libraries, 3);
assert.sameMembers(libraries, [userLibraryID, publicationsLibraryID, group.libraryID]);
assert.isTrue(Zotero.Groups.exists(groupData.json.id));
assert.equal(called, 2);
assert.lengthOf(libraries, 2);
assert.sameMembers(libraries, [userLibraryID, publicationsLibraryID]);
// Groups should still exist but be read-only and archived
[group1, group2].forEach((group) => {
assert.isTrue(Zotero.Groups.exists(group.id));
assert.isTrue(group.archived);
assert.isFalse(group.editable);
assert.isFalse(group.filesEditable);
});
})
it("should cancel sync with remotely missing groups", function* () {