diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-05-03 20:24:09 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-05-03 20:24:26 +0200 |
commit | e06e1dad4a4570e5c1181d05ab6ed7a5d74c6c91 (patch) | |
tree | ef606d36ee693eff087292a1950fe122a7376f19 /framework/domain | |
parent | 21f7851f044cd8b6e38c821ce12d7e1b291cae27 (diff) | |
download | kube-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.txt | 4 | ||||
-rw-r--r-- | framework/domain/actions/sinkactions.cpp | 101 | ||||
-rw-r--r-- | framework/domain/actions/tests/CMakeLists.txt | 6 | ||||
-rw-r--r-- | framework/domain/actions/tests/sinkactiontest.cpp | 60 | ||||
-rw-r--r-- | framework/domain/composercontroller.cpp | 5 | ||||
-rw-r--r-- | framework/domain/maillistmodel.cpp | 2 |
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}) | |||
27 | add_library(mailplugin SHARED ${mailplugin_SRCS}) | 27 | add_library(mailplugin SHARED ${mailplugin_SRCS}) |
28 | 28 | ||
29 | qt5_use_modules(mailplugin Core Quick Qml WebKitWidgets) | 29 | qt5_use_modules(mailplugin Core Quick Qml WebKitWidgets) |
30 | target_link_libraries(mailplugin actionplugin settingsplugin sink KF5::MimeTreeParser KF5::Codecs KF5::Package ${CURL_LIBRARIES}) | 30 | target_link_libraries(mailplugin actionplugin settingsplugin sink KF5::MimeTreeParser KF5::Codecs KF5::Package KF5::Async ${CURL_LIBRARIES}) |
31 | |||
32 | add_subdirectory(actions/tests) | ||
31 | 33 | ||
32 | install(TARGETS mailplugin DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) | 34 | install(TARGETS mailplugin DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) |
33 | install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kube/framework/domain) | 35 | install(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", | 105 | static 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 @@ | |||
1 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) | ||
2 | cmake_policy(SET CMP0063 NEW) | ||
3 | add_executable(sinkactiontest sinkactiontest.cpp) | ||
4 | add_test(sinkactiontest sinkactiontest) | ||
5 | qt5_use_modules(sinkactiontest Core Test Concurrent) | ||
6 | target_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 | |||
12 | using namespace Sink; | ||
13 | |||
14 | class SinkActionTest : public QObject | ||
15 | { | ||
16 | Q_OBJECT | ||
17 | private 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 | |||
59 | QTEST_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() | |||
185 | void ComposerController::saveAsDraft() | 185 | void 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 | } |