summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-06-17 09:09:33 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-06-17 09:09:33 +0200
commit3f4011bcbf4ccf55edb8ea618fbf9b50f9e7bec9 (patch)
tree489d4bc4c672d60f35a20556cb16a98d871a9fe9
parent749c4d7da40bf20d240be5ad7948f4be843865cd (diff)
downloadsink-3f4011bcbf4ccf55edb8ea618fbf9b50f9e7bec9.tar.gz
sink-3f4011bcbf4ccf55edb8ea618fbf9b50f9e7bec9.zip
Initial version of the mailtransport resource
-rw-r--r--common/entitystore.h6
-rw-r--r--examples/mailtransportresource/CMakeLists.txt4
-rw-r--r--examples/mailtransportresource/facade.cpp142
-rw-r--r--examples/mailtransportresource/facade.h36
-rw-r--r--examples/mailtransportresource/mailtransport.cpp11
-rw-r--r--examples/mailtransportresource/mailtransport.h2
-rw-r--r--examples/mailtransportresource/mailtransportresource.cpp199
-rw-r--r--examples/mailtransportresource/mailtransportresource.h20
-rw-r--r--examples/mailtransportresource/tests/CMakeLists.txt11
-rw-r--r--examples/mailtransportresource/tests/mailtransporttest.cpp94
10 files changed, 337 insertions, 188 deletions
diff --git a/common/entitystore.h b/common/entitystore.h
index b795b26..6bfe414 100644
--- a/common/entitystore.h
+++ b/common/entitystore.h
@@ -54,6 +54,12 @@ public:
54 return reader.readPrevious(uid, revision); 54 return reader.readPrevious(uid, revision);
55 } 55 }
56 56
57 template<typename T>
58 EntityReader<T> reader()
59 {
60 return EntityReader<T>(mResourceType, mResourceInstanceIdentifier, mTransaction);
61 }
62
57private: 63private:
58 QByteArray mResourceType; 64 QByteArray mResourceType;
59 QByteArray mResourceInstanceIdentifier; 65 QByteArray mResourceInstanceIdentifier;
diff --git a/examples/mailtransportresource/CMakeLists.txt b/examples/mailtransportresource/CMakeLists.txt
index c9b0401..d16e779 100644
--- a/examples/mailtransportresource/CMakeLists.txt
+++ b/examples/mailtransportresource/CMakeLists.txt
@@ -9,8 +9,10 @@ find_package(CURL 7.20.0 REQUIRED)
9include_directories(${CURL_INCLUDE_DIRS}) 9include_directories(${CURL_INCLUDE_DIRS})
10 10
11 11
12add_library(${PROJECT_NAME} SHARED facade.cpp mailtransportresource.cpp mailtransport.cpp) 12add_library(${PROJECT_NAME} SHARED mailtransportresource.cpp mailtransport.cpp)
13qt5_use_modules(${PROJECT_NAME} Core Network) 13qt5_use_modules(${PROJECT_NAME} Core Network)
14target_link_libraries(${PROJECT_NAME} sink KF5::Mime ${CURL_LIBRARIES}) 14target_link_libraries(${PROJECT_NAME} sink KF5::Mime ${CURL_LIBRARIES})
15 15
16add_subdirectory(tests)
17
16install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SINK_RESOURCE_PLUGINS_PATH}) 18install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${SINK_RESOURCE_PLUGINS_PATH})
diff --git a/examples/mailtransportresource/facade.cpp b/examples/mailtransportresource/facade.cpp
deleted file mode 100644
index cd0dd62..0000000
--- a/examples/mailtransportresource/facade.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
1/*
2 * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include "facade.h"
21
22#include <QDir>
23#include <QFileInfo>
24#include <QSettings>
25#include <QStandardPaths>
26#include <QUuid>
27#include <KMime/Message>
28
29#include "resultprovider.h"
30#include "mailtransport.h"
31#include <log.h>
32#include <resourceconfig.h>
33
34static QString dataDirectory(const QByteArray &identifier)
35{
36 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/sink/mailtransport/" + identifier;
37}
38
39class Outbox {
40public:
41 Outbox(const QByteArray &identifier) : mIdentifier(identifier)
42 {
43
44 }
45
46 static QString fileName(const QByteArray &resourceId, const QByteArray &messageId)
47 {
48 return dataDirectory(resourceId)+"/" + messageId;
49 }
50
51 void add(const QByteArray &messageId, const QString &messagePath, QMap<QByteArray, QString> config)
52 {
53 QDir dir;
54 dir.mkpath(dataDirectory(mIdentifier));
55 if (!QFile(messagePath).rename(fileName(mIdentifier, messageId))) {
56 ErrorMsg() << "Failed to move the file:";
57 ErrorMsg() << messagePath << " to " << fileName(mIdentifier, messageId);
58 }
59 //TODO store settings
60 // QSettings settings(dataDirectory(mIdentifier) + "/messageId.ini", QSettings::IniFormat);
61 }
62
63 void dispatch(const QByteArray &messageId)
64 {
65 QFile mimeMessage(fileName(mIdentifier, messageId));
66 if (!mimeMessage.open(QIODevice::ReadOnly)) {
67 ErrorMsg() << "Failed to open mime message: " << mimeMessage.errorString();
68 ErrorMsg() << fileName(mIdentifier, messageId);
69 return;
70 }
71
72 auto msg = KMime::Message::Ptr::create();
73 msg->setHead(KMime::CRLFtoLF(mimeMessage.readAll()));
74 msg->parse();
75 MailTransport::sendMessage(msg, mServer, mUsername, mPassword, mCaCert);
76 Trace() << "Sent message: " << msg->subject();
77 }
78
79 void setServer(const QByteArray &server, const QByteArray &username, const QByteArray &caCert)
80 {
81 mServer = server;
82 mUsername = username;
83 mCaCert = caCert;
84 }
85
86 void setPassword(const QByteArray &password)
87 {
88 mPassword = password;
89 }
90
91private:
92 QByteArray mServer;
93 QByteArray mUsername;
94 QByteArray mPassword;
95 QByteArray mCaCert;
96 QByteArray mIdentifier;
97};
98
99MailtransportFacade::MailtransportFacade(const QByteArray &identifier) : Sink::StoreFacade<Sink::ApplicationDomain::Mail>(), mIdentifier(identifier)
100{
101}
102
103MailtransportFacade::~MailtransportFacade()
104{
105}
106
107KAsync::Job<void> MailtransportFacade::create(const Sink::ApplicationDomain::Mail &mail)
108{
109 Trace() << "Called create: ";
110 return KAsync::start<void>([mail, this]() {
111 auto config = ResourceConfig::getConfiguration(mIdentifier);
112
113 auto identifier = Sink::Storage::generateUid();
114 Trace() << "Sending new message: " << identifier;
115 Trace() << config.value("server").toByteArray() << config.value("username").toByteArray() << config.value("cacert").toByteArray();
116
117 Outbox outbox(mIdentifier);
118 outbox.setServer(config.value("server").toByteArray(), config.value("username").toByteArray(), config.value("cacert").toByteArray());
119 //FIXME remove and somehow retrieve the password on demand
120 outbox.setPassword(config.value("password").toByteArray());
121
122 const QByteArray mimeMessage = mail.getProperty("mimeMessage").toByteArray();
123 QMap<QByteArray, QString> configurationValues;
124 outbox.add(identifier, mimeMessage, configurationValues);
125 outbox.dispatch(identifier);
126 });
127}
128
129KAsync::Job<void> MailtransportFacade::modify(const Sink::ApplicationDomain::Mail &mail)
130{
131 return KAsync::error<void>(0, "Not implemented.");
132}
133
134KAsync::Job<void> MailtransportFacade::remove(const Sink::ApplicationDomain::Mail &mail)
135{
136 return KAsync::error<void>(0, "Not implemented.");
137}
138
139QPair<KAsync::Job<void>, typename Sink::ResultEmitter<Sink::ApplicationDomain::Mail::Ptr>::Ptr> MailtransportFacade::load(const Sink::Query &query)
140{
141 return qMakePair(KAsync::error<void>(0, "Not implemented."), Sink::ResultEmitter<Sink::ApplicationDomain::Mail::Ptr>::Ptr());
142}
diff --git a/examples/mailtransportresource/facade.h b/examples/mailtransportresource/facade.h
deleted file mode 100644
index 858f73a..0000000
--- a/examples/mailtransportresource/facade.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * Copyright (C) 2014 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#pragma once
21
22#include "common/facade.h"
23
24class MailtransportFacade : public Sink::StoreFacade<Sink::ApplicationDomain::Mail>
25{
26public:
27 MailtransportFacade(const QByteArray &instanceIdentifier);
28 virtual ~MailtransportFacade();
29 KAsync::Job<void> create(const Sink::ApplicationDomain::Mail &resource) Q_DECL_OVERRIDE;
30 KAsync::Job<void> modify(const Sink::ApplicationDomain::Mail &resource) Q_DECL_OVERRIDE;
31 KAsync::Job<void> remove(const Sink::ApplicationDomain::Mail &resource) Q_DECL_OVERRIDE;
32 QPair<KAsync::Job<void>, typename Sink::ResultEmitter<Sink::ApplicationDomain::Mail::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE;
33private:
34 QByteArray mIdentifier;
35};
36
diff --git a/examples/mailtransportresource/mailtransport.cpp b/examples/mailtransportresource/mailtransport.cpp
index 49d858e..5985562 100644
--- a/examples/mailtransportresource/mailtransport.cpp
+++ b/examples/mailtransportresource/mailtransport.cpp
@@ -58,7 +58,7 @@ static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
58} 58}
59 59
60 60
61void sendMessageCurl(const char *to[], int numTos, const char *cc[], int numCcs, const char *msg, bool useTls, const char* from, const char *username, const char *password, const char *server, bool verifyPeer) 61bool sendMessageCurl(const char *to[], int numTos, const char *cc[], int numCcs, const char *msg, bool useTls, const char* from, const char *username, const char *password, const char *server, bool verifyPeer)
62{ 62{
63 //For ssl use "smtps://mainserver.example.net 63 //For ssl use "smtps://mainserver.example.net
64 const char* cacert = 0; // = "/path/to/certificate.pem"; 64 const char* cacert = 0; // = "/path/to/certificate.pem";
@@ -121,15 +121,17 @@ void sendMessageCurl(const char *to[], int numTos, const char *cc[], int numCcs,
121 } 121 }
122 curl_slist_free_all(recipients); 122 curl_slist_free_all(recipients);
123 curl_easy_cleanup(curl); 123 curl_easy_cleanup(curl);
124 return res == CURLE_OK;
124 } 125 }
126 return false;
125} 127}
126 128
127}; 129};
128 130
129void MailTransport::sendMessage(const KMime::Message::Ptr &message, const QByteArray &server, const QByteArray &username, const QByteArray &password, const QByteArray &cacert) 131bool MailTransport::sendMessage(const KMime::Message::Ptr &message, const QByteArray &server, const QByteArray &username, const QByteArray &password, const QByteArray &cacert)
130{ 132{
131 QByteArray msg = message->encodedContent(); 133 QByteArray msg = message->encodedContent();
132 qWarning() << "Sending message " << msg; 134 qDebug() << "Sending message " << msg;
133 135
134 QByteArray from(message->from(true)->mailboxes().isEmpty() ? QByteArray() : message->from(true)->mailboxes().first().address()); 136 QByteArray from(message->from(true)->mailboxes().isEmpty() ? QByteArray() : message->from(true)->mailboxes().first().address());
135 QList<QByteArray> toList; 137 QList<QByteArray> toList;
@@ -155,6 +157,5 @@ void MailTransport::sendMessage(const KMime::Message::Ptr &message, const QByteA
155 cc[i] = ccList.at(i); 157 cc[i] = ccList.at(i);
156 } 158 }
157 159
158 sendMessageCurl(to, numTos, cc, numCcs, msg, useTls, from.isEmpty() ? nullptr : from, username, password, server, verifyPeer); 160 return sendMessageCurl(to, numTos, cc, numCcs, msg, useTls, from.isEmpty() ? nullptr : from, username, password, server, verifyPeer);
159 qWarning() << "Message sent";
160} 161}
diff --git a/examples/mailtransportresource/mailtransport.h b/examples/mailtransportresource/mailtransport.h
index 2eb30a0..6cd3452 100644
--- a/examples/mailtransportresource/mailtransport.h
+++ b/examples/mailtransportresource/mailtransport.h
@@ -24,5 +24,5 @@
24 24
25namespace MailTransport 25namespace MailTransport
26{ 26{
27 void sendMessage(const KMime::Message::Ptr &message, const QByteArray &server, const QByteArray &username, const QByteArray &password, const QByteArray &cacert); 27 bool sendMessage(const KMime::Message::Ptr &message, const QByteArray &server, const QByteArray &username, const QByteArray &password, const QByteArray &cacert);
28}; 28};
diff --git a/examples/mailtransportresource/mailtransportresource.cpp b/examples/mailtransportresource/mailtransportresource.cpp
index 3b8dfd0..e8a15ee 100644
--- a/examples/mailtransportresource/mailtransportresource.cpp
+++ b/examples/mailtransportresource/mailtransportresource.cpp
@@ -20,6 +20,196 @@
20#include "mailtransportresource.h" 20#include "mailtransportresource.h"
21#include "facade.h" 21#include "facade.h"
22#include "facadefactory.h" 22#include "facadefactory.h"
23#include "resourceconfig.h"
24#include "definitions.h"
25#include "domainadaptor.h"
26#include "sourcewriteback.h"
27#include <QDir>
28#include <QFileInfo>
29#include <QSettings>
30#include <QStandardPaths>
31#include <QUuid>
32#include <KMime/Message>
33
34#include "resultprovider.h"
35#include "mailtransport.h"
36#include "mail_generated.h"
37#include <synchronizer.h>
38#include <log.h>
39#include <resourceconfig.h>
40#include <pipeline.h>
41
42#define ENTITY_TYPE_MAIL "mail"
43
44using namespace Sink;
45
46class MimeMessageMover : public Sink::EntityPreprocessor<ApplicationDomain::Mail>
47{
48public:
49 MimeMessageMover(const QByteArray &resourceInstanceIdentifier) : Sink::EntityPreprocessor<ApplicationDomain::Mail>(), mResourceInstanceIdentifier(resourceInstanceIdentifier) {}
50
51 QString moveMessage(const QString &oldPath, const Sink::ApplicationDomain::Mail &mail)
52 {
53 const auto directory = Sink::resourceStorageLocation(mResourceInstanceIdentifier);
54 const auto filePath = directory + "/" + mail.identifier();
55 if (oldPath != filePath) {
56 if (!QDir().mkpath(directory)) {
57 Warning() << "Failed to create the directory: " << directory;
58 }
59 QFile::remove(filePath);
60 QFile origFile(oldPath);
61 if (!origFile.open(QIODevice::ReadWrite)) {
62 Warning() << "Failed to open the original file with write rights: " << origFile.errorString();
63 }
64 if (!origFile.rename(filePath)) {
65 Warning() << "Failed to move the file from: " << oldPath << " to " << filePath << ". " << origFile.errorString();
66 }
67 origFile.close();
68 return filePath;
69 }
70 return oldPath;
71 }
72
73 void newEntity(Sink::ApplicationDomain::Mail &mail, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE
74 {
75 if (!mail.getMimeMessagePath().isEmpty()) {
76 mail.setMimeMessagePath(moveMessage(mail.getMimeMessagePath(), mail));
77 }
78 }
79
80 void modifiedEntity(const Sink::ApplicationDomain::Mail &oldMail, Sink::ApplicationDomain::Mail &newMail, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE
81 {
82 if (!newMail.getMimeMessagePath().isEmpty()) {
83 newMail.setMimeMessagePath(moveMessage(newMail.getMimeMessagePath(), newMail));
84 }
85 }
86
87 void deletedEntity(const Sink::ApplicationDomain::Mail &mail, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE
88 {
89 QFile::remove(mail.getMimeMessagePath());
90 }
91 QByteArray mResourceInstanceIdentifier;
92};
93
94static KAsync::Job<void>send(const ApplicationDomain::Mail &mail, const MailtransportResource::Settings &settings)
95{
96 const auto data = mail.getMimeMessage();
97 auto msg = KMime::Message::Ptr::create();
98 msg->setHead(KMime::CRLFtoLF(data));
99 msg->parse();
100 if (settings.testMode) {
101 Log() << "I would totally send that mail, but I'm in test mode.";
102 } else {
103 if (MailTransport::sendMessage(msg, settings.server.toUtf8(), settings.username.toUtf8(), settings.password.toUtf8(), settings.cacert.toUtf8())) {
104 Log() << "Sent message successfully";
105 } else {
106 Log() << "Failed to send message";
107 return KAsync::error<void>(1, "Failed to send the message.");
108 }
109 }
110 return KAsync::null<void>();
111}
112
113//TODO fold into synchronizer
114class MailtransportWriteback : public Sink::SourceWriteBack
115{
116public:
117 MailtransportWriteback(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier) : Sink::SourceWriteBack(resourceType, resourceInstanceIdentifier)
118 {
119
120 }
121
122 KAsync::Job<QByteArray> replay(const ApplicationDomain::Mail &mail, Sink::Operation operation, const QByteArray &oldRemoteId, const QList<QByteArray> &changedProperties) Q_DECL_OVERRIDE
123 {
124 if (operation == Sink::Operation_Creation) {
125 Trace() << "Dispatching message.";
126 // return send(mail, mSettings);
127 } else if (operation == Sink::Operation_Removal) {
128 } else if (operation == Sink::Operation_Modification) {
129 }
130 return KAsync::null<QByteArray>();
131 }
132
133public:
134 MailtransportResource::Settings mSettings;
135};
136
137class MailtransportSynchronizer : public Sink::Synchronizer {
138public:
139 MailtransportSynchronizer(const QByteArray &resourceType, const QByteArray &resourceInstanceIdentifier)
140 : Sink::Synchronizer(resourceType, resourceInstanceIdentifier)
141 {
142
143 }
144
145 KAsync::Job<void> synchronizeWithSource() Q_DECL_OVERRIDE
146 {
147 Log() << " Synchronizing";
148 return KAsync::start<void>([this](KAsync::Future<void> future) {
149 Sink::Query query;
150 QList<ApplicationDomain::Mail> toSend;
151 Log() << " Looking for mail";
152 store().reader<ApplicationDomain::Mail>().query(query, [&](const ApplicationDomain::Mail &mail) -> bool {
153 Trace() << "Found mail: " << mail.identifier();
154 // if (!mail.isSent()) {
155 toSend << mail;
156 // }
157 return true;
158 });
159 auto job = KAsync::null<void>();
160 for (const auto &m : toSend) {
161 job = job.then(send(m, mSettings)).then<void>([]() {
162 //on success, mark the mail as sent and move it to a separate place
163 //TODO
164 });
165 }
166 job = job.then<void>([&future]() {
167 future.setFinished();
168 },
169 [&future](int errorCode, const QString &errorString) {
170 future.setFinished();
171 });
172 job.exec();
173 });
174 }
175
176public:
177 QByteArray mResourceInstanceIdentifier;
178 MailtransportResource::Settings mSettings;
179};
180
181MailtransportResource::MailtransportResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline)
182 : Sink::GenericResource(PLUGIN_NAME, instanceIdentifier, pipeline)
183{
184 auto config = ResourceConfig::getConfiguration(instanceIdentifier);
185 mSettings = {config.value("server").toString(),
186 config.value("username").toString(),
187 config.value("cacert").toString(),
188 config.value("password").toString(),
189 config.value("testmode").toBool()
190 };
191
192 auto synchronizer = QSharedPointer<MailtransportSynchronizer>::create(PLUGIN_NAME, instanceIdentifier);
193 synchronizer->mSettings = mSettings;
194 setupSynchronizer(synchronizer);
195
196 auto changereplay = QSharedPointer<MailtransportWriteback>::create(PLUGIN_NAME, instanceIdentifier);
197 changereplay->mSettings = mSettings;
198 setupChangereplay(changereplay);
199
200 setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new MimeMessageMover(mResourceInstanceIdentifier));
201}
202
203void MailtransportResource::removeFromDisk(const QByteArray &instanceIdentifier)
204{
205 GenericResource::removeFromDisk(instanceIdentifier);
206 Sink::Storage(Sink::storageLocation(), instanceIdentifier + ".synchronization", Sink::Storage::ReadWrite).removeFromDisk();
207}
208
209KAsync::Job<void> MailtransportResource::inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue)
210{
211 return KAsync::null<void>();
212}
23 213
24MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent) 214MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent)
25 : Sink::ResourceFactory(parent) 215 : Sink::ResourceFactory(parent)
@@ -29,12 +219,15 @@ MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent)
29 219
30Sink::Resource *MailtransportResourceFactory::createResource(const QByteArray &instanceIdentifier) 220Sink::Resource *MailtransportResourceFactory::createResource(const QByteArray &instanceIdentifier)
31{ 221{
32 ErrorMsg() << "The mailtransport resource has no synchronizer process: " << instanceIdentifier; 222 return new MailtransportResource(instanceIdentifier);
33 return nullptr;
34} 223}
35 224
36void MailtransportResourceFactory::registerFacades(Sink::FacadeFactory &factory) 225void MailtransportResourceFactory::registerFacades(Sink::FacadeFactory &factory)
37{ 226{
38 factory.registerFacade<Sink::ApplicationDomain::Mail, MailtransportFacade>(PLUGIN_NAME); 227 factory.registerFacade<ApplicationDomain::Mail, DefaultFacade<ApplicationDomain::Mail, DomainTypeAdaptorFactory<ApplicationDomain::Mail>>>(PLUGIN_NAME);
39} 228}
40 229
230void MailtransportResourceFactory::registerAdaptorFactories(Sink::AdaptorFactoryRegistry &registry)
231{
232 registry.registerFactory<Sink::ApplicationDomain::Mail, DomainTypeAdaptorFactory<ApplicationDomain::Mail>>(PLUGIN_NAME);
233}
diff --git a/examples/mailtransportresource/mailtransportresource.h b/examples/mailtransportresource/mailtransportresource.h
index 2ccca0a..6622ea6 100644
--- a/examples/mailtransportresource/mailtransportresource.h
+++ b/examples/mailtransportresource/mailtransportresource.h
@@ -20,10 +20,29 @@
20#pragma once 20#pragma once
21 21
22#include "common/resource.h" 22#include "common/resource.h"
23#include "common/genericresource.h"
23 24
24//TODO: a little ugly to have this in two places, once here and once in Q_PLUGIN_METADATA 25//TODO: a little ugly to have this in two places, once here and once in Q_PLUGIN_METADATA
25#define PLUGIN_NAME "org.kde.mailtransport" 26#define PLUGIN_NAME "org.kde.mailtransport"
26 27
28class MailtransportResource : public Sink::GenericResource
29{
30public:
31 MailtransportResource(const QByteArray &instanceIdentifier, const QSharedPointer<Sink::Pipeline> &pipeline = QSharedPointer<Sink::Pipeline>());
32 KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE;
33 static void removeFromDisk(const QByteArray &instanceIdentifier);
34
35 struct Settings {
36 QString server;
37 QString username;
38 QString cacert;
39 QString password;
40 bool testMode;
41 };
42private:
43 Settings mSettings;
44};
45
27class MailtransportResourceFactory : public Sink::ResourceFactory 46class MailtransportResourceFactory : public Sink::ResourceFactory
28{ 47{
29 Q_OBJECT 48 Q_OBJECT
@@ -35,5 +54,6 @@ public:
35 54
36 Sink::Resource *createResource(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE; 55 Sink::Resource *createResource(const QByteArray &instanceIdentifier) Q_DECL_OVERRIDE;
37 void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE; 56 void registerFacades(Sink::FacadeFactory &factory) Q_DECL_OVERRIDE;
57 void registerAdaptorFactories(Sink::AdaptorFactoryRegistry &registry) Q_DECL_OVERRIDE;
38}; 58};
39 59
diff --git a/examples/mailtransportresource/tests/CMakeLists.txt b/examples/mailtransportresource/tests/CMakeLists.txt
new file mode 100644
index 0000000..458b462
--- /dev/null
+++ b/examples/mailtransportresource/tests/CMakeLists.txt
@@ -0,0 +1,11 @@
1set(CMAKE_AUTOMOC ON)
2include_directories(
3 ${CMAKE_CURRENT_BINARY_DIR}
4)
5
6include(SinkTest)
7
8auto_tests (
9 mailtransporttest
10)
11target_link_libraries(mailtransporttest sink_resource_mailtransport)
diff --git a/examples/mailtransportresource/tests/mailtransporttest.cpp b/examples/mailtransportresource/tests/mailtransporttest.cpp
new file mode 100644
index 0000000..564b4cb
--- /dev/null
+++ b/examples/mailtransportresource/tests/mailtransporttest.cpp
@@ -0,0 +1,94 @@
1#include <QtTest>
2
3#include "tests/testutils.h"
4#include "../mailtransport.h"
5
6#include "common/test.h"
7#include "common/store.h"
8#include "common/resourcecontrol.h"
9#include "common/domain/applicationdomaintype.h"
10#include "common/log.h"
11
12using namespace Sink;
13using namespace Sink::ApplicationDomain;
14
15class MailtransportTest : public QObject
16{
17 Q_OBJECT
18
19 Sink::ApplicationDomain::SinkResource createResource()
20 {
21 auto resource = ApplicationDomain::MailtransportResource::create("account1");
22 resource.setProperty("server", "localhost");
23 // resource.setProperty("port", 993);
24 resource.setProperty("user", "doe");
25 resource.setProperty("password", "doe");
26 resource.setProperty("testmode", true);
27 return resource;
28 }
29
30 void removeResourceFromDisk(const QByteArray &identifier)
31 {
32 // ::MailtransportResource::removeFromDisk(identifier);
33 }
34 QByteArray mResourceInstanceIdentifier;
35
36private slots:
37
38 void initTestCase()
39 {
40 Test::initTest();
41 Log::setDebugOutputLevel(Sink::Log::Trace);
42 // resetTestEnvironment();
43 auto resource = createResource();
44 QVERIFY(!resource.identifier().isEmpty());
45 VERIFYEXEC(Store::create(resource));
46 mResourceInstanceIdentifier = resource.identifier();
47 // mCapabilities = resource.getProperty("capabilities").value<QByteArrayList>();
48 qWarning() << "FOooooooooooooooooooo";
49 }
50
51 void cleanup()
52 {
53 // VERIFYEXEC(ResourceControl::shutdown(mResourceInstanceIdentifier));
54 // removeResourceFromDisk(mResourceInstanceIdentifier);
55 }
56
57 void init()
58 {
59 // qDebug();
60 // qDebug() << "-----------------------------------------";
61 // qDebug();
62 // VERIFYEXEC(ResourceControl::start(mResourceInstanceIdentifier));
63 }
64
65 void testSendMail()
66 {
67 auto message = KMime::Message::Ptr::create();
68 message->subject(true)->fromUnicodeString(QString::fromLatin1("Foobar"), "utf8");
69 message->assemble();
70
71 auto mail = ApplicationDomain::Mail::create(mResourceInstanceIdentifier);
72 mail.setMimeMessage(message->encodedContent());
73
74 VERIFYEXEC(Store::create(mail));
75 VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
76 VERIFYEXEC(Store::synchronize(Query::ResourceFilter(mResourceInstanceIdentifier)));
77
78 //TODO verify the mail has been sent
79
80 // auto modifiedMail = Store::readOne<ApplicationDomain::Mail>(Query::IdentityFilter(mail));
81 // VERIFYEXEC(Store::modify(modifiedMail));
82 // VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier));
83 // VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier));
84
85 }
86
87 //TODO test mail that fails to be sent. add a special header to the mail and have the resource fail sending. Ensure we can modify the mail to fix sending of the message.
88
89};
90
91
92QTEST_MAIN(MailtransportTest)
93
94#include "mailtransporttest.moc"