Skip to content

Commit

Permalink
Test file watcher locked & unlocked files detection. Test newly-uploa…
Browse files Browse the repository at this point in the history
…ded office files locked & unlocked files detection.

Signed-off-by: alex-z <[email protected]>
  • Loading branch information
allexzander committed Apr 6, 2024
1 parent 202f597 commit a133669
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/gui/folderwatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ void FolderWatcher::slotLockFileDetectedExternally(const QString &lockFile)
changeDetected(lockFile);
}

void FolderWatcher::setShouldWatchForFileUnlocking(bool shouldWatchForFileUnlocking)
{
_shouldWatchForFileUnlocking = shouldWatchForFileUnlocking;
}

int FolderWatcher::lockChangeDebouncingTimout() const

Check warning on line 172 in src/gui/folderwatcher.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/folderwatcher.cpp:172:20 [modernize-use-trailing-return-type]

use a trailing return type for this function
{
return _lockChangeDebouncingTimer.interval();
}

void FolderWatcher::changeDetected(const QString &path)

Check warning on line 177 in src/gui/folderwatcher.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/folderwatcher.cpp:177:21 [readability-convert-member-functions-to-static]

method 'changeDetected' can be made static
{
QFileInfo fileInfo(path);
Expand Down
3 changes: 3 additions & 0 deletions src/gui/folderwatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ class FolderWatcher : public QObject

void slotLockFileDetectedExternally(const QString &lockFile);

void setShouldWatchForFileUnlocking(bool shouldWatchForFileUnlocking);
int lockChangeDebouncingTimout() const;

signals:
/** Emitted when one of the watched directories or one
* of the contained files is changed. */
Expand Down
115 changes: 115 additions & 0 deletions test/testfolderwatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,121 @@ private slots:
mkdir(dir);
QVERIFY(waitForPathChanged(dir));
}

void testDetectLockFiles()
{
QStringList listOfOfficeFiles = {QString(_rootPath + "/document.docx"), QString(_rootPath + "/document.odt")};
std::sort(std::begin(listOfOfficeFiles), std::end(listOfOfficeFiles));

const QStringList listOfOfficeLockFiles = {QString(_rootPath + "/.~lock.document.docx#"), QString(_rootPath + "/.~lock.document.odt#")};

_watcher->setShouldWatchForFileUnlocking(true);

// verify that office files for locking got detected by the watcher
QScopedPointer<QSignalSpy> locksImposedSpy(new QSignalSpy(_watcher.data(), &FolderWatcher::filesLockImposed));

for (const auto &officeFile : listOfOfficeFiles) {
touch(officeFile);
QVERIFY(waitForPathChanged(officeFile));
}
for (const auto &officeLockFile : listOfOfficeLockFiles) {
touch(officeLockFile);
QVERIFY(waitForPathChanged(officeLockFile));
}

locksImposedSpy->wait(_watcher->lockChangeDebouncingTimout() + 100);
QCOMPARE(locksImposedSpy->count(), 1);
auto lockedOfficeFilesByWatcher = locksImposedSpy->takeFirst().at(0).value<QSet<QString>>().toList();
std::sort(std::begin(lockedOfficeFilesByWatcher), std::end(lockedOfficeFilesByWatcher));
QCOMPARE(listOfOfficeFiles.size(), lockedOfficeFilesByWatcher.size());

for (int i = 0; i < listOfOfficeFiles.size(); ++i) {
QVERIFY(listOfOfficeFiles.at(i) == lockedOfficeFilesByWatcher.at(i));
}

// verify that office files for unlocking got detected by the watcher
QScopedPointer<QSignalSpy> locksReleasedSpy(new QSignalSpy(_watcher.data(), &FolderWatcher::filesLockReleased));

for (const auto &officeLockFile : listOfOfficeLockFiles) {
rm(officeLockFile);
QVERIFY(waitForPathChanged(officeLockFile));
}

locksReleasedSpy->wait(_watcher->lockChangeDebouncingTimout() + 100);
QCOMPARE(locksReleasedSpy->count(), 1);
auto unLockedOfficeFilesByWatcher = locksReleasedSpy->takeFirst().at(0).value<QSet<QString>>().toList();
std::sort(std::begin(unLockedOfficeFilesByWatcher), std::end(unLockedOfficeFilesByWatcher));
QCOMPARE(listOfOfficeFiles.size(), unLockedOfficeFilesByWatcher.size());

for (int i = 0; i < listOfOfficeFiles.size(); ++i) {
QVERIFY(listOfOfficeFiles.at(i) == unLockedOfficeFilesByWatcher.at(i));
}

// cleanup
for (const auto &officeLockFile : listOfOfficeLockFiles) {
rm(officeLockFile);
}
for (const auto &officeFile : listOfOfficeFiles) {
rm(officeFile);
}
}
void testDetectLockFilesExternally()
{
QStringList listOfOfficeFiles = {QString(_rootPath + "/document.docx"), QString(_rootPath + "/document.odt")};
std::sort(std::begin(listOfOfficeFiles), std::end(listOfOfficeFiles));

const QStringList listOfOfficeLockFiles = {QString(_rootPath + "/.~lock.document.docx#"), QString(_rootPath + "/.~lock.document.odt#")};

for (const auto &officeFile : listOfOfficeFiles) {
touch(officeFile);
}
for (const auto &officeLockFile : listOfOfficeLockFiles) {
touch(officeLockFile);
}

_watcher.reset(new FolderWatcher);
_watcher->init(_rootPath);
_watcher->setShouldWatchForFileUnlocking(true);
_pathChangedSpy.reset(new QSignalSpy(_watcher.data(), &FolderWatcher::pathChanged));
QScopedPointer<QSignalSpy> locksImposedSpy(new QSignalSpy(_watcher.data(), &FolderWatcher::filesLockImposed));
QScopedPointer<QSignalSpy> locksReleasedSpy(new QSignalSpy(_watcher.data(), &FolderWatcher::filesLockReleased));

for (const auto &officeLockFile : listOfOfficeLockFiles) {
_watcher->slotLockFileDetectedExternally(officeLockFile);
}

// locked files detected
locksImposedSpy->wait(_watcher->lockChangeDebouncingTimout() + 100);
QCOMPARE(locksImposedSpy->count(), 1);
auto lockedOfficeFilesByWatcher = locksImposedSpy->takeFirst().at(0).value<QSet<QString>>().toList();
std::sort(std::begin(lockedOfficeFilesByWatcher), std::end(lockedOfficeFilesByWatcher));
QCOMPARE(listOfOfficeFiles.size(), lockedOfficeFilesByWatcher.size());
for (int i = 0; i < listOfOfficeFiles.size(); ++i) {
QVERIFY(listOfOfficeFiles.at(i) == lockedOfficeFilesByWatcher.at(i));
}

// unlocked files detected
for (const auto &officeLockFile : listOfOfficeLockFiles) {
rm(officeLockFile);
}
locksReleasedSpy->wait(_watcher->lockChangeDebouncingTimout() + 100);
QCOMPARE(locksReleasedSpy->count(), 1);
auto unLockedOfficeFilesByWatcher = locksReleasedSpy->takeFirst().at(0).value<QSet<QString>>().toList();
std::sort(std::begin(unLockedOfficeFilesByWatcher), std::end(unLockedOfficeFilesByWatcher));
QCOMPARE(listOfOfficeFiles.size(), unLockedOfficeFilesByWatcher.size());

for (int i = 0; i < listOfOfficeFiles.size(); ++i) {
QVERIFY(listOfOfficeFiles.at(i) == unLockedOfficeFilesByWatcher.at(i));
}

// cleanup
for (const auto &officeFile : listOfOfficeFiles) {
rm(officeFile);
}
for (const auto &officeLockFile : listOfOfficeLockFiles) {
rm(officeLockFile);
}
}
};

#ifdef Q_OS_MAC
Expand Down
21 changes: 21 additions & 0 deletions test/testlockfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,27 @@ private slots:
const auto localFileLocked = QFileInfo{fakeFolder.localPath() + u"A/a1"};
QVERIFY(!localFileLocked.isWritable());
}

void testLockFile_lockFile_detect_newly_uploaded()
{
const auto testFileName = QStringLiteral("document.docx");
const auto testLockFileName = QStringLiteral(".~lock.document.docx#");

const auto testDocumentsDirName = "documents";

FakeFolder fakeFolder{FileInfo{}};
fakeFolder.localModifier().mkdir(testDocumentsDirName);

fakeFolder.syncEngine().account()->setCapabilities({{"files", QVariantMap{{"locking", QByteArray{"1.0"}}}}});
QSignalSpy lockFileDetectedNewlyUploadedSpy(&fakeFolder.syncEngine(), &OCC::SyncEngine::lockFileDetected);

fakeFolder.localModifier().insert(testDocumentsDirName + QString("/") + testLockFileName);
fakeFolder.localModifier().insert(testDocumentsDirName + QString("/") + testFileName);

QVERIFY(fakeFolder.syncOnce());

QCOMPARE(lockFileDetectedNewlyUploadedSpy.count(), 1);
}
};

QTEST_GUILESS_MAIN(TestLockFile)
Expand Down

0 comments on commit a133669

Please sign in to comment.