| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637 |
- #include "lockfilejobs.h"
- #include "account.h"
- #include "accountstate.h"
- #include "common/syncjournaldb.h"
- #include "common/syncjournalfilerecord.h"
- #include "syncenginetestutils.h"
- #include "localdiscoverytracker.h"
- #include <QTest>
- #include <QSignalSpy>
- class TestLockFile : public QObject
- {
- Q_OBJECT
- public:
- TestLockFile() = default;
- private slots:
- void initTestCase()
- {
- }
- void testLockFile_lockFile_lockSuccess()
- {
- const auto testFileName = QStringLiteral("file.txt");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- QSignalSpy lockFileSuccessSpy(fakeFolder.account().data(), &OCC::Account::lockFileSuccess);
- QSignalSpy lockFileErrorSpy(fakeFolder.account().data(), &OCC::Account::lockFileError);
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- fakeFolder.account()->setLockFileState(QStringLiteral("/") + testFileName, &fakeFolder.syncJournal(), OCC::SyncFileItem::LockStatus::LockedItem);
- QVERIFY(lockFileSuccessSpy.wait());
- QCOMPARE(lockFileErrorSpy.count(), 0);
- }
- void testLockFile_lockFile_lockError()
- {
- const auto testFileName = QStringLiteral("file.txt");
- static constexpr auto LockedHttpErrorCode = 423;
- const auto replyData = QByteArray("<?xml version=\"1.0\"?>\n"
- "<d:prop xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">\n"
- " <nc:lock/>\n"
- " <nc:lock-owner-type>0</nc:lock-owner-type>\n"
- " <nc:lock-owner>john</nc:lock-owner>\n"
- " <nc:lock-owner-displayname>John Doe</nc:lock-owner-displayname>\n"
- " <nc:lock-owner-editor>john</nc:lock-owner-editor>\n"
- " <nc:lock-time>1650619678</nc:lock-time>\n"
- " <nc:lock-timeout>300</nc:lock-timeout>\n"
- " <nc:lock-token>files_lock/310997d7-0aae-4e48-97e1-eeb6be6e2202</nc:lock-token>\n"
- "</d:prop>\n");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- fakeFolder.setServerOverride([replyData] (FakeQNAM::Operation op, const QNetworkRequest &request, QIODevice *) {
- QNetworkReply *reply = nullptr;
- if (op == QNetworkAccessManager::CustomOperation && request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("LOCK")) {
- reply = new FakeErrorReply(op, request, nullptr, LockedHttpErrorCode, replyData);
- }
- return reply;
- });
- QSignalSpy lockFileSuccessSpy(fakeFolder.account().data(), &OCC::Account::lockFileSuccess);
- QSignalSpy lockFileErrorSpy(fakeFolder.account().data(), &OCC::Account::lockFileError);
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- fakeFolder.account()->setLockFileState(QStringLiteral("/") + testFileName, &fakeFolder.syncJournal(), OCC::SyncFileItem::LockStatus::LockedItem);
- QVERIFY(lockFileErrorSpy.wait());
- QCOMPARE(lockFileSuccessSpy.count(), 0);
- }
- void testLockFile_fileLockStatus_queryLockStatus()
- {
- const auto testFileName = QStringLiteral("file.txt");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- QSignalSpy lockFileSuccessSpy(fakeFolder.account().data(), &OCC::Account::lockFileSuccess);
- QSignalSpy lockFileErrorSpy(fakeFolder.account().data(), &OCC::Account::lockFileError);
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- fakeFolder.account()->setLockFileState(QStringLiteral("/") + testFileName, &fakeFolder.syncJournal(), OCC::SyncFileItem::LockStatus::LockedItem);
- QVERIFY(lockFileSuccessSpy.wait());
- QCOMPARE(lockFileErrorSpy.count(), 0);
- auto lockStatus = fakeFolder.account()->fileLockStatus(&fakeFolder.syncJournal(), testFileName);
- QCOMPARE(lockStatus, OCC::SyncFileItem::LockStatus::LockedItem);
- }
- void testLockFile_fileCanBeUnlocked_canUnlock()
- {
- const auto testFileName = QStringLiteral("file.txt");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- QSignalSpy lockFileSuccessSpy(fakeFolder.account().data(), &OCC::Account::lockFileSuccess);
- QSignalSpy lockFileErrorSpy(fakeFolder.account().data(), &OCC::Account::lockFileError);
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- fakeFolder.account()->setLockFileState(QStringLiteral("/") + testFileName, &fakeFolder.syncJournal(), OCC::SyncFileItem::LockStatus::LockedItem);
- QVERIFY(lockFileSuccessSpy.wait());
- QCOMPARE(lockFileErrorSpy.count(), 0);
- auto lockStatus = fakeFolder.account()->fileCanBeUnlocked(&fakeFolder.syncJournal(), testFileName);
- QCOMPARE(lockStatus, true);
- }
- void testLockFile_lockFile_jobSuccess()
- {
- const auto testFileName = QStringLiteral("file.txt");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- auto job = new OCC::LockFileJob(fakeFolder.account(), &fakeFolder.syncJournal(), QStringLiteral("/") + testFileName, OCC::SyncFileItem::LockStatus::LockedItem);
- QSignalSpy jobSuccess(job, &OCC::LockFileJob::finishedWithoutError);
- QSignalSpy jobFailure(job, &OCC::LockFileJob::finishedWithError);
- job->start();
- QVERIFY(jobSuccess.wait());
- QCOMPARE(jobFailure.count(), 0);
- auto fileRecord = OCC::SyncJournalFileRecord{};
- QVERIFY(fakeFolder.syncJournal().getFileRecord(testFileName, &fileRecord));
- QCOMPARE(fileRecord._lockstate._locked, true);
- QCOMPARE(fileRecord._lockstate._lockEditorApp, QString{});
- QCOMPARE(fileRecord._lockstate._lockOwnerDisplayName, QStringLiteral("John Doe"));
- QCOMPARE(fileRecord._lockstate._lockOwnerId, QStringLiteral("admin"));
- QCOMPARE(fileRecord._lockstate._lockOwnerType, static_cast<qint64>(OCC::SyncFileItem::LockOwnerType::UserLock));
- QCOMPARE(fileRecord._lockstate._lockTime, 1234560);
- QCOMPARE(fileRecord._lockstate._lockTimeout, 1800);
- QVERIFY(fakeFolder.syncOnce());
- }
- void testLockFile_lockFile_unlockFile_jobSuccess()
- {
- const auto testFileName = QStringLiteral("file.txt");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- auto lockFileJob = new OCC::LockFileJob(fakeFolder.account(), &fakeFolder.syncJournal(), QStringLiteral("/") + testFileName, OCC::SyncFileItem::LockStatus::LockedItem);
- QSignalSpy lockFileJobSuccess(lockFileJob, &OCC::LockFileJob::finishedWithoutError);
- QSignalSpy lockFileJobFailure(lockFileJob, &OCC::LockFileJob::finishedWithError);
- lockFileJob->start();
- QVERIFY(lockFileJobSuccess.wait());
- QCOMPARE(lockFileJobFailure.count(), 0);
- QVERIFY(fakeFolder.syncOnce());
- auto unlockFileJob = new OCC::LockFileJob(fakeFolder.account(), &fakeFolder.syncJournal(), QStringLiteral("/") + testFileName, OCC::SyncFileItem::LockStatus::UnlockedItem);
- QSignalSpy unlockFileJobSuccess(unlockFileJob, &OCC::LockFileJob::finishedWithoutError);
- QSignalSpy unlockFileJobFailure(unlockFileJob, &OCC::LockFileJob::finishedWithError);
- unlockFileJob->start();
- QVERIFY(unlockFileJobSuccess.wait());
- QCOMPARE(unlockFileJobFailure.count(), 0);
- auto fileRecord = OCC::SyncJournalFileRecord{};
- QVERIFY(fakeFolder.syncJournal().getFileRecord(testFileName, &fileRecord));
- QCOMPARE(fileRecord._lockstate._locked, false);
- QVERIFY(fakeFolder.syncOnce());
- }
- void testLockFile_lockFile_alreadyLockedByUser()
- {
- static constexpr auto LockedHttpErrorCode = 423;
- static constexpr auto PreconditionFailedHttpErrorCode = 412;
- const auto testFileName = QStringLiteral("file.txt");
- const auto replyData = QByteArray("<?xml version=\"1.0\"?>\n"
- "<d:prop xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">\n"
- " <nc:lock>1</nc:lock>\n"
- " <nc:lock-owner-type>0</nc:lock-owner-type>\n"
- " <nc:lock-owner>john</nc:lock-owner>\n"
- " <nc:lock-owner-displayname>John Doe</nc:lock-owner-displayname>\n"
- " <nc:lock-owner-editor>john</nc:lock-owner-editor>\n"
- " <nc:lock-time>1650619678</nc:lock-time>\n"
- " <nc:lock-timeout>300</nc:lock-timeout>\n"
- " <nc:lock-token>files_lock/310997d7-0aae-4e48-97e1-eeb6be6e2202</nc:lock-token>\n"
- "</d:prop>\n");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- fakeFolder.setServerOverride([replyData] (FakeQNAM::Operation op, const QNetworkRequest &request, QIODevice *) {
- QNetworkReply *reply = nullptr;
- if (op == QNetworkAccessManager::CustomOperation && request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("LOCK")) {
- reply = new FakeErrorReply(op, request, nullptr, LockedHttpErrorCode, replyData);
- } else if (op == QNetworkAccessManager::CustomOperation && request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("UNLOCK")) {
- reply = new FakeErrorReply(op, request, nullptr, PreconditionFailedHttpErrorCode, replyData);
- }
- return reply;
- });
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- auto job = new OCC::LockFileJob(fakeFolder.account(), &fakeFolder.syncJournal(), QStringLiteral("/") + testFileName, OCC::SyncFileItem::LockStatus::LockedItem);
- QSignalSpy jobSuccess(job, &OCC::LockFileJob::finishedWithoutError);
- QSignalSpy jobFailure(job, &OCC::LockFileJob::finishedWithError);
- job->start();
- QVERIFY(jobFailure.wait());
- QCOMPARE(jobSuccess.count(), 0);
- }
- void testLockFile_lockFile_alreadyLockedByApp()
- {
- static constexpr auto LockedHttpErrorCode = 423;
- static constexpr auto PreconditionFailedHttpErrorCode = 412;
- const auto testFileName = QStringLiteral("file.txt");
- const auto replyData = QByteArray("<?xml version=\"1.0\"?>\n"
- "<d:prop xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">\n"
- " <nc:lock>1</nc:lock>\n"
- " <nc:lock-owner-type>1</nc:lock-owner-type>\n"
- " <nc:lock-owner>john</nc:lock-owner>\n"
- " <nc:lock-owner-displayname>John Doe</nc:lock-owner-displayname>\n"
- " <nc:lock-owner-editor>Text</nc:lock-owner-editor>\n"
- " <nc:lock-time>1650619678</nc:lock-time>\n"
- " <nc:lock-timeout>300</nc:lock-timeout>\n"
- " <nc:lock-token>files_lock/310997d7-0aae-4e48-97e1-eeb6be6e2202</nc:lock-token>\n"
- "</d:prop>\n");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- fakeFolder.setServerOverride([replyData] (FakeQNAM::Operation op, const QNetworkRequest &request, QIODevice *) {
- QNetworkReply *reply = nullptr;
- if (op == QNetworkAccessManager::CustomOperation && request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("LOCK")) {
- reply = new FakeErrorReply(op, request, nullptr, LockedHttpErrorCode, replyData);
- } else if (op == QNetworkAccessManager::CustomOperation && request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("UNLOCK")) {
- reply = new FakeErrorReply(op, request, nullptr, PreconditionFailedHttpErrorCode, replyData);
- }
- return reply;
- });
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- auto job = new OCC::LockFileJob(fakeFolder.account(), &fakeFolder.syncJournal(), QStringLiteral("/") + testFileName, OCC::SyncFileItem::LockStatus::LockedItem);
- QSignalSpy jobSuccess(job, &OCC::LockFileJob::finishedWithoutError);
- QSignalSpy jobFailure(job, &OCC::LockFileJob::finishedWithError);
- job->start();
- QVERIFY(jobFailure.wait());
- QCOMPARE(jobSuccess.count(), 0);
- }
- void testLockFile_unlockFile_alreadyUnlocked()
- {
- static constexpr auto LockedHttpErrorCode = 423;
- static constexpr auto PreconditionFailedHttpErrorCode = 412;
- const auto testFileName = QStringLiteral("file.txt");
- const auto replyData = QByteArray("<?xml version=\"1.0\"?>\n"
- "<d:prop xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">\n"
- " <nc:lock/>\n"
- " <nc:lock-owner-type>0</nc:lock-owner-type>\n"
- " <nc:lock-owner>john</nc:lock-owner>\n"
- " <nc:lock-owner-displayname>John Doe</nc:lock-owner-displayname>\n"
- " <nc:lock-owner-editor>john</nc:lock-owner-editor>\n"
- " <nc:lock-time>1650619678</nc:lock-time>\n"
- " <nc:lock-timeout>300</nc:lock-timeout>\n"
- " <nc:lock-token>files_lock/310997d7-0aae-4e48-97e1-eeb6be6e2202</nc:lock-token>\n"
- "</d:prop>\n");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- fakeFolder.setServerOverride([replyData] (FakeQNAM::Operation op, const QNetworkRequest &request, QIODevice *) {
- QNetworkReply *reply = nullptr;
- if (op == QNetworkAccessManager::CustomOperation && request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("LOCK")) {
- reply = new FakeErrorReply(op, request, nullptr, LockedHttpErrorCode, replyData);
- } else if (op == QNetworkAccessManager::CustomOperation && request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("UNLOCK")) {
- reply = new FakeErrorReply(op, request, nullptr, PreconditionFailedHttpErrorCode, replyData);
- }
- return reply;
- });
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- auto job = new OCC::LockFileJob(fakeFolder.account(), &fakeFolder.syncJournal(), QStringLiteral("/") + testFileName, OCC::SyncFileItem::LockStatus::UnlockedItem);
- QSignalSpy jobSuccess(job, &OCC::LockFileJob::finishedWithoutError);
- QSignalSpy jobFailure(job, &OCC::LockFileJob::finishedWithError);
- job->start();
- QVERIFY(jobSuccess.wait());
- QCOMPARE(jobFailure.count(), 0);
- }
- void testLockFile_unlockFile_lockedBySomeoneElse()
- {
- static constexpr auto LockedHttpErrorCode = 423;
- const auto testFileName = QStringLiteral("file.txt");
- const auto replyData = QByteArray("<?xml version=\"1.0\"?>\n"
- "<d:prop xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">\n"
- " <nc:lock>1</nc:lock>\n"
- " <nc:lock-owner-type>0</nc:lock-owner-type>\n"
- " <nc:lock-owner>alice</nc:lock-owner>\n"
- " <nc:lock-owner-displayname>Alice Doe</nc:lock-owner-displayname>\n"
- " <nc:lock-owner-editor>Text</nc:lock-owner-editor>\n"
- " <nc:lock-time>1650619678</nc:lock-time>\n"
- " <nc:lock-timeout>300</nc:lock-timeout>\n"
- " <nc:lock-token>files_lock/310997d7-0aae-4e48-97e1-eeb6be6e2202</nc:lock-token>\n"
- "</d:prop>\n");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- fakeFolder.setServerOverride([replyData] (FakeQNAM::Operation op, const QNetworkRequest &request, QIODevice *) {
- QNetworkReply *reply = nullptr;
- if (op == QNetworkAccessManager::CustomOperation && (request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("LOCK") ||
- request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("UNLOCK"))) {
- reply = new FakeErrorReply(op, request, nullptr, LockedHttpErrorCode, replyData);
- }
- return reply;
- });
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- auto job = new OCC::LockFileJob(fakeFolder.account(), &fakeFolder.syncJournal(), QStringLiteral("/") + testFileName, OCC::SyncFileItem::LockStatus::UnlockedItem);
- QSignalSpy jobSuccess(job, &OCC::LockFileJob::finishedWithoutError);
- QSignalSpy jobFailure(job, &OCC::LockFileJob::finishedWithError);
- job->start();
- QVERIFY(jobFailure.wait());
- QCOMPARE(jobSuccess.count(), 0);
- }
- void testLockFile_lockFile_jobError()
- {
- const auto testFileName = QStringLiteral("file.txt");
- static constexpr auto InternalServerErrorHttpErrorCode = 500;
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- fakeFolder.setServerOverride([] (FakeQNAM::Operation op, const QNetworkRequest &request, QIODevice *) {
- QNetworkReply *reply = nullptr;
- if (op == QNetworkAccessManager::CustomOperation && (request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("LOCK") ||
- request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("UNLOCK"))) {
- reply = new FakeErrorReply(op, request, nullptr, InternalServerErrorHttpErrorCode, {});
- }
- return reply;
- });
- fakeFolder.localModifier().insert(QStringLiteral("file.txt"));
- QVERIFY(fakeFolder.syncOnce());
- auto lockFileJob = new OCC::LockFileJob(fakeFolder.account(), &fakeFolder.syncJournal(), QStringLiteral("/") + testFileName, OCC::SyncFileItem::LockStatus::LockedItem);
- QSignalSpy lockFileJobSuccess(lockFileJob, &OCC::LockFileJob::finishedWithoutError);
- QSignalSpy lockFileJobFailure(lockFileJob, &OCC::LockFileJob::finishedWithError);
- lockFileJob->start();
- QVERIFY(lockFileJobFailure.wait());
- QCOMPARE(lockFileJobSuccess.count(), 0);
- QVERIFY(fakeFolder.syncOnce());
- auto unlockFileJob = new OCC::LockFileJob(fakeFolder.account(), &fakeFolder.syncJournal(), QStringLiteral("/") + testFileName, OCC::SyncFileItem::LockStatus::UnlockedItem);
- QSignalSpy unlockFileJobSuccess(unlockFileJob, &OCC::LockFileJob::finishedWithoutError);
- QSignalSpy unlockFileJobFailure(unlockFileJob, &OCC::LockFileJob::finishedWithError);
- unlockFileJob->start();
- QVERIFY(unlockFileJobFailure.wait());
- QCOMPARE(unlockFileJobSuccess.count(), 0);
- QVERIFY(fakeFolder.syncOnce());
- }
- void testLockFile_lockFile_preconditionFailedError()
- {
- static constexpr auto PreconditionFailedHttpErrorCode = 412;
- const auto testFileName = QStringLiteral("file.txt");
- const auto replyData = QByteArray("<?xml version=\"1.0\"?>\n"
- "<d:prop xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:oc=\"http://owncloud.org/ns\" xmlns:nc=\"http://nextcloud.org/ns\">\n"
- " <nc:lock>1</nc:lock>\n"
- " <nc:lock-owner-type>0</nc:lock-owner-type>\n"
- " <nc:lock-owner>alice</nc:lock-owner>\n"
- " <nc:lock-owner-displayname>Alice Doe</nc:lock-owner-displayname>\n"
- " <nc:lock-owner-editor>Text</nc:lock-owner-editor>\n"
- " <nc:lock-time>1650619678</nc:lock-time>\n"
- " <nc:lock-timeout>300</nc:lock-timeout>\n"
- " <nc:lock-token>files_lock/310997d7-0aae-4e48-97e1-eeb6be6e2202</nc:lock-token>\n"
- "</d:prop>\n");
- FakeFolder fakeFolder{FileInfo{}};
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- fakeFolder.setServerOverride([replyData] (FakeQNAM::Operation op, const QNetworkRequest &request, QIODevice *) {
- QNetworkReply *reply = nullptr;
- if (op == QNetworkAccessManager::CustomOperation && (request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("LOCK") ||
- request.attribute(QNetworkRequest::CustomVerbAttribute).toString() == QStringLiteral("UNLOCK"))) {
- reply = new FakeErrorReply(op, request, nullptr, PreconditionFailedHttpErrorCode, replyData);
- }
- return reply;
- });
- fakeFolder.localModifier().insert(testFileName);
- QVERIFY(fakeFolder.syncOnce());
- auto job = new OCC::LockFileJob(fakeFolder.account(), &fakeFolder.syncJournal(), QStringLiteral("/") + testFileName, OCC::SyncFileItem::LockStatus::UnlockedItem);
- QSignalSpy jobSuccess(job, &OCC::LockFileJob::finishedWithoutError);
- QSignalSpy jobFailure(job, &OCC::LockFileJob::finishedWithError);
- job->start();
- QVERIFY(jobFailure.wait());
- QCOMPARE(jobSuccess.count(), 0);
- }
- void testSyncLockedFilesAlmostExpired()
- {
- FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- QSignalSpy spySyncCompleted(&fakeFolder.syncEngine(), &OCC::SyncEngine::finished);
- ItemCompletedSpy completeSpy(fakeFolder);
- completeSpy.clear();
- QVERIFY(fakeFolder.syncOnce());
- QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1"))->_locked, OCC::SyncFileItem::LockStatus::UnlockedItem);
- OCC::SyncJournalFileRecord fileRecordBefore;
- QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordBefore));
- QVERIFY(!fileRecordBefore._lockstate._locked);
- fakeFolder.remoteModifier().modifyLockState(QStringLiteral("A/a1"), FileModifier::LockState::FileLocked, 1, QStringLiteral("Nextcloud Office"), {}, QStringLiteral("richdocuments"), QDateTime::currentDateTime().toSecsSinceEpoch() - 1220, 1226);
- completeSpy.clear();
- QVERIFY(fakeFolder.syncOnce());
- QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1"))->_locked, OCC::SyncFileItem::LockStatus::LockedItem);
- OCC::SyncJournalFileRecord fileRecordLocked;
- QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordLocked));
- QVERIFY(fileRecordLocked._lockstate._locked);
- spySyncCompleted.clear();
- QTest::qWait(5000);
- fakeFolder.remoteModifier().modifyLockState(QStringLiteral("A/a1"), FileModifier::LockState::FileUnlocked, {}, {}, {}, {}, {}, {});
- QCOMPARE(spySyncCompleted.count(), 0);
- QVERIFY(spySyncCompleted.wait(3000));
- QCOMPARE(spySyncCompleted.count(), 1);
- OCC::SyncJournalFileRecord fileRecordUnlocked;
- QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordUnlocked));
- QVERIFY(!fileRecordUnlocked._lockstate._locked);
- }
- void testSyncLockedFilesNoExpiredLockedFiles()
- {
- FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- QSignalSpy spySyncCompleted(&fakeFolder.syncEngine(), &OCC::SyncEngine::finished);
- ItemCompletedSpy completeSpy(fakeFolder);
- completeSpy.clear();
- QVERIFY(fakeFolder.syncOnce());
- QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1"))->_locked, OCC::SyncFileItem::LockStatus::UnlockedItem);
- OCC::SyncJournalFileRecord fileRecordBefore;
- QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordBefore));
- QVERIFY(!fileRecordBefore._lockstate._locked);
- fakeFolder.remoteModifier().modifyLockState(QStringLiteral("A/a1"), FileModifier::LockState::FileLocked, 1, QStringLiteral("Nextcloud Office"), {}, QStringLiteral("richdocuments"), QDateTime::currentDateTime().toSecsSinceEpoch() - 1220, 1226);
- completeSpy.clear();
- QVERIFY(fakeFolder.syncOnce());
- QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1"))->_locked, OCC::SyncFileItem::LockStatus::LockedItem);
- OCC::SyncJournalFileRecord fileRecordLocked;
- QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordLocked));
- QVERIFY(fileRecordLocked._lockstate._locked);
- completeSpy.clear();
- QVERIFY(fakeFolder.syncOnce());
- spySyncCompleted.clear();
- QTest::qWait(1000);
- fakeFolder.remoteModifier().modifyLockState(QStringLiteral("A/a1"), FileModifier::LockState::FileUnlocked, {}, {}, {}, {}, {}, {});
- QCOMPARE(spySyncCompleted.count(), 0);
- QVERIFY(!spySyncCompleted.wait(3000));
- QCOMPARE(spySyncCompleted.count(), 0);
- OCC::SyncJournalFileRecord fileRecordUnlocked;
- QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordUnlocked));
- QVERIFY(fileRecordUnlocked._lockstate._locked);
- }
- void testSyncLockedFiles()
- {
- FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };
- QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
- int nGET = 0, nPUT = 0;
- QObject parent;
- fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData) -> QNetworkReply * {
- Q_UNUSED(outgoingData)
- Q_UNUSED(request)
- if (op == QNetworkAccessManager::PutOperation) {
- ++nPUT;
- } else if (op == QNetworkAccessManager::GetOperation) {
- ++nGET;
- }
- return nullptr;
- });
- ItemCompletedSpy completeSpy(fakeFolder);
- completeSpy.clear();
- QVERIFY(fakeFolder.syncOnce());
- QCOMPARE(nGET, 0);
- QCOMPARE(nPUT, 0);
- QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1"))->_locked, OCC::SyncFileItem::LockStatus::UnlockedItem);
- OCC::SyncJournalFileRecord fileRecordBefore;
- QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordBefore));
- QVERIFY(!fileRecordBefore._lockstate._locked);
- fakeFolder.remoteModifier().modifyLockState(QStringLiteral("A/a1"), FileModifier::LockState::FileLocked, 1, QStringLiteral("Nextcloud Office"), {}, QStringLiteral("richdocuments"), QDateTime::currentDateTime().toSecsSinceEpoch(), 1226);
- fakeFolder.remoteModifier().setModTimeKeepEtag(QStringLiteral("A/a1"), QDateTime::currentDateTime());
- fakeFolder.remoteModifier().appendByte(QStringLiteral("A/a1"));
- completeSpy.clear();
- QVERIFY(fakeFolder.syncOnce());
- QCOMPARE(nGET, 1);
- QCOMPARE(nPUT, 0);
- QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1"))->_locked, OCC::SyncFileItem::LockStatus::LockedItem);
- OCC::SyncJournalFileRecord fileRecordLocked;
- QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordLocked));
- QVERIFY(fileRecordLocked._lockstate._locked);
- completeSpy.clear();
- QVERIFY(fakeFolder.syncOnce());
- QCOMPARE(nGET, 1);
- QCOMPARE(nPUT, 0);
- OCC::SyncJournalFileRecord fileRecordAfter;
- QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordAfter));
- QVERIFY(fileRecordAfter._lockstate._locked);
- auto expectedState = fakeFolder.currentLocalState();
- QCOMPARE(fakeFolder.currentRemoteState(), expectedState);
- }
- };
- QTEST_GUILESS_MAIN(TestLockFile)
- #include "testlockfile.moc"
|