mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-25 22:46:04 +03:00
Move: add more test and fix move within moves
This commit is contained in:
parent
ade4c11de3
commit
1fb4c22adf
4 changed files with 58 additions and 14 deletions
|
@ -282,7 +282,7 @@ void ProcessDirectoryJob::processFile(PathTuple path,
|
|||
<< " | fileid: " << dbEntry._fileId << "//" << serverEntry.fileId
|
||||
<< " | inode: " << dbEntry._inode << "/" << localEntry.inode << "/";
|
||||
|
||||
if (_discoveryData->_renamedItems.contains(path._original)) {
|
||||
if (_discoveryData->isRenamed(path._original)) {
|
||||
qCDebug(lcDisco) << "Ignoring renamed";
|
||||
return; // Ignore this.
|
||||
}
|
||||
|
@ -489,7 +489,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
|
|||
// Now we know there is a sane rename candidate.
|
||||
QString originalPath = QString::fromUtf8(base._path);
|
||||
|
||||
if (_discoveryData->_renamedItems.contains(originalPath)) {
|
||||
if (_discoveryData->isRenamed(originalPath)) {
|
||||
qCInfo(lcDisco, "folder already has a rename entry, skipping");
|
||||
return;
|
||||
}
|
||||
|
@ -530,8 +530,8 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
|
|||
bool wasDeletedOnServer = _discoveryData->findAndCancelDeletedJob(originalPath).first;
|
||||
|
||||
auto postProcessRename = [this, item, base, originalPath](PathTuple &path) {
|
||||
auto adjustedOriginalPath = _discoveryData->adjustRenamedPath(originalPath);
|
||||
_discoveryData->_renamedItems.insert(originalPath, path._target);
|
||||
auto adjustedOriginalPath = _discoveryData->adjustRenamedPath(originalPath, SyncFileItem::Up);
|
||||
_discoveryData->_renamedItemsRemote.insert(originalPath, path._target);
|
||||
item->_modtime = base._modtime;
|
||||
item->_inode = base._inode;
|
||||
item->_instruction = CSYNC_INSTRUCTION_RENAME;
|
||||
|
@ -556,7 +556,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
|
|||
QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs);
|
||||
if (etag || etag.error().code != 404 ||
|
||||
// Somehow another item claimed this original path, consider as if it existed
|
||||
_discoveryData->_renamedItems.contains(originalPath)) {
|
||||
_discoveryData->isRenamed(originalPath)) {
|
||||
// If the file exist or if there is another error, consider it is a new file.
|
||||
postProcessServerNew();
|
||||
return;
|
||||
|
@ -818,7 +818,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
|||
}
|
||||
}
|
||||
auto originalPath = QString::fromUtf8(base._path);
|
||||
if (isMove && _discoveryData->_renamedItems.contains(originalPath))
|
||||
if (isMove && _discoveryData->isRenamed(originalPath))
|
||||
isMove = false;
|
||||
|
||||
//Check local permission if we are allowed to put move the file here
|
||||
|
@ -833,8 +833,8 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
|||
auto wasDeletedOnClient = _discoveryData->findAndCancelDeletedJob(originalPath);
|
||||
|
||||
auto processRename = [item, originalPath, base, this](PathTuple &path) {
|
||||
auto adjustedOriginalPath = _discoveryData->adjustRenamedPath(originalPath);
|
||||
_discoveryData->_renamedItems.insert(originalPath, path._target);
|
||||
auto adjustedOriginalPath = _discoveryData->adjustRenamedPath(originalPath, SyncFileItem::Down);
|
||||
_discoveryData->_renamedItemsLocal.insert(originalPath, path._target);
|
||||
item->_renameTarget = path._target;
|
||||
path._server = adjustedOriginalPath;
|
||||
item->_file = path._server;
|
||||
|
@ -861,7 +861,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
|||
chopVirtualFileSuffix(serverOriginalPath);
|
||||
auto job = new RequestEtagJob(_discoveryData->_account, serverOriginalPath, this);
|
||||
connect(job, &RequestEtagJob::finishedWithResult, this, [=](const HttpResult<QString> &etag) mutable {
|
||||
if (!etag || (*etag != base._etag && !item->isDirectory()) || _discoveryData->_renamedItems.contains(originalPath)) {
|
||||
if (!etag || (*etag != base._etag && !item->isDirectory()) || _discoveryData->isRenamed(originalPath)) {
|
||||
qCInfo(lcDisco) << "Can't rename because the etag has changed or the directory is gone" << originalPath;
|
||||
// Can't be a rename, leave it as a new.
|
||||
postProcessLocalNew();
|
||||
|
|
|
@ -132,11 +132,10 @@ void DiscoveryPhase::checkSelectiveSyncNewFolder(const QString &path, RemotePerm
|
|||
propfindJob->start();
|
||||
}
|
||||
|
||||
|
||||
/* Given a path on the remote, give the path as it is when the rename is done */
|
||||
QString DiscoveryPhase::adjustRenamedPath(const QString &original) const
|
||||
QString DiscoveryPhase::adjustRenamedPath(const QString &original, SyncFileItem::Direction d) const
|
||||
{
|
||||
return OCC::adjustRenamedPath(_renamedItems, original);
|
||||
return OCC::adjustRenamedPath(d == SyncFileItem::Down ? _renamedItemsRemote : _renamedItemsLocal, original);
|
||||
}
|
||||
|
||||
QString adjustRenamedPath(const QMap<QString, QString> renamedItems, const QString original)
|
||||
|
|
|
@ -132,7 +132,10 @@ class DiscoveryPhase : public QObject
|
|||
friend class ProcessDirectoryJob;
|
||||
QMap<QString, SyncFileItemPtr> _deletedItem;
|
||||
QMap<QString, ProcessDirectoryJob *> _queuedDeletedDirectories;
|
||||
QMap<QString, QString> _renamedItems; // map source -> destinations
|
||||
// map source -> destinations
|
||||
QMap<QString, QString> _renamedItemsRemote;
|
||||
QMap<QString, QString> _renamedItemsLocal;
|
||||
bool isRenamed(const QString &p) { return _renamedItemsLocal.contains(p) || _renamedItemsRemote.contains(p); }
|
||||
int _currentlyActiveJobs = 0;
|
||||
|
||||
// both must contain a sorted list
|
||||
|
@ -153,7 +156,7 @@ class DiscoveryPhase : public QObject
|
|||
* Note that it only considers parent directory renames. So if A/B got renamed to C/D,
|
||||
* checking A/B/file would yield C/D/file, but checking A/B would yield A/B.
|
||||
*/
|
||||
QString adjustRenamedPath(const QString &original) const;
|
||||
QString adjustRenamedPath(const QString &original, SyncFileItem::Direction) const;
|
||||
|
||||
/**
|
||||
* Check if there is already a job to delete that item.
|
||||
|
|
|
@ -670,6 +670,48 @@ private slots:
|
|||
QCOMPARE(fakeFolder.currentLocalState(), expectedState);
|
||||
QCOMPARE(fakeFolder.currentRemoteState(), expectedState);
|
||||
}
|
||||
|
||||
void testDeepHierarchy_data()
|
||||
{
|
||||
QTest::addColumn<bool>("local");
|
||||
QTest::newRow("remote") << false;
|
||||
QTest::newRow("local") << true;
|
||||
}
|
||||
|
||||
void testDeepHierarchy()
|
||||
{
|
||||
QFETCH(bool, local);
|
||||
FakeFolder fakeFolder { FileInfo::A12_B12_C12_S12() };
|
||||
auto &modifier = local ? fakeFolder.localModifier() : fakeFolder.remoteModifier();
|
||||
|
||||
modifier.mkdir("FolA");
|
||||
modifier.mkdir("FolA/FolB");
|
||||
modifier.mkdir("FolA/FolB/FolC");
|
||||
modifier.mkdir("FolA/FolB/FolC/FolD");
|
||||
modifier.mkdir("FolA/FolB/FolC/FolD/FolE");
|
||||
modifier.insert("FolA/FileA.txt");
|
||||
modifier.insert("FolA/FolB/FileB.txt");
|
||||
modifier.insert("FolA/FolB/FolC/FileC.txt");
|
||||
modifier.insert("FolA/FolB/FolC/FolD/FileD.txt");
|
||||
modifier.insert("FolA/FolB/FolC/FolD/FolE/FileE.txt");
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
|
||||
modifier.insert("FolA/FileA2.txt");
|
||||
modifier.insert("FolA/FolB/FileB2.txt");
|
||||
modifier.insert("FolA/FolB/FolC/FileC2.txt");
|
||||
modifier.insert("FolA/FolB/FolC/FolD/FileD2.txt");
|
||||
modifier.insert("FolA/FolB/FolC/FolD/FolE/FileE2.txt");
|
||||
modifier.rename("FolA", "FolA_Renamed");
|
||||
modifier.rename("FolA_Renamed/FolB", "FolB_Renamed");
|
||||
modifier.rename("FolB_Renamed/FolC", "FolA");
|
||||
modifier.rename("FolA/FolD", "FolA/FolD_Renamed");
|
||||
modifier.mkdir("FolB_Renamed/New");
|
||||
modifier.rename("FolA/FolD_Renamed/FolE", "FolB_Renamed/New/FolE");
|
||||
auto expected = local ? fakeFolder.currentLocalState() : fakeFolder.currentRemoteState();
|
||||
QVERIFY(fakeFolder.syncOnce());
|
||||
QCOMPARE(fakeFolder.currentLocalState(), expected);
|
||||
QCOMPARE(fakeFolder.currentRemoteState(), expected);
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_GUILESS_MAIN(TestSyncMove)
|
||||
|
|
Loading…
Reference in a new issue