File indexing completed on 2024-05-12 05:22:06

0001 /*
0002  * SPDX-FileCopyrightText: 2018 Daniel Vrátil <dvratil@kde.org>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005  */
0006 
0007 #include <QList>
0008 #include <QObject>
0009 #include <QSignalSpy>
0010 #include <QTest>
0011 
0012 #include "account.h"
0013 #include "accountmanager.h"
0014 #include "accountstorage_p.h"
0015 #include "fakeaccountstorage.h"
0016 #include "fakeauthbrowser.h"
0017 #include "fakenetworkaccessmanager.h"
0018 #include "fakenetworkaccessmanagerfactory.h"
0019 #include "fakenetworkreply.h"
0020 #include "testutils.h"
0021 
0022 using namespace KGAPI2;
0023 
0024 namespace
0025 {
0026 
0027 const static auto ApiKey1 = QStringLiteral("Key1");
0028 const static auto SecretKey1 = QStringLiteral("Secret1");
0029 const static auto Account1 = QStringLiteral("jonh.doe@fakegmail.invalid");
0030 
0031 }
0032 
0033 class TestableAccountManager : public AccountManager
0034 {
0035     Q_OBJECT
0036 public:
0037     explicit TestableAccountManager(QObject *parent = nullptr)
0038         : AccountManager(parent)
0039     {
0040         sInstance = this;
0041     }
0042 
0043     ~TestableAccountManager() override
0044     {
0045         sInstance = nullptr;
0046     }
0047 
0048     FakeAccountStorage *fakeStore() const
0049     {
0050         return mStorageFactory.fakeStore();
0051     }
0052 
0053 private:
0054     FakeAccountStorageFactory mStorageFactory;
0055 };
0056 
0057 class AccountManagerTest : public QObject
0058 {
0059     Q_OBJECT
0060 
0061 private Q_SLOTS:
0062     void initTestCase()
0063     {
0064         NetworkAccessManagerFactory::setFactory(new FakeNetworkAccessManagerFactory);
0065     }
0066 
0067     void testGetNewAccount()
0068     {
0069         FakeAuthBrowser authBrowser;
0070         FakeNetworkAccessManagerFactory::get()->setScenarios(
0071             {scenarioFromFile(QFINDTESTDATA("data/accountmanager_part1_request.txt"), QFINDTESTDATA("data/accountmanager_part1_response.txt"), false),
0072              scenarioFromFile(QFINDTESTDATA("data/accountinfo_fetch_request.txt"), QFINDTESTDATA("data/accountinfo_fetch_response.txt"))});
0073 
0074         TestableAccountManager accountManager;
0075         const auto promise = accountManager.getAccount(ApiKey1, SecretKey1, Account1, {Account::peopleScopeUrl()});
0076 
0077         QCOMPARE(promise->account(), AccountPtr{});
0078         QSignalSpy spy(promise, &AccountPromise::finished);
0079         QVERIFY(spy.wait());
0080         QCOMPARE(spy.count(), 1);
0081         const auto account = promise->account();
0082         QVERIFY(account);
0083         QCOMPARE(account->accountName(), Account1);
0084         const QList<QUrl> expectedScopes = {Account::peopleScopeUrl(), Account::accountInfoEmailScopeUrl()};
0085         QCOMPARE(account->scopes(), expectedScopes);
0086         QVERIFY(!account->accessToken().isEmpty());
0087         QVERIFY(!account->refreshToken().isEmpty());
0088         QVERIFY(account->expireDateTime().isValid());
0089 
0090         const auto storeAccount = accountManager.fakeStore()->mStore.value(ApiKey1 + Account1);
0091         QVERIFY(storeAccount);
0092         QCOMPARE(*storeAccount, *account);
0093     }
0094 
0095     void testGetExistingAccount()
0096     {
0097         TestableAccountManager accountManager;
0098 
0099         const auto insertedAccount = AccountPtr::create(*accountManager.fakeStore()->generateAccount(ApiKey1, Account1, {Account::peopleScopeUrl()}));
0100         QVERIFY(insertedAccount);
0101 
0102         const auto promise = accountManager.getAccount(ApiKey1, SecretKey1, Account1, {Account::peopleScopeUrl()});
0103         QCOMPARE(promise->account(), AccountPtr{});
0104         QSignalSpy spy(promise, &AccountPromise::finished);
0105         QVERIFY(spy.wait());
0106         QCOMPARE(spy.count(), 1);
0107         QVERIFY(promise->account());
0108 
0109         QCOMPARE(*promise->account(), *insertedAccount);
0110     }
0111 
0112     void testMergeAccountScopes()
0113     {
0114         FakeAuthBrowser authBrowser;
0115         FakeNetworkAccessManagerFactory::get()->setScenarios(
0116             {scenarioFromFile(QFINDTESTDATA("data/accountmanager_part1_request.txt"), QFINDTESTDATA("data/accountmanager_part1_response.txt"), false),
0117              scenarioFromFile(QFINDTESTDATA("data/accountinfo_fetch_request.txt"), QFINDTESTDATA("data/accountinfo_fetch_response.txt"))});
0118 
0119         TestableAccountManager accountManager;
0120         const auto insertedAccount = accountManager.fakeStore()->generateAccount(ApiKey1, Account1, {Account::peopleScopeUrl()});
0121         QVERIFY(insertedAccount);
0122         auto expectedAccount = AccountPtr::create(*insertedAccount);
0123         expectedAccount->setScopes({Account::peopleScopeUrl(), Account::calendarScopeUrl(), Account::accountInfoEmailScopeUrl()});
0124 
0125         const auto promise = accountManager.getAccount(ApiKey1, SecretKey1, Account1, {Account::calendarScopeUrl()});
0126         QCOMPARE(promise->account(), AccountPtr{});
0127         QSignalSpy spy(promise, &AccountPromise::finished);
0128         QVERIFY(spy.wait());
0129         QCOMPARE(spy.count(), 1);
0130         const auto account = promise->account();
0131         QVERIFY(account);
0132         QCOMPARE(account->accountName(), Account1);
0133         QVERIFY(!account->accessToken().isEmpty());
0134         QVERIFY(!account->refreshToken().isEmpty());
0135         QVERIFY(account->expireDateTime().isValid());
0136         QCOMPARE(account->scopes(), expectedAccount->scopes());
0137 
0138         const auto storeAccount = accountManager.fakeStore()->mStore.value(ApiKey1 + Account1);
0139         QVERIFY(storeAccount);
0140         QCOMPARE(storeAccount->accountName(), Account1);
0141         QVERIFY(!storeAccount->accessToken().isEmpty());
0142         QVERIFY(!storeAccount->refreshToken().isEmpty());
0143         QVERIFY(storeAccount->expireDateTime().isValid());
0144         QCOMPARE(storeAccount->scopes(), expectedAccount->scopes());
0145     }
0146 
0147     void testRemoveAccountScopes()
0148     {
0149         TestableAccountManager accountManager;
0150         accountManager.fakeStore()->generateAccount(ApiKey1, Account1, {Account::peopleScopeUrl(), Account::calendarScopeUrl()});
0151 
0152         accountManager.removeScopes(ApiKey1, Account1, {Account::peopleScopeUrl()});
0153 
0154         const auto storeAccount = accountManager.fakeStore()->mStore.value(ApiKey1 + Account1);
0155         QVERIFY(storeAccount);
0156         QCOMPARE(storeAccount->accountName(), Account1);
0157         QVERIFY(storeAccount->accessToken().isEmpty());
0158         QVERIFY(storeAccount->refreshToken().isEmpty());
0159         QVERIFY(storeAccount->expireDateTime().isNull());
0160         QCOMPARE(storeAccount->scopes(), QList<QUrl>{Account::calendarScopeUrl()});
0161     }
0162 
0163     void testRemoveAllScopes()
0164     {
0165         TestableAccountManager accountManager;
0166         accountManager.fakeStore()->generateAccount(ApiKey1, Account1, {Account::peopleScopeUrl(), Account::calendarScopeUrl()});
0167 
0168         accountManager.removeScopes(ApiKey1, Account1, {Account::peopleScopeUrl(), Account::calendarScopeUrl()});
0169 
0170         QVERIFY(!accountManager.fakeStore()->mStore.contains(ApiKey1 + Account1));
0171     }
0172 
0173     void testFindInvalidAccount()
0174     {
0175         TestableAccountManager accountManager;
0176 
0177         const auto promise = accountManager.findAccount(ApiKey1, Account1);
0178         QCOMPARE(promise->account(), AccountPtr{});
0179         QSignalSpy spy(promise, &AccountPromise::finished);
0180         QVERIFY(spy.wait());
0181         QCOMPARE(spy.count(), 1);
0182         QCOMPARE(promise->account(), AccountPtr());
0183     }
0184 
0185     void testFindValidAccount()
0186     {
0187         TestableAccountManager accountManager;
0188 
0189         const auto insertedAccount = accountManager.fakeStore()->generateAccount(ApiKey1, Account1, {Account::calendarScopeUrl()});
0190 
0191         const auto promise = accountManager.findAccount(ApiKey1, Account1);
0192         QCOMPARE(promise->account(), AccountPtr{});
0193         QSignalSpy spy(promise, &AccountPromise::finished);
0194         QVERIFY(spy.wait());
0195         QCOMPARE(spy.count(), 1);
0196         QVERIFY(promise->account());
0197         QCOMPARE(*promise->account(), *insertedAccount);
0198     }
0199 
0200     void testRefreshTokens()
0201     {
0202         FakeAuthBrowser authBrowser;
0203         FakeNetworkAccessManagerFactory::get()->setScenarios(
0204             {scenarioFromFile(QFINDTESTDATA("data/accountmanager_refresh_request.txt"), QFINDTESTDATA("data/accountmanager_refresh_response.txt"), false)});
0205 
0206         TestableAccountManager accountManager;
0207 
0208         auto insertedAccount = accountManager.fakeStore()->generateAccount(ApiKey1, Account1, {Account::calendarScopeUrl()});
0209         insertedAccount->setRefreshToken(QStringLiteral("FakeRefreshToken"));
0210 
0211         const auto promise = accountManager.refreshTokens(ApiKey1, SecretKey1, Account1);
0212         QCOMPARE(promise->account(), AccountPtr{});
0213         QSignalSpy spy(promise, &AccountPromise::finished);
0214         QVERIFY(spy.wait());
0215         QCOMPARE(spy.count(), 1);
0216         QVERIFY(promise->account());
0217         QCOMPARE(promise->account()->accountName(), insertedAccount->accountName());
0218         QCOMPARE(promise->account()->accessToken(), QStringLiteral("NewAccessToken"));
0219     }
0220 };
0221 
0222 QTEST_MAIN(AccountManagerTest)
0223 
0224 #include "accountmanagertest.moc"