262 lines
14 KiB
C++
262 lines
14 KiB
C++
/*
|
|
* This software is in the public domain, furnished "as is", without technical
|
|
* support, and with no warranty, express or implied, as to its usefulness for
|
|
* any purpose.
|
|
*
|
|
*/
|
|
|
|
#include <qglobal.h>
|
|
#include <QTemporaryDir>
|
|
#include <QtTest>
|
|
|
|
#include "common/utility.h"
|
|
#include "folderman.h"
|
|
#include "account.h"
|
|
#include "accountstate.h"
|
|
#include "configfile.h"
|
|
|
|
#include "testutils/testutils.h"
|
|
|
|
#ifndef Q_OS_WIN
|
|
#include <unistd.h>
|
|
#else
|
|
#include "common/utility_win.h"
|
|
#endif
|
|
|
|
using namespace OCC;
|
|
|
|
|
|
class TestFolderMan: public QObject
|
|
{
|
|
Q_OBJECT
|
|
private Q_SLOTS:
|
|
void testCheckPathValidityForNewFolder()
|
|
{
|
|
#ifdef Q_OS_WIN
|
|
QNtfsPermissionCheckGuard ntfs_perm;
|
|
#endif
|
|
auto dir = TestUtils::createTempDir();
|
|
QVERIFY(dir.isValid());
|
|
QDir dir2(dir.path());
|
|
QVERIFY(dir2.mkpath(QStringLiteral("sub/QSfera1/folder/f")));
|
|
QVERIFY(dir2.mkpath(QStringLiteral("QSfera2")));
|
|
QVERIFY(dir2.mkpath(QStringLiteral("sub/free")));
|
|
QVERIFY(dir2.mkpath(QStringLiteral("free2/sub")));
|
|
{
|
|
QFile f(dir.path() + QStringLiteral("/sub/file.txt"));
|
|
f.open(QFile::WriteOnly);
|
|
f.write("hello");
|
|
}
|
|
QString dirPath = dir2.canonicalPath();
|
|
|
|
auto newAccountState = TestUtils::createDummyAccount();
|
|
FolderMan *folderman = TestUtils::folderMan();
|
|
QCOMPARE(folderman, FolderMan::instance());
|
|
QVERIFY(folderman->addFolder(
|
|
newAccountState.get(), TestUtils::createDummyFolderDefinition(newAccountState->account(), dirPath + QStringLiteral("/sub/QSfera1"))));
|
|
QVERIFY(folderman->addFolder(
|
|
newAccountState.get(), TestUtils::createDummyFolderDefinition(newAccountState->account(), dirPath + QStringLiteral("/QSfera2"))));
|
|
|
|
const auto type = FolderMan::NewFolderType::SpacesFolder;
|
|
const QUuid uuid = {};
|
|
|
|
// those should be allowed
|
|
// QString FolderMan::checkPathValidityForNewFolder(const QString& path, const QUrl &serverUrl, bool forNewDirectory)
|
|
|
|
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/free"), type, uuid), QString());
|
|
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/free2/"), type, uuid), QString());
|
|
// Not an existing directory -> Ok
|
|
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/bliblablu"), type, uuid), QString());
|
|
QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/free/bliblablu"), type, uuid), QString());
|
|
// QCOMPARE(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/bliblablu/some/more")), QString());
|
|
|
|
// A file -> Error
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/file.txt"), type, uuid).isNull());
|
|
|
|
// The following both fail because they refer to the same account
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/QSfera1"), type, uuid).isNull());
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/QSfera2/"), type, uuid).isNull());
|
|
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath, type, uuid).isNull());
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/QSfera1/folder"), type, uuid).isNull());
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/QSfera1/folder/f"), type, uuid).isNull());
|
|
|
|
#ifndef Q_OS_WIN // no links on windows, no permissions
|
|
// make a bunch of links
|
|
QVERIFY(QFile::link(dirPath + QStringLiteral("/sub/free"), dirPath + QStringLiteral("/link1")));
|
|
QVERIFY(QFile::link(dirPath + QStringLiteral("/sub"), dirPath + QStringLiteral("/link2")));
|
|
QVERIFY(QFile::link(dirPath + QStringLiteral("/sub/QSfera1"), dirPath + QStringLiteral("/link3")));
|
|
QVERIFY(QFile::link(dirPath + QStringLiteral("/sub/QSfera1/folder"), dirPath + QStringLiteral("/link4")));
|
|
|
|
// Ok
|
|
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link1"), type, uuid).isNull());
|
|
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link2/free"), type, uuid).isNull());
|
|
|
|
// Not Ok
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link2"), type, uuid).isNull());
|
|
|
|
// link 3 points to an existing sync folder. To make it fail, the account must be the same
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link3"), type, uuid).isNull());
|
|
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link4"), type, uuid).isNull());
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link3/folder"), type, uuid).isNull());
|
|
|
|
// test some non existing sub path (error)
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/QSfera1/some/sub/path"), type, uuid).isNull());
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/QSfera2/blublu"), type, uuid).isNull());
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/sub/QSfera1/folder/g/h"), type, uuid).isNull());
|
|
QCOMPARE_NE(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link3/folder/neu_folder"), type, uuid), QString());
|
|
|
|
// Subfolder of links
|
|
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link1/subfolder"), type, uuid).isNull());
|
|
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/link2/free/subfolder"), type, uuid).isNull());
|
|
|
|
if (getuid() != 0) {
|
|
// Should not have the rights
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(QStringLiteral("/"), type, uuid).isNull());
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(QStringLiteral("/usr/bin/somefolder"), type, uuid).isNull());
|
|
}
|
|
#endif
|
|
|
|
if (Utility::isWindows()) { // drive-letter tests
|
|
if (!QFileInfo(QStringLiteral("v:/")).exists()) {
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(QStringLiteral("v:"), type, uuid).isNull());
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(QStringLiteral("v:/"), type, uuid).isNull());
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(QStringLiteral("v:/foo"), type, uuid).isNull());
|
|
}
|
|
if (QFileInfo(QStringLiteral("c:/")).isWritable()) {
|
|
QVERIFY(folderman->checkPathValidityForNewFolder(QStringLiteral("c:"), type, uuid).isNull());
|
|
QVERIFY(folderman->checkPathValidityForNewFolder(QStringLiteral("c:/"), type, uuid).isNull());
|
|
QVERIFY(folderman->checkPathValidityForNewFolder(QStringLiteral("c:/foo"), type, uuid).isNull());
|
|
}
|
|
}
|
|
|
|
// Invalid paths
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder({}, type, uuid).isNull());
|
|
|
|
|
|
// REMOVE QSfera2 from the filesystem, but keep a folder sync'ed to it.
|
|
QDir(dirPath + QStringLiteral("/QSfera2/")).removeRecursively();
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/QSfera2/blublu"), type, uuid).isNull());
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/QSfera2/sub/subsub/sub"), type, uuid).isNull());
|
|
|
|
{ // check for rejection of a directory with `.sync_*.db`
|
|
QVERIFY(dir2.mkpath(QStringLiteral("db-check1")));
|
|
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/db-check1"), type, uuid).isNull());
|
|
QFile f(dirPath + QStringLiteral("/db-check1/.sync_something.db"));
|
|
QVERIFY(f.open(QFile::Truncate | QFile::WriteOnly));
|
|
f.close();
|
|
QVERIFY(QFileInfo::exists(dirPath + QStringLiteral("/db-check1/.sync_something.db")));
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/db-check1"), type, uuid).isNull());
|
|
}
|
|
|
|
{ // check for rejection of a directory with `._sync_*.db`
|
|
QVERIFY(dir2.mkpath(QStringLiteral("db-check2")));
|
|
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/db-check2"), type, uuid).isNull());
|
|
QFile f(dirPath + QStringLiteral("/db-check2/._sync_something.db"));
|
|
QVERIFY(f.open(QFile::Truncate | QFile::WriteOnly));
|
|
f.close();
|
|
QVERIFY(QFileInfo::exists(dirPath + QStringLiteral("/db-check2/._sync_something.db")));
|
|
QVERIFY(!folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/db-check2"), type, uuid).isNull());
|
|
}
|
|
}
|
|
|
|
void testFindGoodPathForNewSyncFolder()
|
|
{
|
|
// SETUP
|
|
|
|
auto dir = TestUtils::createTempDir();
|
|
QVERIFY(dir.isValid());
|
|
QDir dir2(dir.path());
|
|
QVERIFY(dir2.mkpath(QStringLiteral("sub/QSfera1/folder/f")));
|
|
QVERIFY(dir2.mkpath(QStringLiteral("QSfera")));
|
|
QVERIFY(dir2.mkpath(QStringLiteral("QSfera2")));
|
|
QVERIFY(dir2.mkpath(QStringLiteral("QSfera2/foo")));
|
|
QVERIFY(dir2.mkpath(QStringLiteral("sub/free")));
|
|
QVERIFY(dir2.mkpath(QStringLiteral("free2/sub")));
|
|
QString dirPath = dir2.canonicalPath();
|
|
|
|
auto newAccountState = TestUtils::createDummyAccount();
|
|
|
|
FolderMan *folderman = TestUtils::folderMan();
|
|
QVERIFY(folderman->addFolder(
|
|
newAccountState.get(), TestUtils::createDummyFolderDefinition(newAccountState->account(), dirPath + QStringLiteral("/sub/QSfera/"))));
|
|
QVERIFY(folderman->addFolder(
|
|
newAccountState.get(), TestUtils::createDummyFolderDefinition(newAccountState->account(), dirPath + QStringLiteral("/QSfera (2)/"))));
|
|
|
|
// TEST
|
|
const auto folderType = FolderMan::NewFolderType::SpacesFolder;
|
|
const auto uuid = QUuid::createUuid();
|
|
|
|
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("oc"), folderType, uuid), dirPath + QStringLiteral("/oc"));
|
|
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("QSfera"), folderType, uuid), dirPath + QStringLiteral("/QSfera (3)"));
|
|
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("QSfera2"), folderType, uuid), dirPath + QStringLiteral("/QSfera2 (2)"));
|
|
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("QSfera (2)"), folderType, uuid), dirPath + QStringLiteral("/QSfera (2) (2)"));
|
|
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("QSfera2/foo"), folderType, uuid), dirPath + QStringLiteral("/QSfera2_foo"));
|
|
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("QSfera2/bar"), folderType, uuid), dirPath + QStringLiteral("/QSfera2_bar"));
|
|
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("sub"), folderType, uuid), dirPath + QStringLiteral("/sub (2)"));
|
|
|
|
// REMOVE QSfera2 from the filesystem, but keep a folder sync'ed to it.
|
|
// We should still not suggest this folder as a new folder.
|
|
QDir(dirPath + QStringLiteral("/QSfera (2)/")).removeRecursively();
|
|
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("QSfera"), folderType, uuid), dirPath + QStringLiteral("/QSfera (3)"));
|
|
QCOMPARE(
|
|
folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("QSfera2"), folderType, uuid), QString(dirPath + QStringLiteral("/QSfera2 (2)")));
|
|
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("QSfera (2)"), folderType, uuid),
|
|
QString(dirPath + QStringLiteral("/QSfera (2) (2)")));
|
|
|
|
// make sure people can't do evil stuff
|
|
QCOMPARE(
|
|
folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral("../../../Bo/b"), folderType, uuid), QString(dirPath + QStringLiteral("/___Bo_b")));
|
|
|
|
// normalise the name
|
|
QCOMPARE(folderman->findGoodPathForNewSyncFolder(dirPath, QStringLiteral(" Bo:*<>!b "), folderType, uuid),
|
|
QString(dirPath + QStringLiteral("/Bo____!b")));
|
|
}
|
|
|
|
void testSpacesSyncRootAndFolderCreation()
|
|
{
|
|
auto dir = TestUtils::createTempDir();
|
|
QVERIFY(dir.isValid());
|
|
QDir dir2(dir.path());
|
|
|
|
// Create a sync root for another account
|
|
QVERIFY(dir2.mkpath(QStringLiteral("AnotherSpacesSyncRoot")));
|
|
const auto anotherUuid = QUuid::createUuid();
|
|
Utility::markDirectoryAsSyncRoot(dir2.filePath(QStringLiteral("AnotherSpacesSyncRoot")), anotherUuid);
|
|
|
|
FolderMan *folderman = TestUtils::folderMan();
|
|
QCOMPARE(folderman, FolderMan::instance());
|
|
|
|
QString dirPath = dir2.canonicalPath();
|
|
const auto ourUuid = QUuid::createUuid();
|
|
|
|
// Spaces Sync Root in another Spaces Sync Root should fail
|
|
QVERIFY(!folderman
|
|
->checkPathValidityForNewFolder(
|
|
dirPath + QStringLiteral("/AnotherSpacesSyncRoot/OurSpacesSyncRoot"), FolderMan::NewFolderType::SpacesSyncRoot, ourUuid)
|
|
.isNull());
|
|
// Spaces Sync Root one level up should be fine
|
|
QVERIFY(folderman->checkPathValidityForNewFolder(dirPath + QStringLiteral("/OurSpacesSyncRoot"), FolderMan::NewFolderType::SpacesSyncRoot, ourUuid)
|
|
.isNull());
|
|
|
|
// Create the sync root so we can test Spaces Folder creation below
|
|
QVERIFY(dir2.mkpath(QStringLiteral("OurSpacesSyncRoot")));
|
|
Utility::markDirectoryAsSyncRoot(dir2.filePath(QStringLiteral("OurSpacesSyncRoot")), ourUuid);
|
|
|
|
// A folder for a Space in a sync root for another account should fail
|
|
QVERIFY(!folderman
|
|
->checkPathValidityForNewFolder(
|
|
dirPath + QStringLiteral("/AnotherSpacesSyncRoot/OurSpacesFolder"), FolderMan::NewFolderType::SpacesFolder, ourUuid)
|
|
.isNull());
|
|
// But in our sync root that should just be fine
|
|
QVERIFY(
|
|
folderman
|
|
->checkPathValidityForNewFolder(dirPath + QStringLiteral("/OurSpacesSyncRoot/OurSpacesFolder"), FolderMan::NewFolderType::SpacesFolder, ourUuid)
|
|
.isNull());
|
|
}
|
|
};
|
|
|
|
QTEST_GUILESS_MAIN(TestFolderMan)
|
|
#include "testfolderman.moc"
|