From e06e1dad4a4570e5c1181d05ab6ed7a5d74c6c91 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Tue, 3 May 2016 20:24:09 +0200 Subject: 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. --- framework/domain/actions/sinkactions.cpp | 101 +++++++++++----------- framework/domain/actions/tests/CMakeLists.txt | 6 ++ framework/domain/actions/tests/sinkactiontest.cpp | 60 +++++++++++++ 3 files changed, 117 insertions(+), 50 deletions(-) create mode 100644 framework/domain/actions/tests/CMakeLists.txt create mode 100644 framework/domain/actions/tests/sinkactiontest.cpp (limited to 'framework/domain/actions') 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", }, [](Context *context) { auto accountId = context->property("accountId").value(); - //For ssl use "smtps://mainserver.example.net - // QByteArray cacert; // = "/path/to/certificate.pem"; auto message = context->property("message").value(); - auto mimeMessage = Sink::Store::getTemporaryFilePath(); - QFile file(mimeMessage); - if (!file.open(QIODevice::ReadWrite)) { - qWarning() << "Failed to open the file: " << file.errorString() << mimeMessage; - return; - } - file.write(message->encodedContent()); qWarning() << "Sending a mail: "; Sink::Query query; @@ -98,53 +89,63 @@ static ActionHandlerHelper sendMailHandler("org.kde.kube.actions.sendmail", query += Sink::Query::PropertyFilter("account", QVariant::fromValue(accountId)); Sink::Store::fetchAll(query) .then>([=](const QList &resources) { - if (resources.isEmpty()) { - qWarning() << "Failed to find a mailtransport resource"; - } else { + if (!resources.isEmpty()) { auto resourceId = resources[0]->identifier(); qDebug() << "Sending message via resource: " << resourceId; Sink::ApplicationDomain::Mail mail(resourceId); - mail.setProperty("mimeMessage", mimeMessage); - Sink::Store::create(mail).exec(); - // return Sink::Store::create(mail); + mail.setBlobProperty("mimeMessage", message->encodedContent()); + return Sink::Store::create(mail); } + qWarning() << "Failed to find a mailtransport resource"; return KAsync::error(0, "Failed to find a MailTransport resource."); }).exec(); } ); -// static ActionHandlerHelper saveAsDraft("org.kde.kube.actions.save-as-draft", -// [](Context *context) -> bool { -// return context->property("mail").isValid(); -// }, -// [](Context *context) { -// Sink::Query query; -// query += Sink::Query::RequestedProperties(QByteArrayList() << "name") -// //FIXME do something like specialuse? -// query += Sink::Query::PropertyFilter("name", "Drafts"); -// // query += Sink::Query::PropertyContainsFilter("specialuser", "drafts"); -// query += Sink::Query::PropertyFilter("drafts", true); -// //TODO Use drafts folder of that specific account -// Sink::Store::fetchAll(query) -// .then>([](const QList folders) { -// if (folders.isEmpty()) { -// return KAsync::start([]() { -// //If message is already existing, modify, otherwise create -// }); -// } -// }); -// //TODO -// // * Find drafts folder -// // * Store KMime::Message on disk for use in blob property -// // * Check if message is already existing and either create or update -// // * -// // auto mail = context->property("mail").value(); -// // if (!mail) { -// // qWarning() << "Failed to get the mail mail: " << context->property("mail"); -// // return; -// // } -// // mail->setProperty("unread", false); -// // qDebug() << "Mark as read " << mail->identifier(); -// // Sink::Store::modify(*mail).exec(); -// } -// ); +static ActionHandlerHelper saveAsDraft("org.kde.kube.actions.save-as-draft", + [](Context *context) -> bool { + auto accountId = context->property("accountId").value(); + auto message = context->property("message").value(); + return !accountId.isEmpty() && message; + }, + ActionHandlerHelper::JobHandler([](Context *context) -> KAsync::Job { + qWarning() << "executing save as draft"; + const auto accountId = context->property("accountId").value(); + const auto message = context->property("message").value(); + auto existingMail = context->property("existingMail").value(); + if (!message) { + qWarning() << "Failed to get the mail: " << context->property("mail"); + return KAsync::error(1, "Failed to get the mail: " + context->property("mail").toString()); + } + + if (existingMail.identifier().isEmpty()) { + Sink::Query query; + query += Sink::Query::RequestedProperties(QByteArrayList() << "name"); + query += Sink::Query::PropertyContainsFilter("specialpurpose", "drafts"); + query += Sink::Query::AccountFilter(accountId); + qWarning() << "fetching the drafts folder"; + return Sink::Store::fetchAll(query) + .then>([=](const QList folders) { + qWarning() << "fetched a drafts folder" << folders.size(); + if (folders.isEmpty()) { + return KAsync::error(1, "Failed to find a drafts folder."); + } + if (folders.size() > 1) { + qWarning() << "Found too many draft folders (taking the first): " << folders; + } + const auto folder = folders.first(); + Sink::ApplicationDomain::Mail mail(folder->resourceInstanceIdentifier()); + mail.setProperty("folder", folder->identifier()); + mail.setBlobProperty("mimeMessage", message->encodedContent()); + return Sink::Store::create(mail); + }) + .then([](){ + qWarning() << "done"; + }); + } else { + qWarning() << "Modifying an existing mail"; + existingMail.setBlobProperty("mimeMessage", message->encodedContent()); + return Sink::Store::modify(existingMail); + } + }) +); 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 @@ +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +cmake_policy(SET CMP0063 NEW) +add_executable(sinkactiontest sinkactiontest.cpp) +add_test(sinkactiontest sinkactiontest) +qt5_use_modules(sinkactiontest Core Test Concurrent) +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 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace Sink; + +class SinkActionTest : public QObject +{ + Q_OBJECT +private slots: + + void initTestCase() + { + Sink::Test::initTest(); + Sink::Log::setDebugOutputLevel(Sink::Log::Trace); + } + + void testSaveAsDraftFail() + { + Kube::Context context; + auto future = Kube::Action("org.kde.kube.actions.save-as-draft", context).execute(); + + QTRY_VERIFY(future.isDone()); + //because of empty context + QVERIFY(future.error()); + } + + void testSaveAsDraftNew() + { + auto message = KMime::Message::Ptr::create(); + message->subject(true)->fromUnicodeString(QString::fromLatin1("Foobar"), "utf8"); + message->assemble(); + + auto &&account = Test::TestAccount::registerAccount(); + auto folder = account.createEntity(); + folder->setProperty("specialpurpose", QVariant::fromValue(QByteArrayList() << "drafts")); + + Kube::Context context; + context.setProperty("message", QVariant::fromValue(message)); + context.setProperty("accountId", QVariant::fromValue(account.identifier)); + auto future = Kube::Action("org.kde.kube.actions.save-as-draft", context).execute(); + + QTRY_VERIFY(future.isDone()); + QVERIFY(!future.error()); + auto mails = account.entities(); + QCOMPARE(mails.size(), 1); + auto mail = mails.first(); + QCOMPARE(mail->getProperty("folder").toByteArray(), folder->identifier()); + } +}; + +QTEST_GUILESS_MAIN(SinkActionTest) +#include "sinkactiontest.moc" -- cgit v1.2.3