/* * Copyright (C) 2016 Christian Mollekopf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "mailtest.h" #include #include #include #include "store.h" #include "resourcecontrol.h" #include "log.h" #include "test.h" using namespace Sink; using namespace Sink::ApplicationDomain; void MailTest::initTestCase() { Test::initTest(); QVERIFY(isBackendAvailable()); resetTestEnvironment(); auto resource = createResource(); QVERIFY(!resource.getResourceType().isEmpty()); QVERIFY(!resource.identifier().isEmpty()); VERIFYEXEC(Store::create(resource)); mResourceInstanceIdentifier = resource.identifier(); //Load the capabilities resource = Store::readOne(Sink::Query{resource}); mCapabilities = resource.getCapabilities(); } void MailTest::cleanup() { VERIFYEXEC(Store::removeDataFromDisk(mResourceInstanceIdentifier)); } void MailTest::init() { VERIFYEXEC(ResourceControl::start(mResourceInstanceIdentifier)); } void MailTest::testCreateModifyDeleteFolder() { int baseCount = 0; //First figure out how many folders we have by default { auto job = Store::fetchAll(Query()) .then([&](const QList &folders) { baseCount = folders.size(); }); VERIFYEXEC(job); } QString name = "name"; QByteArray icon = "icon"; auto folder = Folder::create(mResourceInstanceIdentifier); folder.setName(name); folder.setIcon(icon); VERIFYEXEC(Store::create(folder)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); { auto job = Store::fetchAll(Query().request().request()) .then([=](const QList &folders) { QCOMPARE(folders.size(), baseCount + 1); QHash foldersByName; for (const auto &folder : folders) { foldersByName.insert(folder->getName(), folder); } QVERIFY(foldersByName.contains(name)); auto folder = *foldersByName.value(name); QCOMPARE(folder.getName(), name); QCOMPARE(folder.getIcon(), icon); }); VERIFYEXEC(job); } VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(folder, true))); if (!mCapabilities.contains("-folder.rename")) { QString name2 = "name2"; QByteArray icon2 = "icon2"; folder.setName(name2); folder.setIcon(icon2); VERIFYEXEC(Store::modify(folder)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); { auto job = Store::fetchAll(Query().request().request()) .then([=](const QList &folders) { QCOMPARE(folders.size(), baseCount + 1); QHash foldersByName; for (const auto &folder : folders) { foldersByName.insert(folder->getName(), folder); } QVERIFY(foldersByName.contains(name2)); auto folder = *foldersByName.value(name2); QCOMPARE(folder.getName(), name2); QCOMPARE(folder.getIcon(), icon2); }); VERIFYEXEC(job); } VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(folder, true))); } VERIFYEXEC(Store::remove(folder)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); { auto job = Store::fetchAll(Query().request().request()) .then([=](const QList &folders) { QCOMPARE(folders.size(), baseCount); }); VERIFYEXEC(job); } VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)); //This is not currently possible to check. The local folder and mapping has already been removed. // VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(folder, false))); } void MailTest::testCreateModifyDeleteMail() { const auto subject = QString::fromLatin1("Foobar"); auto folder = Folder::create(mResourceInstanceIdentifier); folder.setName("folder"); VERIFYEXEC(Store::create(folder)); auto message = KMime::Message::Ptr::create(); message->subject(true)->fromUnicodeString(subject, "utf8"); message->assemble(); auto mail = Mail::create(mResourceInstanceIdentifier); mail.setMimeMessage(message->encodedContent(true)); mail.setFolder(folder); VERIFYEXEC(Store::create(mail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); { auto job = Store::fetchAll(Query().request().request().request()) .then([=](const QList &mails) { QCOMPARE(mails.size(), 1); auto mail = *mails.first(); QCOMPARE(mail.getSubject(), subject); QCOMPARE(mail.getFolder(), folder.identifier()); QVERIFY(QFile(mail.getMimeMessagePath()).exists()); KMime::Message m; m.setContent(KMime::CRLFtoLF(mail.getMimeMessage())); m.parse(); QCOMPARE(m.subject(true)->asUnicodeString(), subject); }); VERIFYEXEC(job); } VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(mail, true))); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::PropertyInspection(mail, Mail::Subject::name, subject))); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::CacheIntegrityInspection(folder))); const auto subject2 = QString::fromLatin1("Foobar2"); auto message2 = KMime::Message::Ptr::create(); message2->subject(true)->fromUnicodeString(subject2, "utf8"); message2->assemble(); mail.setMimeMessage(message2->encodedContent(true)); VERIFYEXEC(Store::modify(mail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); { auto job = Store::fetchAll(Query().request().request().request()) .then([=](const QList &mails) { QCOMPARE(mails.size(), 1); auto mail = *mails.first(); QCOMPARE(mail.getSubject(), subject2); QCOMPARE(mail.getFolder(), folder.identifier()); QVERIFY(QFile(mail.getMimeMessagePath()).exists()); KMime::Message m; m.setContent(KMime::CRLFtoLF(mail.getMimeMessage())); m.parse(); QCOMPARE(m.subject(true)->asUnicodeString(), subject2); }); VERIFYEXEC(job); } VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(mail, true))); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::PropertyInspection(mail, Mail::Subject::name, subject2))); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::CacheIntegrityInspection(folder))); VERIFYEXEC(Store::remove(mail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); { auto job = Store::fetchAll(Query().request().request()) .then([=](const QList &mails) { QCOMPARE(mails.size(), 0); }); VERIFYEXEC(job); } VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)); // VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(mail, false))); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::CacheIntegrityInspection(folder))); } void MailTest::testMoveMail() { const auto subject = QString::fromLatin1("Foobar"); auto folder = Folder::create(mResourceInstanceIdentifier); folder.setName("folder2"); VERIFYEXEC(Store::create(folder)); auto folder1 = Folder::create(mResourceInstanceIdentifier); folder1.setName("folder3"); VERIFYEXEC(Store::create(folder1)); auto message = KMime::Message::Ptr::create(); message->subject(true)->fromUnicodeString(subject, "utf8"); message->assemble(); auto mail = Mail::create(mResourceInstanceIdentifier); mail.setMimeMessage(message->encodedContent(true)); mail.setFolder(folder); VERIFYEXEC(Store::create(mail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); Mail modifiedMail; { auto job = Store::fetchAll(Query().request().request().request()) .then([=, &modifiedMail](const QList &mails) { QCOMPARE(mails.size(), 1); auto mail = *mails.first(); modifiedMail = mail; QCOMPARE(mail.getFolder(), folder.identifier()); SinkWarning() << "path: " << mail.getMimeMessagePath(); QVERIFY(QFile(mail.getMimeMessagePath()).exists()); }); VERIFYEXEC(job); } VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::CacheIntegrityInspection(folder))); modifiedMail.setFolder(folder1); VERIFYEXEC(Store::modify(modifiedMail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); { auto job = Store::fetchAll(Query().request().request().request()) .then([=](const QList &mails) { QCOMPARE(mails.size(), 1); auto mail = *mails.first(); QCOMPARE(mail.getFolder(), folder1.identifier()); QVERIFY(QFile(mail.getMimeMessagePath()).exists()); SinkTrace() << "Mime message path: " << mail.getMimeMessagePath(); }); VERIFYEXEC(job); } VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::CacheIntegrityInspection(folder))); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::CacheIntegrityInspection(folder1))); } void MailTest::testMarkMailAsRead() { auto folder = Folder::create(mResourceInstanceIdentifier); folder.setName("anotherfolder"); VERIFYEXEC(Store::create(folder)); auto message = KMime::Message::Ptr::create(); message->subject(true)->fromUnicodeString("subject", "utf8"); message->assemble(); auto mail = Mail::create(mResourceInstanceIdentifier); mail.setMimeMessage(message->encodedContent(true)); mail.setFolder(folder); mail.setUnread(true); VERIFYEXEC(Store::create(mail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); auto job = Store::fetchAll(Query() .resourceFilter(mResourceInstanceIdentifier) .request() .request() ) .then>([this](const QList &mails) { ASYNCCOMPARE(mails.size(), 1); auto mail = mails.first(); mail->setUnread(false); return Store::modify(*mail) .then(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)) // The change needs to be replayed already .then(ResourceControl::inspect(ResourceControl::Inspection::PropertyInspection(*mail, Mail::Unread::name, false))) .then(ResourceControl::inspect(ResourceControl::Inspection::PropertyInspection(*mail, Mail::Subject::name, mail->getSubject()))); }); VERIFYEXEC(job); // Verify that we can still query for all relevant information auto job2 = Store::fetchAll(Query() .resourceFilter(mResourceInstanceIdentifier) .request() .request() .request() .request() ) .then>([](const QList &mails) { ASYNCCOMPARE(mails.size(), 1); auto mail = mails.first(); ASYNCVERIFY(!mail->getSubject().isEmpty()); ASYNCCOMPARE(mail->getUnread(), false); ASYNCVERIFY(QFileInfo(mail->getMimeMessagePath()).exists()); return KAsync::null(); }); VERIFYEXEC(job2); } void MailTest::testCreateDraft() { if (!mCapabilities.contains(ResourceCapabilities::Mail::drafts)) { QSKIP("Resource doesn't have the drafts capability"); } auto message = KMime::Message::Ptr::create(); message->subject(true)->fromUnicodeString(QString::fromLatin1("Foobar"), "utf8"); message->assemble(); auto mail = ApplicationDomain::Mail::create(mResourceInstanceIdentifier); mail.setMimeMessage(message->encodedContent(true)); mail.setDraft(true); VERIFYEXEC(Store::create(mail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); QByteArray folderIdentifier; auto createdDraft = Store::readOne(Query(mail).request()); folderIdentifier = createdDraft.getFolder(); QVERIFY(!folderIdentifier.isEmpty()); //Ensure we can also query by folder { auto mails = Store::read(Query().filter(folderIdentifier)); bool found = false; for (const auto &m : mails) { if (m.identifier() == mail.identifier()) { found = true; } } QVERIFY(found); } //Ensure the folder is also existing { ApplicationDomain::Folder folder; auto folders = Store::read(Query().filter(folderIdentifier)); QCOMPARE(folders.size(), 1); folder = folders.first(); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(folder, true))); } VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(mail, true))); } void MailTest::testModifyMailToDraft() { if (!mCapabilities.contains(ResourceCapabilities::Mail::drafts)) { QSKIP("Resource doesn't have the drafts capability"); } auto folder = Folder::create(mResourceInstanceIdentifier); folder.setName("sdljldskjf"); VERIFYEXEC(Store::create(folder)); auto message = KMime::Message::Ptr::create(); message->subject(true)->fromUnicodeString(QString::fromLatin1("Foobar"), "utf8"); message->assemble(); auto mail = ApplicationDomain::Mail::create(mResourceInstanceIdentifier); mail.setMimeMessage(message->encodedContent(true)); mail.setDraft(false); mail.setFolder(folder); VERIFYEXEC(Store::create(mail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); auto modifiedMail = Store::readOne(Query(mail)); modifiedMail.setDraft(true); VERIFYEXEC(Store::modify(modifiedMail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)); QByteArray folderIdentifier; { auto createdDraft = Store::readOne(Query(mail).request()); folderIdentifier = createdDraft.getFolder(); QVERIFY(!folderIdentifier.isEmpty()); } //Ensure the folder is also existing { ApplicationDomain::Folder folder; auto folders = Store::read(Query().filter(folderIdentifier).request()); QCOMPARE(folders.size(), 1); folder = folders.first(); QVERIFY(folder.getSpecialPurpose().contains("drafts")); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(folder, true))); } VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(mail, true))); } void MailTest::testModifyMailToTrash() { if (!mCapabilities.contains(ResourceCapabilities::Mail::trash)) { QSKIP("Resource doesn't have the trash capability"); } auto folder = Folder::create(mResourceInstanceIdentifier); folder.setName("sdljldskjf2"); VERIFYEXEC(Store::create(folder)); auto message = KMime::Message::Ptr::create(); message->subject(true)->fromUnicodeString(QString::fromLatin1("Foobar"), "utf8"); message->assemble(); auto mail = ApplicationDomain::Mail::create(mResourceInstanceIdentifier); mail.setMimeMessage(message->encodedContent(true)); mail.setTrash(false); mail.setFolder(folder); VERIFYEXEC(Store::create(mail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); auto modifiedMail = Store::readOne(Query(mail)); modifiedMail.setTrash(true); VERIFYEXEC(Store::modify(modifiedMail)); VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); VERIFYEXEC(ResourceControl::flushReplayQueue(QByteArrayList() << mResourceInstanceIdentifier)); QByteArray folderIdentifier; { auto createdMail = Store::readOne(Query(mail).request()); folderIdentifier = createdMail.getFolder(); QVERIFY(!folderIdentifier.isEmpty()); } //Ensure the folder is also existing { ApplicationDomain::Folder folder; auto folders = Store::read(Query().filter(folderIdentifier).request()); QCOMPARE(folders.size(), 1); folder = folders.first(); QVERIFY(folder.getSpecialPurpose().contains("trash")); VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(folder, true))); } VERIFYEXEC(ResourceControl::inspect(ResourceControl::Inspection::ExistenceInspection(mail, true))); } #include "mailtest.moc"