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:
parent
2fe756c1c9
commit
80a0826eb6
2 changed files with 113 additions and 14 deletions
|
@ -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)];
|
||||
});
|
||||
|
||||
|
|
|
@ -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* () {
|
||||
|
|
Loading…
Reference in a new issue