Fix error deleting some orphaned or invalid WebDAV files

If a .prop file was passed to `_deleteStorageFiles()`, it would throw
`deletePropURI.QueryInterface is not a function`.
This commit is contained in:
Dan Stillman 2021-12-27 14:52:32 -05:00
parent d955a77e98
commit 3dab64ddbb
2 changed files with 54 additions and 12 deletions

View file

@ -1437,17 +1437,19 @@ Zotero.Sync.Storage.Mode.WebDAV.prototype = {
break;
}
// If an item file URI, get the property URI
// If a .zip file URL, get the .prop file URI
var deletePropURI = this._getPropertyURIFromItemURI(deleteURI);
// Only nsIURL has fileName
deletePropURI.QueryInterface(Ci.nsIURL);
// If we already deleted the prop file, skip it
if (!deletePropURI || results.deleted.has(deletePropURI.fileName)) {
// Not a .zip file URL
if (!deletePropURI) {
return;
}
// Only nsIURL has fileName
deletePropURI.QueryInterface(Ci.nsIURL);
fileName = deletePropURI.fileName;
// Already deleted
if (results.deleted.has(fileName)) {
return;
}
// Delete property file
var req = yield Zotero.HTTP.request(

View file

@ -1008,6 +1008,8 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
},
text: '<?xml version="1.0" encoding="utf-8"?>'
+ '<D:multistatus xmlns:D="DAV:" xmlns:ns0="DAV:">'
// Orphaned files to delete
+ '<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">'
+ `<D:href>${davBasePath}zotero/</D:href>`
+ '<D:propstat>'
@ -1035,7 +1037,6 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
+ '<D:status>HTTP/1.1 200 OK</D:status>'
+ '</D:propstat>'
+ '</D:response>'
+ '<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">'
+ `<D:href>${davBasePath}zotero/AAAAAAAA.zip</D:href>`
+ '<D:propstat>'
@ -1054,9 +1055,28 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
+ '<D:status>HTTP/1.1 200 OK</D:status>'
+ '</D:propstat>'
+ '</D:response>'
+ '<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">'
+ `<D:href>${davBasePath}zotero/BBBBBBBB.zip</D:href>`
+ '<D:propstat>'
+ '<D:prop>'
+ `<lp1:getlastmodified>${beforeTime}</lp1:getlastmodified>`
+ '</D:prop>'
+ '<D:status>HTTP/1.1 200 OK</D:status>'
+ '</D:propstat>'
+ '</D:response>'
+ '<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">'
+ `<D:href>${davBasePath}zotero/BBBBBBBB.prop</D:href>`
+ '<D:propstat>'
+ '<D:prop>'
+ `<lp1:getlastmodified>${beforeTime}</lp1:getlastmodified>`
+ '</D:prop>'
+ '<D:status>HTTP/1.1 200 OK</D:status>'
+ '</D:propstat>'
+ '</D:response>'
// Orphaned files that aren't old enough to delete
+ '<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">'
+ `<D:href>${davBasePath}zotero/CCCCCCCC.zip</D:href>`
+ '<D:propstat>'
+ '<D:prop>'
+ `<lp1:getlastmodified>${currentTime}</lp1:getlastmodified>`
@ -1065,7 +1085,7 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
+ '</D:propstat>'
+ '</D:response>'
+ '<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">'
+ `<D:href>${davBasePath}zotero/BBBBBBBB.prop</D:href>`
+ `<D:href>${davBasePath}zotero/CCCCCCCC.prop</D:href>`
+ '<D:propstat>'
+ '<D:prop>'
+ `<lp1:getlastmodified>${currentTime}</lp1:getlastmodified>`
@ -1125,6 +1145,16 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
url: 'zotero/AAAAAAAA.zip',
status: 204
});
setResponse({
method: "DELETE",
url: 'zotero/BBBBBBBB.prop',
status: 204
});
setResponse({
method: "DELETE",
url: 'zotero/BBBBBBBB.zip',
status: 204
});
setResponse({
method: "DELETE",
url: 'zotero/lastsync.txt',
@ -1137,9 +1167,19 @@ describe("Zotero.Sync.Storage.Mode.WebDAV", function () {
});
var results = yield controller.purgeOrphanedStorageFiles();
assertRequestCount(5);
assertRequestCount(7);
assert.sameMembers(results.deleted, ['lastsync.txt', 'lastsync', 'AAAAAAAA.prop', 'AAAAAAAA.zip']);
assert.sameMembers(
results.deleted,
[
'lastsync.txt',
'lastsync',
'AAAAAAAA.prop',
'AAAAAAAA.zip',
'BBBBBBBB.prop',
'BBBBBBBB.zip'
]
);
assert.lengthOf(results.missing, 0);
assert.lengthOf(results.error, 0);
})