File indexing completed on 2024-05-12 05:26:07
0001 /* 0002 * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) version 3, or any 0008 * later version accepted by the membership of KDE e.V. (or its 0009 * successor approved by the membership of KDE e.V.), which shall 0010 * act as a proxy defined in Section 6 of version 3 of the license. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Lesser General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Lesser General Public 0018 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 0019 */ 0020 0021 #include "test.h" 0022 0023 #include <QStandardPaths> 0024 #include <QDir> 0025 #include <QDebug> 0026 #include "facade.h" 0027 #include "facadefactory.h" 0028 #include "query.h" 0029 #include "resourceconfig.h" 0030 #include "definitions.h" 0031 0032 using namespace Sink; 0033 0034 void Sink::Test::initTest() 0035 { 0036 auto logIniFile = Sink::configLocation() + "/log.ini"; 0037 auto areaAutocompletionFile = Sink::dataLocation() + "/debugAreas.ini"; 0038 0039 setTestModeEnabled(true); 0040 // qDebug() << "Removing " << QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); 0041 QDir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)).removeRecursively(); 0042 // qDebug() << "Removing " << QStandardPaths::writableLocation(QStandardPaths::DataLocation); 0043 QDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)).removeRecursively(); 0044 // qDebug() << "Removing " << QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); 0045 QDir(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)).removeRecursively(); 0046 // qDebug() << "Removing " << QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); 0047 QDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)).removeRecursively(); 0048 // qDebug() << "Removing " << QStandardPaths::writableLocation(QStandardPaths::CacheLocation); 0049 QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)).removeRecursively(); 0050 // qDebug() << "Removing " << QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation); 0051 QDir(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)).removeRecursively(); 0052 Log::setPrimaryComponent("test"); 0053 0054 //We copy those files so we can control debug output from outside the test with sinksh 0055 { 0056 QDir dir; 0057 dir.mkpath(Sink::configLocation()); 0058 0059 QFile file(logIniFile); 0060 if (!file.open(QIODevice::ReadOnly)) { 0061 qWarning() << "Failed to open the file: " << logIniFile; 0062 } else { 0063 if (!file.copy(Sink::configLocation() + "/log.ini")) { 0064 qWarning() << "Failed to move the file: " << Sink::configLocation() + "/log.ini"; 0065 } 0066 } 0067 } 0068 { 0069 QFile file(areaAutocompletionFile); 0070 if (!file.open(QIODevice::ReadOnly)) { 0071 qWarning() << "Failed to open the file: " << logIniFile; 0072 } 0073 QDir dir; 0074 dir.mkpath(Sink::dataLocation()); 0075 if (!file.copy(Sink::dataLocation() + "/debugAreas.ini")) { 0076 qWarning() << "Failed to move the file: " << Sink::configLocation() + "/log.ini"; 0077 } 0078 } 0079 } 0080 0081 void Sink::Test::setTestModeEnabled(bool enabled) 0082 { 0083 QStandardPaths::setTestModeEnabled(enabled); 0084 Sink::clearLocationCache(); 0085 if (enabled) { 0086 qputenv("SINK_TESTMODE", "TRUE"); 0087 } else { 0088 qunsetenv("SINK_TESTMODE"); 0089 } 0090 } 0091 0092 bool Sink::Test::testModeEnabled() 0093 { 0094 return !qEnvironmentVariableIsEmpty("SINK_TESTMODE"); 0095 } 0096 0097 template <typename T> 0098 class TestFacade : public Sink::StoreFacade<T> 0099 { 0100 public: 0101 static std::shared_ptr<TestFacade<T>> registerFacade(Test::TestAccount *testAccount, const QByteArray &instanceIdentifier = QByteArray()) 0102 { 0103 static QMap<QByteArray, std::shared_ptr<TestFacade<T>>> map; 0104 auto facade = std::make_shared<TestFacade<T>>(); 0105 facade->mTestAccount = testAccount; 0106 map.insert(instanceIdentifier, facade); 0107 bool alwaysReturnFacade = instanceIdentifier.isEmpty(); 0108 Sink::FacadeFactory::instance().registerFacade<T, TestFacade<T>>("testresource", [alwaysReturnFacade](const Sink::ResourceContext &context) { 0109 if (alwaysReturnFacade) { 0110 return map.value(QByteArray()); 0111 } 0112 return map.value(context.resourceInstanceIdentifier); 0113 }); 0114 return facade; 0115 } 0116 ~TestFacade() Q_DECL_OVERRIDE {}; 0117 KAsync::Job<void> create(const T &domainObject) Q_DECL_OVERRIDE 0118 { 0119 mTestAccount->addEntity<T>(T::Ptr::create(domainObject)); 0120 return KAsync::null<void>(); 0121 }; 0122 KAsync::Job<void> modify(const T &domainObject) Q_DECL_OVERRIDE 0123 { 0124 // mTestAccount->modifyEntity<T>(domainObject); 0125 return KAsync::null<void>(); 0126 }; 0127 KAsync::Job<void> move(const T &domainObject, const QByteArray &newResource) Q_DECL_OVERRIDE 0128 { 0129 // mTestAccount->moveEntity<T>(domainObject, newResource); 0130 return KAsync::null<void>(); 0131 }; 0132 KAsync::Job<void> copy(const T &domainObject, const QByteArray &newResource) Q_DECL_OVERRIDE 0133 { 0134 // mTestAccount->copyEntity<T>(domainObject, newResource); 0135 return KAsync::null<void>(); 0136 }; 0137 KAsync::Job<void> remove(const T &domainObject) Q_DECL_OVERRIDE 0138 { 0139 //FIXME 0140 // mTestAccount->removeEntity<T>(domainObject); 0141 return KAsync::null<void>(); 0142 }; 0143 QPair<KAsync::Job<void>, typename Sink::ResultEmitter<typename T::Ptr>::Ptr> load(const Sink::Query &query, const Sink::Log::Context &) Q_DECL_OVERRIDE 0144 { 0145 auto resultProvider = new Sink::ResultProvider<typename T::Ptr>(); 0146 resultProvider->onDone([resultProvider]() { 0147 SinkTrace() << "Result provider is done"; 0148 delete resultProvider; 0149 }); 0150 // We have to do it this way, otherwise we're not setting the fetcher right 0151 auto emitter = resultProvider->emitter(); 0152 0153 resultProvider->setFetcher([query, resultProvider, this]() { 0154 SinkTrace() << "Running the fetcher."; 0155 SinkTrace() << "-------------------------."; 0156 for (const auto &res : mTestAccount->entities<T>()) { 0157 resultProvider->add(res.template staticCast<T>()); 0158 } 0159 resultProvider->initialResultSetComplete(true); 0160 }); 0161 return qMakePair(KAsync::null(), emitter); 0162 } 0163 0164 Test::TestAccount *mTestAccount; 0165 }; 0166 0167 Test::TestAccount Sink::Test::TestAccount::registerAccount() 0168 { 0169 Test::TestAccount account; 0170 account.mFacades.insert(ApplicationDomain::getTypeName<ApplicationDomain::Folder>(), TestFacade<ApplicationDomain::Folder>::registerFacade(&account)); 0171 account.mFacades.insert(ApplicationDomain::getTypeName<ApplicationDomain::Mail>(), TestFacade<ApplicationDomain::Mail>::registerFacade(&account)); 0172 account.identifier = "testresource.instance1"; 0173 ResourceConfig::addResource(account.identifier, "testresource"); 0174 QMap<QByteArray, QVariant> configuration; 0175 configuration.insert(ApplicationDomain::SinkResource::Account::name, account.identifier); 0176 configuration.insert(ApplicationDomain::SinkResource::Capabilities::name, QVariant::fromValue(QByteArrayList() << ApplicationDomain::ResourceCapabilities::Mail::drafts << ApplicationDomain::ResourceCapabilities::Mail::storage << ApplicationDomain::ResourceCapabilities::Mail::transport)); 0177 ResourceConfig::configureResource(account.identifier, configuration); 0178 return account; 0179 } 0180 0181 template<typename DomainType> 0182 void Sink::Test::TestAccount::addEntity(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject) 0183 { 0184 mEntities[ApplicationDomain::getTypeName<DomainType>()].append(domainObject); 0185 } 0186 0187 template<typename DomainType> 0188 typename DomainType::Ptr Sink::Test::TestAccount::createEntity() 0189 { 0190 auto entity = DomainType::Ptr::create(ApplicationDomain::ApplicationDomainType::createEntity<DomainType>(identifier)); 0191 addEntity<DomainType>(entity); 0192 return entity; 0193 } 0194 0195 template<typename DomainType> 0196 QList<Sink::ApplicationDomain::ApplicationDomainType::Ptr> Sink::Test::TestAccount::entities() const 0197 { 0198 return mEntities.value(ApplicationDomain::getTypeName<DomainType>()); 0199 } 0200 0201 0202 #define REGISTER_TYPE(T) \ 0203 template QList<Sink::ApplicationDomain::ApplicationDomainType::Ptr> Sink::Test::TestAccount::entities<T>() const; \ 0204 template void Sink::Test::TestAccount::addEntity<T>(const ApplicationDomain::ApplicationDomainType::Ptr &); \ 0205 template typename T::Ptr Sink::Test::TestAccount::createEntity<T>(); 0206 0207 SINK_REGISTER_TYPES()