File indexing completed on 2024-05-12 05:52:47
0001 /* 0002 * SPDX-License-Identifier: GPL-3.0-or-later 0003 * SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com> 0004 */ 0005 #include "account/account.h" 0006 0007 #include "../test-utils/output.h" 0008 #include "../../test-utils/spy.h" 0009 0010 #include <QDateTime> 0011 #include <QFile> 0012 #include <QSignalSpy> 0013 #include <QString> 0014 #include <QTest> 0015 #include <QVector> 0016 #include <QtDebug> 0017 0018 static QString testIniResource(QLatin1String("test.ini")); 0019 0020 class StorageDefaultLifeCycleTest: public QObject 0021 { 0022 Q_OBJECT 0023 private Q_SLOTS: 0024 void initTestCase(void); 0025 void testLifecycle(void); 0026 }; 0027 0028 void StorageDefaultLifeCycleTest::initTestCase(void) 0029 { 0030 QVERIFY2(test::ensureOutputDirectory(), "output directory should be available"); 0031 QVERIFY2(test::copyResourceAsWritable(QStringLiteral(":/storage-lifecycles/starting.ini"), testIniResource), "test corpus INI resource should be available as file"); 0032 } 0033 0034 void StorageDefaultLifeCycleTest::testLifecycle(void) 0035 { 0036 const QString iniResource = test::path(testIniResource); 0037 const QString samleAccountFullName(QLatin1String("autotests:valid-hotp-sample-1")); 0038 0039 const accounts::SettingsProvider settings([&iniResource](const accounts::PersistenceAction &action) -> void 0040 { 0041 QSettings data(iniResource, QSettings::IniFormat); 0042 action(data); 0043 }); 0044 0045 accounts::AccountStorage *uut = accounts::AccountStorage::open(settings); 0046 QSignalSpy error(uut, &accounts::AccountStorage::error); 0047 QSignalSpy loaded(uut, &accounts::AccountStorage::loaded); 0048 QSignalSpy accountAdded(uut, &accounts::AccountStorage::added); 0049 QSignalSpy storageDisposed(uut, &accounts::AccountStorage::disposed); 0050 QSignalSpy storageCleaned(uut, &accounts::AccountStorage::destroyed); 0051 0052 accounts::AccountSecret *secret = uut->secret(); 0053 QSignalSpy existingPasswordNeeded(secret, &accounts::AccountSecret::existingPasswordNeeded); 0054 QSignalSpy newPasswordNeeded(secret, &accounts::AccountSecret::newPasswordNeeded); 0055 QSignalSpy passwordAvailable(secret, &accounts::AccountSecret::passwordAvailable); 0056 QSignalSpy keyAvailable(secret, &accounts::AccountSecret::keyAvailable); 0057 QSignalSpy passwordRequestsCancelled(secret, &accounts::AccountSecret::requestsCancelled); 0058 QSignalSpy secretCleaned(secret, &accounts::AccountSecret::destroyed); 0059 0060 // first phase: check that account objects can be loaded from storage 0061 QCOMPARE(uut->isLoaded(), false); 0062 QCOMPARE(uut->hasError(), false); 0063 0064 // expect that unlocking is scheduled automatically, so advancing the event loop should trigger the signal 0065 QVERIFY2(test::signal_eventually_emitted_once(existingPasswordNeeded), "(existing) password should be asked by now"); 0066 QCOMPARE(newPasswordNeeded.count(), 0); 0067 0068 QString password(QLatin1String("password")); 0069 secret->answerExistingPassword(password); 0070 0071 QVERIFY2(test::signal_eventually_emitted_once(passwordAvailable), "(existing) password should have been accepted by now"); 0072 QCOMPARE(password, QString(QLatin1String("********"))); 0073 0074 QVERIFY2(test::signal_eventually_emitted_once(keyAvailable, 2500), "key should have been derived by now"); 0075 0076 // expect that loading is scheduled automatically, so advancing the event loop should trigger the signal 0077 QVERIFY2(test::signal_eventually_emitted_once(loaded), "sample account should be loaded by now"); 0078 QCOMPARE(uut->isLoaded(), true); 0079 QCOMPARE(uut->hasError(), false); 0080 QCOMPARE(error.count(), 0); 0081 QCOMPARE(accountAdded.count(), 1); 0082 QCOMPARE(accountAdded.at(0).at(0), samleAccountFullName); 0083 0084 accounts::Account *sampleAccount = uut->get(samleAccountFullName); 0085 QVERIFY2(sampleAccount != nullptr, "get() should return the sample account"); 0086 0087 QSignalSpy sampleAccountCleaned(sampleAccount, &accounts::Account::destroyed); 0088 0089 // second phase: check that disposing storage cleans up objects properly 0090 uut->dispose(); 0091 0092 QVERIFY2(test::signal_eventually_emitted_once(passwordRequestsCancelled), "account secret should have signalled cancellation by now"); 0093 QVERIFY2(test::signal_eventually_emitted_once(storageDisposed), "storage should be disposed of by now"); 0094 QVERIFY2(test::signal_eventually_emitted_once(sampleAccountCleaned), "sample account should be cleaned up by now"); 0095 QVERIFY2(test::signal_eventually_emitted_once(secretCleaned), "account secret should be cleaned up by now"); 0096 QVERIFY2(test::signal_eventually_emitted_once(storageCleaned), "storage should be cleaned up by now"); 0097 } 0098 0099 QTEST_MAIN(StorageDefaultLifeCycleTest) 0100 0101 #include "storage-default-lifecycle.moc"