summaryrefslogtreecommitdiffstats
path: root/framework/domain
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-05-03 20:24:09 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-05-03 20:24:26 +0200
commite06e1dad4a4570e5c1181d05ab6ed7a5d74c6c91 (patch)
treeef606d36ee693eff087292a1950fe122a7376f19 /framework/domain
parent21f7851f044cd8b6e38c821ce12d7e1b291cae27 (diff)
downloadkube-e06e1dad4a4570e5c1181d05ab6ed7a5d74c6c91.tar.gz
kube-e06e1dad4a4570e5c1181d05ab6ed7a5d74c6c91.zip
A save-as-draft action & action results
This patch introduces tracking of actions, so they can be tested. It also provides a save-as-draft action, that looks for the draft folder, and stores the mail accordingly.
Diffstat (limited to 'framework/domain')
-rw-r--r--framework/domain/CMakeLists.txt4
-rw-r--r--framework/domain/actions/sinkactions.cpp101
-rw-r--r--framework/domain/actions/tests/CMakeLists.txt6
-rw-r--r--framework/domain/actions/tests/sinkactiontest.cpp60
-rw-r--r--framework/domain/composercontroller.cpp5
-rw-r--r--framework/domain/maillistmodel.cpp2
6 files changed, 125 insertions, 53 deletions
diff --git a/framework/domain/CMakeLists.txt b/framework/domain/CMakeLists.txt
index b3d47750..29385b39 100644
--- a/framework/domain/CMakeLists.txt
+++ b/framework/domain/CMakeLists.txt
@@ -27,7 +27,9 @@ include_directories(${CURL_INCLUDE_DIRS})
27add_library(mailplugin SHARED ${mailplugin_SRCS}) 27add_library(mailplugin SHARED ${mailplugin_SRCS})
28 28
29qt5_use_modules(mailplugin Core Quick Qml WebKitWidgets) 29qt5_use_modules(mailplugin Core Quick Qml WebKitWidgets)
30target_link_libraries(mailplugin actionplugin settingsplugin sink KF5::MimeTreeParser KF5::Codecs KF5::Package ${CURL_LIBRARIES}) 30target_link_libraries(mailplugin actionplugin settingsplugin sink KF5::MimeTreeParser KF5::Codecs KF5::Package KF5::Async ${CURL_LIBRARIES})
31
32add_subdirectory(actions/tests)
31 33
32install(TARGETS mailplugin DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) 34install(TARGETS mailplugin DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain)
33install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) 35install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain)
diff --git a/framework/domain/actions/sinkactions.cpp b/framework/domain/actions/sinkactions.cpp
index dea6fc72..5dbe623c 100644
--- a/framework/domain/actions/sinkactions.cpp
+++ b/framework/domain/actions/sinkactions.cpp
@@ -81,16 +81,7 @@ static ActionHandlerHelper sendMailHandler("org.kde.kube.actions.sendmail",
81 }, 81 },
82 [](Context *context) { 82 [](Context *context) {
83 auto accountId = context->property("accountId").value<QByteArray>(); 83 auto accountId = context->property("accountId").value<QByteArray>();
84 //For ssl use "smtps://mainserver.example.net
85 // QByteArray cacert; // = "/path/to/certificate.pem";
86 auto message = context->property("message").value<KMime::Message::Ptr>(); 84 auto message = context->property("message").value<KMime::Message::Ptr>();
87 auto mimeMessage = Sink::Store::getTemporaryFilePath();
88 QFile file(mimeMessage);
89 if (!file.open(QIODevice::ReadWrite)) {
90 qWarning() << "Failed to open the file: " << file.errorString() << mimeMessage;
91 return;
92 }
93 file.write(message->encodedContent());
94 qWarning() << "Sending a mail: "; 85 qWarning() << "Sending a mail: ";
95 86
96 Sink::Query query; 87 Sink::Query query;
@@ -98,53 +89,63 @@ static ActionHandlerHelper sendMailHandler("org.kde.kube.actions.sendmail",
98 query += Sink::Query::PropertyFilter("account", QVariant::fromValue(accountId)); 89 query += Sink::Query::PropertyFilter("account", QVariant::fromValue(accountId));
99 Sink::Store::fetchAll<Sink::ApplicationDomain::SinkResource>(query) 90 Sink::Store::fetchAll<Sink::ApplicationDomain::SinkResource>(query)
100 .then<void, QList<Sink::ApplicationDomain::SinkResource::Ptr>>([=](const QList<Sink::ApplicationDomain::SinkResource::Ptr> &resources) { 91 .then<void, QList<Sink::ApplicationDomain::SinkResource::Ptr>>([=](const QList<Sink::ApplicationDomain::SinkResource::Ptr> &resources) {
101 if (resources.isEmpty()) { 92 if (!resources.isEmpty()) {
102 qWarning() << "Failed to find a mailtransport resource";
103 } else {
104 auto resourceId = resources[0]->identifier(); 93 auto resourceId = resources[0]->identifier();
105 qDebug() << "Sending message via resource: " << resourceId; 94 qDebug() << "Sending message via resource: " << resourceId;
106 Sink::ApplicationDomain::Mail mail(resourceId); 95 Sink::ApplicationDomain::Mail mail(resourceId);
107 mail.setProperty("mimeMessage", mimeMessage); 96 mail.setBlobProperty("mimeMessage", message->encodedContent());
108 Sink::Store::create(mail).exec(); 97 return Sink::Store::create(mail);
109 // return Sink::Store::create(mail);
110 } 98 }
99 qWarning() << "Failed to find a mailtransport resource";
111 return KAsync::error<void>(0, "Failed to find a MailTransport resource."); 100 return KAsync::error<void>(0, "Failed to find a MailTransport resource.");
112 }).exec(); 101 }).exec();
113 } 102 }
114); 103);
115 104
116// static ActionHandlerHelper saveAsDraft("org.kde.kube.actions.save-as-draft", 105static ActionHandlerHelper saveAsDraft("org.kde.kube.actions.save-as-draft",
117// [](Context *context) -> bool { 106 [](Context *context) -> bool {
118// return context->property("mail").isValid(); 107 auto accountId = context->property("accountId").value<QByteArray>();
119// }, 108 auto message = context->property("message").value<KMime::Message::Ptr>();
120// [](Context *context) { 109 return !accountId.isEmpty() && message;
121// Sink::Query query; 110 },
122// query += Sink::Query::RequestedProperties(QByteArrayList() << "name") 111 ActionHandlerHelper::JobHandler([](Context *context) -> KAsync::Job<void> {
123// //FIXME do something like specialuse? 112 qWarning() << "executing save as draft";
124// query += Sink::Query::PropertyFilter("name", "Drafts"); 113 const auto accountId = context->property("accountId").value<QByteArray>();
125// // query += Sink::Query::PropertyContainsFilter("specialuser", "drafts"); 114 const auto message = context->property("message").value<KMime::Message::Ptr>();
126// query += Sink::Query::PropertyFilter("drafts", true); 115 auto existingMail = context->property("existingMail").value<Sink::ApplicationDomain::Mail>();
127// //TODO Use drafts folder of that specific account 116 if (!message) {
128// Sink::Store::fetchAll<Sink::ApplicationDomain::Folder>(query) 117 qWarning() << "Failed to get the mail: " << context->property("mail");
129// .then<void, QList<Sink::ApplicationDomain::Folder>>([](const QList<Sink::ApplicationDomain::Folder> folders) { 118 return KAsync::error<void>(1, "Failed to get the mail: " + context->property("mail").toString());
130// if (folders.isEmpty()) { 119 }
131// return KAsync::start([]() { 120
132// //If message is already existing, modify, otherwise create 121 if (existingMail.identifier().isEmpty()) {
133// }); 122 Sink::Query query;
134// } 123 query += Sink::Query::RequestedProperties(QByteArrayList() << "name");
135// }); 124 query += Sink::Query::PropertyContainsFilter("specialpurpose", "drafts");
136// //TODO 125 query += Sink::Query::AccountFilter(accountId);
137// // * Find drafts folder 126 qWarning() << "fetching the drafts folder";
138// // * Store KMime::Message on disk for use in blob property 127 return Sink::Store::fetchAll<Sink::ApplicationDomain::Folder>(query)
139// // * Check if message is already existing and either create or update 128 .then<void, QList<Sink::ApplicationDomain::Folder::Ptr>>([=](const QList<Sink::ApplicationDomain::Folder::Ptr> folders) {
140// // * 129 qWarning() << "fetched a drafts folder" << folders.size();
141// // auto mail = context->property("mail").value<Sink::ApplicationDomain::Mail::Ptr>(); 130 if (folders.isEmpty()) {
142// // if (!mail) { 131 return KAsync::error<void>(1, "Failed to find a drafts folder.");
143// // qWarning() << "Failed to get the mail mail: " << context->property("mail"); 132 }
144// // return; 133 if (folders.size() > 1) {
145// // } 134 qWarning() << "Found too many draft folders (taking the first): " << folders;
146// // mail->setProperty("unread", false); 135 }
147// // qDebug() << "Mark as read " << mail->identifier(); 136 const auto folder = folders.first();
148// // Sink::Store::modify(*mail).exec(); 137 Sink::ApplicationDomain::Mail mail(folder->resourceInstanceIdentifier());
149// } 138 mail.setProperty("folder", folder->identifier());
150// ); 139 mail.setBlobProperty("mimeMessage", message->encodedContent());
140 return Sink::Store::create(mail);
141 })
142 .then<void>([](){
143 qWarning() << "done";
144 });
145 } else {
146 qWarning() << "Modifying an existing mail";
147 existingMail.setBlobProperty("mimeMessage", message->encodedContent());
148 return Sink::Store::modify(existingMail);
149 }
150 })
151);
diff --git a/framework/domain/actions/tests/CMakeLists.txt b/framework/domain/actions/tests/CMakeLists.txt
new file mode 100644
index 00000000..dc9d01b1
--- /dev/null
+++ b/framework/domain/actions/tests/CMakeLists.txt
@@ -0,0 +1,6 @@
1include_directories(${CMAKE_CURRENT_BINARY_DIR})
2cmake_policy(SET CMP0063 NEW)
3add_executable(sinkactiontest sinkactiontest.cpp)
4add_test(sinkactiontest sinkactiontest)
5qt5_use_modules(sinkactiontest Core Test Concurrent)
6target_link_libraries(sinkactiontest sink actionplugin KF5::Mime mailplugin)
diff --git a/framework/domain/actions/tests/sinkactiontest.cpp b/framework/domain/actions/tests/sinkactiontest.cpp
new file mode 100644
index 00000000..3e4567fd
--- /dev/null
+++ b/framework/domain/actions/tests/sinkactiontest.cpp
@@ -0,0 +1,60 @@
1#include <QTest>
2#include <QDebug>
3#include <QSignalSpy>
4#include <sink/test.h>
5#include <sink/store.h>
6#include <sink/log.h>
7#include <KMime/Message>
8
9#include <actions/action.h>
10#include <actions/context.h>
11
12using namespace Sink;
13
14class SinkActionTest : public QObject
15{
16 Q_OBJECT
17private slots:
18
19 void initTestCase()
20 {
21 Sink::Test::initTest();
22 Sink::Log::setDebugOutputLevel(Sink::Log::Trace);
23 }
24
25 void testSaveAsDraftFail()
26 {
27 Kube::Context context;
28 auto future = Kube::Action("org.kde.kube.actions.save-as-draft", context).execute();
29
30 QTRY_VERIFY(future.isDone());
31 //because of empty context
32 QVERIFY(future.error());
33 }
34
35 void testSaveAsDraftNew()
36 {
37 auto message = KMime::Message::Ptr::create();
38 message->subject(true)->fromUnicodeString(QString::fromLatin1("Foobar"), "utf8");
39 message->assemble();
40
41 auto &&account = Test::TestAccount::registerAccount();
42 auto folder = account.createEntity<ApplicationDomain::Folder>();
43 folder->setProperty("specialpurpose", QVariant::fromValue(QByteArrayList() << "drafts"));
44
45 Kube::Context context;
46 context.setProperty("message", QVariant::fromValue(message));
47 context.setProperty("accountId", QVariant::fromValue(account.identifier));
48 auto future = Kube::Action("org.kde.kube.actions.save-as-draft", context).execute();
49
50 QTRY_VERIFY(future.isDone());
51 QVERIFY(!future.error());
52 auto mails = account.entities<Sink::ApplicationDomain::Mail>();
53 QCOMPARE(mails.size(), 1);
54 auto mail = mails.first();
55 QCOMPARE(mail->getProperty("folder").toByteArray(), folder->identifier());
56 }
57};
58
59QTEST_GUILESS_MAIN(SinkActionTest)
60#include "sinkactiontest.moc"
diff --git a/framework/domain/composercontroller.cpp b/framework/domain/composercontroller.cpp
index bca90d33..0cf61442 100644
--- a/framework/domain/composercontroller.cpp
+++ b/framework/domain/composercontroller.cpp
@@ -185,9 +185,12 @@ void ComposerController::send()
185void ComposerController::saveAsDraft() 185void ComposerController::saveAsDraft()
186{ 186{
187 auto mail = assembleMessage(); 187 auto mail = assembleMessage();
188 auto currentAccountId = identityModel()->index(m_currentAccountIndex, 0).data(IdentitiesModel::AccountId).toByteArray();
189
188 Kube::Context context; 190 Kube::Context context;
189 context.setProperty("message", QVariant::fromValue(mail)); 191 context.setProperty("message", QVariant::fromValue(mail));
190 Kube::Action("org.kde.kube.actions.saveasdraft", context).execute(); 192 context.setProperty("accountId", QVariant::fromValue(currentAccountId));
193 Kube::Action("org.kde.kube.actions.save-as-draft", context).execute();
191 clear(); 194 clear();
192} 195}
193 196
diff --git a/framework/domain/maillistmodel.cpp b/framework/domain/maillistmodel.cpp
index 7cbc5587..2df3ecbc 100644
--- a/framework/domain/maillistmodel.cpp
+++ b/framework/domain/maillistmodel.cpp
@@ -111,10 +111,10 @@ void MailListModel::setParentFolder(const QVariant &parentFolder)
111 Sink::Query query; 111 Sink::Query query;
112 query.liveQuery = true; 112 query.liveQuery = true;
113 query.requestedProperties << "subject" << "sender" << "senderName" << "date" << "unread" << "important" << "folder"; 113 query.requestedProperties << "subject" << "sender" << "senderName" << "date" << "unread" << "important" << "folder";
114 query.propertyFilter.insert("folder", folder->identifier());
115 query.resources << folder->resourceInstanceIdentifier(); 114 query.resources << folder->resourceInstanceIdentifier();
116 query.sortProperty = "date"; 115 query.sortProperty = "date";
117 query.limit = 100; 116 query.limit = 100;
117 query += Sink::Query::PropertyFilter("folder", *folder);
118 qWarning() << "Running folder query: " << folder->resourceInstanceIdentifier() << folder->identifier(); 118 qWarning() << "Running folder query: " << folder->resourceInstanceIdentifier() << folder->identifier();
119 runQuery(query); 119 runQuery(query);
120} 120}