From 55c594717b5c04c6fe5fac035dadf9242f52e06f Mon Sep 17 00:00:00 2001 From: Jyrki Gadinger Date: Fri, 7 Nov 2025 12:42:24 +0100 Subject: [PATCH 1/2] fix(gui): initialise e2e()->account() from Account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This resolves a crash when opening the settings window in case the ConnectionValidator already reported a Connected status, but is still busy fetching the user info. Added a test to ensure the constructor no longer crashes with this fix. I hope this works fine in CI 🤞 Signed-off-by: Jyrki Gadinger --- src/gui/connectionvalidator.cpp | 1 - src/gui/folderman.h | 2 ++ src/libsync/account.cpp | 1 + test/CMakeLists.txt | 2 ++ test/foldermantestutils.cpp | 17 ++++++++++ test/foldermantestutils.h | 25 ++++++++++++++ test/testaccountsettings.cpp | 59 +++++++++++++++++++++++++++++++++ test/testhelper.h | 10 ++++++ 8 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 test/foldermantestutils.cpp create mode 100644 test/foldermantestutils.h create mode 100644 test/testaccountsettings.cpp diff --git a/src/gui/connectionvalidator.cpp b/src/gui/connectionvalidator.cpp index c1bc70ae245c3..66fd819643337 100644 --- a/src/gui/connectionvalidator.cpp +++ b/src/gui/connectionvalidator.cpp @@ -322,7 +322,6 @@ void ConnectionValidator::slotUserFetched(UserInfo *userInfo) #ifndef TOKEN_AUTH_ONLY connect(_account->e2e(), &ClientSideEncryption::initializationFinished, this, &ConnectionValidator::reportConnected); - _account->e2e()->setAccount(_account); _account->e2e()->initialize(nullptr); #else reportResult(Connected); diff --git a/src/gui/folderman.h b/src/gui/folderman.h index bf3775ad115cb..bac72f86fc693 100644 --- a/src/gui/folderman.h +++ b/src/gui/folderman.h @@ -27,6 +27,7 @@ class ShareTestHelper; class EndToEndTestHelper; class TestSyncConflictsModel; class TestRemoteWipe; +class FolderManTestHelper; namespace OCC { @@ -415,6 +416,7 @@ private slots: friend class ::EndToEndTestHelper; friend class ::TestFolderStatusModel; friend class ::TestRemoteWipe; + friend class ::FolderManTestHelper; }; } // namespace OCC diff --git a/src/libsync/account.cpp b/src/libsync/account.cpp index 92fc41f0d9a5d..f0ef44f33a378 100644 --- a/src/libsync/account.cpp +++ b/src/libsync/account.cpp @@ -84,6 +84,7 @@ AccountPtr Account::create() { AccountPtr acc = AccountPtr(new Account); acc->setSharedThis(acc); + acc->_e2e.setAccount(acc); return acc; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8cfe502b861f8..77b39298b277e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,6 +19,7 @@ add_library(testutils sharetestutils.cpp endtoendtestutils.cpp activitylistmodeltestutils.cpp + foldermantestutils.cpp ) target_link_libraries(testutils PUBLIC Nextcloud::sync Qt::Test Qt::Core5Compat) @@ -140,6 +141,7 @@ nextcloud_add_test(LongPath) nextcloud_add_benchmark(LargeSync) nextcloud_add_test(Account) +nextcloud_add_test(AccountSettings) nextcloud_add_test(Folder) nextcloud_add_test(FolderMan) nextcloud_add_test(RemoteWipe) diff --git a/test/foldermantestutils.cpp b/test/foldermantestutils.cpp new file mode 100644 index 0000000000000..c23e17d143ebd --- /dev/null +++ b/test/foldermantestutils.cpp @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "foldermantestutils.h" + +FolderManTestHelper::FolderManTestHelper(QObject *parent) + : QObject{parent} +{ + +} + +FolderManTestHelper::~FolderManTestHelper() +{ + +} diff --git a/test/foldermantestutils.h b/test/foldermantestutils.h new file mode 100644 index 0000000000000..b32fd942bd9ea --- /dev/null +++ b/test/foldermantestutils.h @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#pragma once + +#include + +#include "gui/folderman.h" + +using namespace OCC; + +/// Helper class to enable usage of FolderMan::instance() from within the +/// tested code. +class FolderManTestHelper : public QObject +{ + Q_OBJECT + +public: + explicit FolderManTestHelper(QObject *parent = nullptr); + ~FolderManTestHelper() override; + + FolderMan fm; +}; diff --git a/test/testaccountsettings.cpp b/test/testaccountsettings.cpp new file mode 100644 index 0000000000000..b43723f63060a --- /dev/null +++ b/test/testaccountsettings.cpp @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: CC0-1.0 + * + * 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 + +#include "account.h" +#include "testhelper.h" +#include "foldermantestutils.h" +#include "logger.h" + +#include "accountsettings.h" + +using namespace OCC; + +class TestAccountSettings : public QObject +{ + Q_OBJECT + + FolderManTestHelper helper; + +private slots: + void initTestCase() + { + OCC::Logger::instance()->setLogFlush(true); + OCC::Logger::instance()->setLogDebug(true); + + QStandardPaths::setTestModeEnabled(true); + } + + void test_whenAccountStateIsNotConnected_doesNotCrash() + { + auto account = Account::create(); + auto accountState = new FakeAccountState(account); + accountState->setStateForTesting(OCC::AccountState::SignedOut); + QCOMPARE_EQ(accountState->state(), OCC::AccountState::SignedOut); + AccountSettings a(accountState); + } + + void test_whenAccountStateIsConnected_doesNotCrash() + { + // this occurred because ConnectionValidator used to set the account + // inside a Account's _e2e member, instead of letting Account itself + // do that. + + auto account = Account::create(); + auto accountState = new FakeAccountState(account); + QCOMPARE_EQ(accountState->state(), OCC::AccountState::Connected); + AccountSettings a(accountState); + } +}; + +QTEST_MAIN(TestAccountSettings) +#include "testaccountsettings.moc" diff --git a/test/testhelper.h b/test/testhelper.h index 80bb99fe6c721..e0d1c97431063 100644 --- a/test/testhelper.h +++ b/test/testhelper.h @@ -44,6 +44,16 @@ class FakeAccountState : public OCC::AccountState public slots: void checkConnectivity() override {}; + void setStateForTesting(OCC::AccountState::State state) + { + if (_state == state) { + return; + } + + _state = state; + Q_EMIT stateChanged(state); + } + private slots: void setState(OCC::AccountState::State state) override { Q_UNUSED(state) }; }; From 381fc61d4163a214a7c90bebe152a9e606c807b2 Mon Sep 17 00:00:00 2001 From: Jyrki Gadinger Date: Fri, 7 Nov 2025 14:02:09 +0100 Subject: [PATCH 2/2] chore(test): exclude AccountSettings test from CI/ctest runs when building a VFS client Ironically enough, a VFS/File Provider client build crashes on this test when run in CI. I'm not yet sure what's causing it as it works fine in a non-VFS build... Signed-off-by: Jyrki Gadinger --- test/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 77b39298b277e..c9f1a078def49 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -141,11 +141,16 @@ nextcloud_add_test(LongPath) nextcloud_add_benchmark(LargeSync) nextcloud_add_test(Account) -nextcloud_add_test(AccountSettings) nextcloud_add_test(Folder) nextcloud_add_test(FolderMan) nextcloud_add_test(RemoteWipe) +if(NOT BUILD_FILE_PROVIDER_MODULE) + # the File Provider build crashes this test in CI for some reason + # I'm not yet sure what's causing it as it works fine with a classic build... + nextcloud_add_test(AccountSettings) +endif() + configure_file(test_journal.db "${PROJECT_BINARY_DIR}/bin/test_journal.db" COPYONLY) find_package(CMocka)