From 48d90ea6433fc7f604a0fcf93e9e912aa16d92f7 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Tue, 25 Jun 2024 10:28:20 +0200 Subject: [PATCH 1/2] automated test: block rename of the top folder of a mount point encode current behavior in a new automated test Signed-off-by: Matthieu Gallien --- test/testsyncmove.cpp | 59 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/test/testsyncmove.cpp b/test/testsyncmove.cpp index f4926722f681f..25cd674dd9988 100644 --- a/test/testsyncmove.cpp +++ b/test/testsyncmove.cpp @@ -18,19 +18,26 @@ struct OperationCounter { int nPUT = 0; int nMOVE = 0; int nDELETE = 0; + int nPROPFIND = 0; + int nMKCOL = 0; void reset() { *this = {}; } auto functor() { return [&](QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice *) { - if (op == QNetworkAccessManager::GetOperation) + if (op == QNetworkAccessManager::GetOperation) { ++nGET; - if (op == QNetworkAccessManager::PutOperation) + } else if (op == QNetworkAccessManager::PutOperation) { ++nPUT; - if (op == QNetworkAccessManager::DeleteOperation) + } else if (op == QNetworkAccessManager::DeleteOperation) { ++nDELETE; - if (req.attribute(QNetworkRequest::CustomVerbAttribute) == "MOVE") + } else if (req.attribute(QNetworkRequest::CustomVerbAttribute).toString() == "MOVE") { ++nMOVE; + } else if (req.attribute(QNetworkRequest::CustomVerbAttribute).toString() == "PROPFIND") { + ++nPROPFIND; + } else if (req.attribute(QNetworkRequest::CustomVerbAttribute).toString() == "MKCOL") { + ++nMKCOL; + } return nullptr; }; } @@ -79,6 +86,13 @@ bool expectAndWipeConflict(FileModifier &local, FileInfo state, const QString pa return false; } +static void setAllPerm(FileInfo *fi, OCC::RemotePermissions perm) +{ + fi->permissions = perm; + for (auto &subFi : fi->children) + setAllPerm(&subFi, perm); +} + class TestSyncMove : public QObject { Q_OBJECT @@ -1123,6 +1137,43 @@ private slots: QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); } + + void testBlockRenameTopFolderFromGroupFolder() + { + FakeFolder fakeFolder{{}}; + fakeFolder.syncEngine().account()->setServerVersion("29.0.2.0"); + + fakeFolder.remoteModifier().mkdir("FolA"); + auto groupFolderRoot = fakeFolder.remoteModifier().find("FolA"); + groupFolderRoot->extraDavProperties = "true"; + setAllPerm(groupFolderRoot, RemotePermissions::fromServerString("WDNVCKRM")); + fakeFolder.remoteModifier().mkdir("FolA/FolB"); + fakeFolder.remoteModifier().mkdir("FolA/FolB/FolC"); + fakeFolder.remoteModifier().mkdir("FolA/FolB/FolC/FolD"); + fakeFolder.remoteModifier().mkdir("FolA/FolB/FolC/FolD/FolE"); + fakeFolder.remoteModifier().insert("FolA/FileA.txt"); + fakeFolder.remoteModifier().insert("FolA/FolB/FileB.txt"); + fakeFolder.remoteModifier().insert("FolA/FolB/FolC/FileC.txt"); + fakeFolder.remoteModifier().insert("FolA/FolB/FolC/FolD/FileD.txt"); + fakeFolder.remoteModifier().insert("FolA/FolB/FolC/FolD/FolE/FileE.txt"); + QVERIFY(fakeFolder.syncOnce()); + + OperationCounter counter; + fakeFolder.setServerOverride(counter.functor()); + + fakeFolder.localModifier().insert("FolA/FileA2.txt"); + fakeFolder.localModifier().insert("FolA/FolB/FileB2.txt"); + fakeFolder.localModifier().insert("FolA/FolB/FolC/FileC2.txt"); + fakeFolder.localModifier().insert("FolA/FolB/FolC/FolD/FileD2.txt"); + fakeFolder.localModifier().insert("FolA/FolB/FolC/FolD/FolE/FileE2.txt"); + fakeFolder.localModifier().rename("FolA", "FolA_Renamed"); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(counter.nDELETE, 0); + QCOMPARE(counter.nGET, 0); + QCOMPARE(counter.nPUT, 10); + QCOMPARE(counter.nMOVE, 0); + QCOMPARE(counter.nMKCOL, 5); + } }; QTEST_GUILESS_MAIN(TestSyncMove) From e389b91ce692a354b11b4078aa397414f7abd7ed Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Tue, 25 Jun 2024 10:33:22 +0200 Subject: [PATCH 2/2] automated test: allow rename of the child items of a mount point Signed-off-by: Matthieu Gallien --- test/testsyncmove.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/testsyncmove.cpp b/test/testsyncmove.cpp index 25cd674dd9988..47d3e955af780 100644 --- a/test/testsyncmove.cpp +++ b/test/testsyncmove.cpp @@ -1174,6 +1174,44 @@ private slots: QCOMPARE(counter.nMOVE, 0); QCOMPARE(counter.nMKCOL, 5); } + + void testAllowRenameChildFolderFromGroupFolder() + { + FakeFolder fakeFolder{{}}; + fakeFolder.syncEngine().account()->setServerVersion("29.0.2.0"); + + fakeFolder.remoteModifier().mkdir("FolA"); + auto groupFolderRoot = fakeFolder.remoteModifier().find("FolA"); + groupFolderRoot->extraDavProperties = "true"; + setAllPerm(groupFolderRoot, RemotePermissions::fromServerString("WDNVCKRM")); + fakeFolder.remoteModifier().mkdir("FolA/FolB"); + fakeFolder.remoteModifier().mkdir("FolA/FolB/FolC"); + fakeFolder.remoteModifier().mkdir("FolA/FolB/FolC/FolD"); + fakeFolder.remoteModifier().mkdir("FolA/FolB/FolC/FolD/FolE"); + fakeFolder.remoteModifier().insert("FolA/FileA.txt"); + fakeFolder.remoteModifier().insert("FolA/FolB/FileB.txt"); + fakeFolder.remoteModifier().insert("FolA/FolB/FolC/FileC.txt"); + fakeFolder.remoteModifier().insert("FolA/FolB/FolC/FolD/FileD.txt"); + fakeFolder.remoteModifier().insert("FolA/FolB/FolC/FolD/FolE/FileE.txt"); + QVERIFY(fakeFolder.syncOnce()); + + OperationCounter counter; + fakeFolder.setServerOverride(counter.functor()); + + fakeFolder.localModifier().insert("FolA/FileA2.txt"); + fakeFolder.localModifier().insert("FolA/FolB/FileB2.txt"); + fakeFolder.localModifier().insert("FolA/FolB/FolC/FileC2.txt"); + fakeFolder.localModifier().insert("FolA/FolB/FolC/FolD/FileD2.txt"); + fakeFolder.localModifier().insert("FolA/FolB/FolC/FolD/FolE/FileE2.txt"); + fakeFolder.localModifier().rename("FolA/FolB", "FolA/FolB_Renamed"); + fakeFolder.localModifier().rename("FolA/FileA.txt", "FolA/FileA_Renamed.txt"); + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(counter.nDELETE, 0); + QCOMPARE(counter.nGET, 0); + QCOMPARE(counter.nPUT, 5); + QCOMPARE(counter.nMOVE, 2); + QCOMPARE(counter.nMKCOL, 0); + } }; QTEST_GUILESS_MAIN(TestSyncMove)