File indexing completed on 2024-05-12 05:10:40

0001 /*
0002     SPDX-FileCopyrightText: 2011 Sérgio Martins <iamsergio@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 // mailclient_p.cpp isn't exported so we include it directly.
0008 
0009 #include "mailclient_p.h"
0010 
0011 #include <Akonadi/ItemCreateJob>
0012 #include <Akonadi/MessageQueueJob>
0013 #include <KCalendarCore/FreeBusy>
0014 #include <KCalendarCore/Incidence>
0015 #include <KContacts/Addressee>
0016 #include <KIdentityManagementCore/Identity>
0017 #include <MessageComposer/ContactPreference>
0018 
0019 #include <gpgme++/context.h>
0020 #include <gpgme++/keylistresult.h>
0021 
0022 #include <akonadi/qtest_akonadi.h>
0023 
0024 #include <QObject>
0025 #include <QTestEventLoop>
0026 
0027 const QString s_ourEmail = QStringLiteral("unittests@dev.nul"); // change also in kdepimlibs/akonadi/calendar/tests/unittestenv/kdehome/share/config
0028 const auto s_ourGpgKey = QByteArray("7E501DEA81F62DB17389393325058D1857FDD0E7");
0029 
0030 const QString s_testEmail = QStringLiteral("test@example.com");
0031 const auto s_testGpgKey = QByteArray("D6003D89B2840A1B1888C39E5AB1CE1311F6B1DB");
0032 
0033 const QString s_test2Email = QStringLiteral("test2@example.com");
0034 const auto s_test2GpgKey = QByteArray("A9794D762BC67B1DEB161CDD8B3613B451672CB8");
0035 
0036 enum class CryptoState { Plain, Signed, Encrypted };
0037 
0038 struct ExpectedDialog {
0039     QString text;
0040     Akonadi::ITIPHandlerDialogDelegate::DialogAction action;
0041 };
0042 
0043 using ContactPreferences = QMap<QString, MessageComposer::ContactPreference>;
0044 
0045 using namespace Akonadi;
0046 
0047 Q_DECLARE_METATYPE(KCalendarCore::Incidence::Ptr)
0048 Q_DECLARE_METATYPE(CryptoState)
0049 Q_DECLARE_METATYPE(QList<ExpectedDialog>)
0050 Q_DECLARE_METATYPE(ContactPreferences)
0051 
0052 class FakeMessageQueueJob : public Akonadi::MessageQueueJob
0053 {
0054 public:
0055     explicit FakeMessageQueueJob(QObject *parent = nullptr)
0056         : Akonadi::MessageQueueJob(parent)
0057     {
0058     }
0059 
0060     void start() override
0061     {
0062         UnitTestResult unitTestResult;
0063         unitTestResult.message = message();
0064         unitTestResult.from = addressAttribute().from();
0065         unitTestResult.to = addressAttribute().to();
0066         unitTestResult.cc = addressAttribute().cc();
0067         unitTestResult.bcc = addressAttribute().bcc();
0068         unitTestResult.transportId = transportAttribute().transportId();
0069         FakeMessageQueueJob::sUnitTestResults << unitTestResult;
0070 
0071         setError(Akonadi::MailClient::ResultSuccess);
0072         setErrorText(QString());
0073 
0074         emitResult();
0075     }
0076 
0077     static UnitTestResult::List sUnitTestResults;
0078 };
0079 
0080 UnitTestResult::List FakeMessageQueueJob::sUnitTestResults;
0081 
0082 class FakeITIPHandlerDialogDelegate : public ITIPHandlerDialogDelegate
0083 {
0084 public:
0085     explicit FakeITIPHandlerDialogDelegate(const KCalendarCore::Incidence::Ptr &incidence, KCalendarCore::iTIPMethod method, QWidget *parent = nullptr)
0086         : ITIPHandlerDialogDelegate(incidence, method, parent)
0087     {
0088     }
0089 
0090     static QList<ExpectedDialog> expectedWarningTwoActionsCancelDialogs;
0091 
0092 protected:
0093     int warningTwoActionsCancel(const QString &text, const QString &title, const KGuiItem &, const KGuiItem &, const KGuiItem &) override
0094     {
0095         if (expectedWarningTwoActionsCancelDialogs.empty()) {
0096             QTest::qFail("Unexpected dialog - the testcase doesn't expect any dialog", __FILE__, __LINE__);
0097             qDebug() << "Dialog title:" << title;
0098             qDebug() << "Dialog text:" << text;
0099             return ITIPHandlerDialogDelegate::CancelAction;
0100         }
0101 
0102         const auto expected = expectedWarningTwoActionsCancelDialogs.front();
0103         expectedWarningTwoActionsCancelDialogs.erase(expectedWarningTwoActionsCancelDialogs.begin());
0104 
0105         if (!title.contains(expected.text) && !text.contains(expected.text)) {
0106             QTest::qFail("Mismatching dialog - the dialog text doesn't match the expected string", __FILE__, __LINE__);
0107             qDebug() << "Dialog title:" << title;
0108             qDebug() << "Dialog text:" << text;
0109             qDebug() << "Expected substring:" << expected.text;
0110             return ITIPHandlerDialogDelegate::CancelAction;
0111         }
0112 
0113         return expected.action;
0114     }
0115 };
0116 
0117 QList<ExpectedDialog> FakeITIPHandlerDialogDelegate::expectedWarningTwoActionsCancelDialogs;
0118 
0119 class FakeITIPHandlerComponentFactory : public ITIPHandlerComponentFactory
0120 {
0121 public:
0122     explicit FakeITIPHandlerComponentFactory(QObject *parent = nullptr)
0123         : ITIPHandlerComponentFactory(parent)
0124     {
0125     }
0126 
0127     Akonadi::MessageQueueJob *createMessageQueueJob(const KCalendarCore::IncidenceBase::Ptr &incidence,
0128                                                     const KIdentityManagementCore::Identity &identity,
0129                                                     QObject *parent = nullptr) override
0130     {
0131         Q_UNUSED(incidence)
0132         Q_UNUSED(identity)
0133         return new FakeMessageQueueJob(parent);
0134     }
0135 
0136     ITIPHandlerDialogDelegate *
0137     createITIPHanderDialogDelegate(const KCalendarCore::Incidence::Ptr &incidence, KCalendarCore::iTIPMethod method, QWidget *parent = nullptr) override
0138     {
0139         return new FakeITIPHandlerDialogDelegate(incidence, method, parent);
0140     }
0141 };
0142 
0143 class TestableMailClient : public MailClient
0144 {
0145 public:
0146     TestableMailClient(QObject *parent)
0147         : MailClient(new FakeITIPHandlerComponentFactory(parent), parent)
0148     {
0149         // Disable Akonadi contacts lookup - we ain't gonna find anything anyway,
0150         // since there's no indexer in the test env
0151         setAkonadiLookupEnabled(false);
0152     }
0153 
0154     static ContactPreferences preferences;
0155 
0156 private:
0157     std::optional<MessageComposer::ContactPreference> contactPreference(const QString &address) override
0158     {
0159         auto it = preferences.constFind(address);
0160         if (it != preferences.cend()) {
0161             return *it;
0162         }
0163 
0164         return {};
0165     }
0166 
0167     bool showKeyApprovalDialog() const override
0168     {
0169         return false; // no gui in tests!
0170     }
0171 };
0172 
0173 ContactPreferences TestableMailClient::preferences;
0174 
0175 static MessageComposer::ContactPreference
0176 createPreference(const QByteArray &key, Kleo::EncryptionPreference encPref, Kleo::SigningPreference sigPref = Kleo::UnknownSigningPreference)
0177 {
0178     MessageComposer::ContactPreference preference;
0179     preference.pgpKeyFingerprints.push_back(QString::fromLatin1(key));
0180     preference.encryptionPreference = encPref;
0181     preference.signingPreference = sigPref;
0182     preference.cryptoMessageFormat = Kleo::AnyOpenPGP;
0183     return preference;
0184 }
0185 
0186 class MailClientTest : public QObject
0187 {
0188     Q_OBJECT
0189 
0190 private:
0191     TestableMailClient *mMailClient = nullptr;
0192     int mPendingSignals;
0193     MailClient::Result mLastResult;
0194     QString mLastErrorMessage;
0195 
0196 private Q_SLOTS:
0197 
0198     void initTestCase()
0199     {
0200         AkonadiTest::checkTestIsIsolated();
0201 
0202         mPendingSignals = 0;
0203         mMailClient = new TestableMailClient(this);
0204         mLastResult = MailClient::ResultSuccess;
0205         connect(mMailClient, &MailClient::finished, this, &MailClientTest::handleFinished);
0206     }
0207 
0208     void cleanupTestCase()
0209     {
0210     }
0211 
0212     void testMailAttendees_data()
0213     {
0214         QTest::addColumn<KCalendarCore::Incidence::Ptr>("incidence");
0215         QTest::addColumn<KIdentityManagementCore::Identity>("identity");
0216         QTest::addColumn<bool>("bccMe");
0217         QTest::addColumn<QString>("attachment");
0218         QTest::addColumn<QString>("transport");
0219         QTest::addColumn<MailClient::Result>("expectedResult");
0220         QTest::addColumn<int>("expectedTransportId");
0221         QTest::addColumn<QString>("expectedFrom");
0222         QTest::addColumn<QStringList>("expectedToList");
0223         QTest::addColumn<QStringList>("expectedCcList");
0224         QTest::addColumn<QStringList>("expectedBccList");
0225         QTest::addColumn<CryptoState>("expectedCrypto");
0226         QTest::addColumn<QList<ExpectedDialog>>("expectedDialogs");
0227         QTest::addColumn<ContactPreferences>("contactPreferences");
0228 
0229         KCalendarCore::Incidence::Ptr incidence(new KCalendarCore::Event());
0230         KIdentityManagementCore::Identity identity;
0231         identity.setPrimaryEmailAddress(s_ourEmail);
0232 
0233         KIdentityManagementCore::Identity cryptoIdentity = identity;
0234         cryptoIdentity.setPGPSigningKey(s_ourGpgKey);
0235         cryptoIdentity.setPGPEncryptionKey(s_ourGpgKey);
0236         cryptoIdentity.setPgpAutoSign(true);
0237         cryptoIdentity.setPgpAutoEncrypt(true);
0238 
0239         bool bccMe = false;
0240         QString attachment;
0241         QString transport;
0242         MailClient::Result expectedResult = MailClient::ResultNoAttendees;
0243         const int expectedTransportId = 69372773; // from tests/unittestenv/kdehome/share/config/mailtransports
0244         const QString expectedFrom = s_ourEmail; // from tests/unittestenv/kdehome/share/config/emailidentities
0245         KCalendarCore::Person organizer(QStringLiteral("Organizer"), s_ourEmail);
0246 
0247         QStringList toList;
0248         QStringList toCcList;
0249         QStringList toBccList;
0250         //----------------------------------------------------------------------------------------------
0251         QTest::newRow("No attendees") << incidence << identity << bccMe << attachment << transport << expectedResult << -1 << QString() << toList << toCcList
0252                                       << toBccList << CryptoState::Plain << QList<ExpectedDialog>{} << ContactPreferences{};
0253         //----------------------------------------------------------------------------------------------
0254         // One attendee, but without e-mail
0255         KCalendarCore::Attendee attendee(QStringLiteral("name1"), QString());
0256         incidence = KCalendarCore::Incidence::Ptr(new KCalendarCore::Event());
0257         incidence->addAttendee(attendee);
0258         expectedResult = MailClient::ResultReallyNoAttendees;
0259         QTest::newRow("No attendees with email") << incidence << identity << bccMe << attachment << transport << expectedResult << -1 << QString() << toList
0260                                                  << toCcList << toBccList << CryptoState::Plain << QList<ExpectedDialog>{} << ContactPreferences{};
0261         //----------------------------------------------------------------------------------------------
0262         // One valid attendee
0263         attendee = KCalendarCore::Attendee(QStringLiteral("name1"), QStringLiteral("test@foo.org"));
0264         incidence = KCalendarCore::Incidence::Ptr(new KCalendarCore::Event());
0265         incidence->addAttendee(attendee);
0266         incidence->setOrganizer(organizer);
0267         expectedResult = MailClient::ResultSuccess;
0268         toList << QStringLiteral("test@foo.org");
0269         QTest::newRow("One attendee") << incidence << identity << bccMe << attachment << transport << expectedResult << expectedTransportId << expectedFrom
0270                                       << toList << toCcList << toBccList << CryptoState::Plain << QList<ExpectedDialog>{} << ContactPreferences{};
0271         //----------------------------------------------------------------------------------------------
0272         // One valid attendee
0273         attendee = KCalendarCore::Attendee(QStringLiteral("name1"), QStringLiteral("test@foo.org"));
0274         incidence = KCalendarCore::Incidence::Ptr(new KCalendarCore::Event());
0275         incidence->setOrganizer(organizer);
0276         incidence->addAttendee(attendee);
0277         QString invalidTransport = QStringLiteral("foo");
0278         expectedResult = MailClient::ResultSuccess;
0279         // Should default to the default transport
0280         QTest::newRow("Invalid transport") << incidence << identity << bccMe << attachment << invalidTransport << expectedResult << expectedTransportId
0281                                            << expectedFrom << toList << toCcList << toBccList << CryptoState::Plain << QList<ExpectedDialog>{}
0282                                            << ContactPreferences{};
0283 
0284         //----------------------------------------------------------------------------------------------
0285         // One valid attendee, identity wants to sign
0286         {
0287             auto ident = identity;
0288             ident.setPGPSigningKey(s_ourGpgKey);
0289             ident.setPgpAutoSign(true);
0290 
0291             QTest::newRow("One attendee, identity wants to sign")
0292                 << incidence << ident << bccMe << attachment << transport << expectedResult << expectedTransportId << expectedFrom << toList << toCcList
0293                 << toBccList << CryptoState::Signed << QList<ExpectedDialog>{} << ContactPreferences{};
0294         }
0295 
0296         //----------------------------------------------------------------------------------------------
0297         // One valid attendee, identity wants to encrypt
0298         {
0299             KCalendarCore::Incidence::Ptr inc{incidence->clone()};
0300             inc->clearAttendees();
0301             inc->addAttendee(KCalendarCore::Attendee({}, s_testEmail));
0302             // No crypto preference for the attendee
0303 
0304             QTest::newRow("One attendee, identity wants to encrypt")
0305                 << inc << cryptoIdentity << bccMe << attachment << transport << expectedResult << expectedTransportId << expectedFrom
0306                 << QStringList({s_testEmail}) << toCcList << toBccList << CryptoState::Encrypted << QList<ExpectedDialog>{} << ContactPreferences{};
0307         }
0308 
0309         //----------------------------------------------------------------------------------------------
0310         // One valid attendee, attendee wants to encrypt
0311         {
0312             auto ident = identity;
0313             ident.setPGPSigningKey(s_ourGpgKey);
0314             ident.setPGPEncryptionKey(s_ourGpgKey);
0315 
0316             KCalendarCore::Incidence::Ptr inc{incidence->clone()};
0317             inc->clearAttendees();
0318             inc->addAttendee(KCalendarCore::Attendee({}, s_testEmail));
0319 
0320             QTest::newRow("One attendee, attendee wants to encrypt")
0321                 << inc << ident << bccMe << attachment << transport << expectedResult << expectedTransportId << expectedFrom << QStringList({s_testEmail})
0322                 << toCcList << toBccList << CryptoState::Encrypted << QList<ExpectedDialog>{}
0323                 << ContactPreferences{{s_testEmail, createPreference(s_testGpgKey, Kleo::AlwaysEncrypt, Kleo::AlwaysSign)}};
0324         }
0325 
0326         //----------------------------------------------------------------------------------------------
0327         // Two attendees, one without key
0328         {
0329             auto ident = identity;
0330             ident.setPGPSigningKey(s_ourGpgKey);
0331             ident.setPGPEncryptionKey(s_ourGpgKey);
0332 
0333             KCalendarCore::Incidence::Ptr inc{incidence->clone()};
0334             inc->addAttendee(KCalendarCore::Attendee({}, s_testEmail));
0335 
0336             QTest::newRow("Two attendees, one wants encryption, one has no key")
0337                 << inc << ident << bccMe << attachment << transport << expectedResult << expectedTransportId << expectedFrom
0338                 << QStringList({QStringLiteral("test@foo.org"), s_testEmail}) << toCcList << toBccList << CryptoState::Plain
0339                 << QList<ExpectedDialog>{{QStringLiteral("conflicting encryption preferences"),
0340                                           ITIPHandlerDialogDelegate::SecondaryAction /* do not encrypt */}}
0341                 << ContactPreferences{{s_testEmail, createPreference(s_testGpgKey, Kleo::AlwaysEncrypt)}};
0342         }
0343 
0344         //----------------------------------------------------------------------------------------------
0345         // Two attendees, both have key but only one explicitly wants encryption - we should encrypt anyway
0346         {
0347             auto ident = identity;
0348             ident.setPGPSigningKey(s_ourGpgKey);
0349             ident.setPGPEncryptionKey(s_ourGpgKey);
0350 
0351             KCalendarCore::Incidence::Ptr inc{incidence->clone()};
0352             inc->clearAttendees();
0353             inc->addAttendee(KCalendarCore::Attendee({}, s_testEmail));
0354             inc->addAttendee(KCalendarCore::Attendee({}, s_test2Email));
0355 
0356             QTest::newRow("Two attendees, both have keys but only one explicitly wants encryption")
0357                 << inc << ident << bccMe << attachment << transport << expectedResult << expectedTransportId << expectedFrom
0358                 << QStringList({s_testEmail, s_test2Email}) << toCcList << toBccList << CryptoState::Encrypted << QList<ExpectedDialog>{}
0359                 << ContactPreferences{{s_test2Email, createPreference(s_test2GpgKey, Kleo::AlwaysEncrypt)}};
0360         }
0361 
0362         //----------------------------------------------------------------------------------------------
0363         // One valid attendee, and bcc me
0364         attendee = KCalendarCore::Attendee(QStringLiteral("name1"), QStringLiteral("test@foo.org"));
0365         incidence = KCalendarCore::Incidence::Ptr(new KCalendarCore::Event());
0366         incidence->setOrganizer(organizer);
0367         incidence->addAttendee(attendee);
0368         expectedResult = MailClient::ResultSuccess;
0369         // Should default to the default transport
0370         toBccList.clear();
0371         toBccList << s_ourEmail;
0372         QTest::newRow("Test bcc") << incidence << identity << /*bccMe*/ true << attachment << transport << expectedResult << expectedTransportId << expectedFrom
0373                                   << toList << toCcList << toBccList << CryptoState::Plain << QList<ExpectedDialog>{} << ContactPreferences{};
0374         //----------------------------------------------------------------------------------------------
0375         // Test CC list
0376         attendee = KCalendarCore::Attendee(QStringLiteral("name1"), QStringLiteral("test@foo.org"));
0377         KCalendarCore::Attendee optionalAttendee(QStringLiteral("opt"), QStringLiteral("optional@foo.org"));
0378         KCalendarCore::Attendee nonParticipant(QStringLiteral("non"), QStringLiteral("non@foo.org"));
0379         optionalAttendee.setRole(KCalendarCore::Attendee::OptParticipant);
0380         nonParticipant.setRole(KCalendarCore::Attendee::NonParticipant);
0381         incidence = KCalendarCore::Incidence::Ptr(new KCalendarCore::Event());
0382         incidence->setOrganizer(organizer);
0383         incidence->addAttendee(attendee);
0384         incidence->addAttendee(optionalAttendee);
0385         incidence->addAttendee(nonParticipant);
0386         expectedResult = MailClient::ResultSuccess;
0387         // Should default to the default transport
0388         toBccList.clear();
0389         toBccList << s_ourEmail;
0390 
0391         toCcList.clear();
0392         toCcList << QStringLiteral("optional@foo.org") << QStringLiteral("non@foo.org");
0393         QTest::newRow("Test cc") << incidence << identity << /*bccMe*/ true << attachment << transport << expectedResult << expectedTransportId << expectedFrom
0394                                  << toList << toCcList << toBccList << CryptoState::Plain << QList<ExpectedDialog>{} << ContactPreferences{};
0395     }
0396 
0397     void testMailAttendees()
0398     {
0399         QFETCH(KCalendarCore::Incidence::Ptr, incidence);
0400         QFETCH(KIdentityManagementCore::Identity, identity);
0401         QFETCH(bool, bccMe);
0402         QFETCH(QString, attachment);
0403         QFETCH(QString, transport);
0404         QFETCH(MailClient::Result, expectedResult);
0405         QFETCH(int, expectedTransportId);
0406         QFETCH(QString, expectedFrom);
0407         QFETCH(QStringList, expectedToList);
0408         QFETCH(QStringList, expectedCcList);
0409         QFETCH(QStringList, expectedBccList);
0410         QFETCH(CryptoState, expectedCrypto);
0411         QFETCH(QList<ExpectedDialog>, expectedDialogs);
0412         QFETCH(ContactPreferences, contactPreferences);
0413 
0414         FakeMessageQueueJob::sUnitTestResults.clear();
0415 
0416         FakeITIPHandlerDialogDelegate::expectedWarningTwoActionsCancelDialogs = expectedDialogs;
0417         TestableMailClient::preferences = contactPreferences;
0418 
0419         mPendingSignals = 1;
0420         mMailClient->mailAttendees(incidence, identity, KCalendarCore::iTIPRequest, bccMe, attachment, transport);
0421         waitForSignals();
0422 
0423         if (mLastResult != expectedResult) {
0424             qDebug() << "Fail1: last=" << mLastResult << "; expected=" << expectedResult << "; error=" << mLastErrorMessage;
0425             QVERIFY(false);
0426         }
0427 
0428         if (FakeMessageQueueJob::sUnitTestResults.isEmpty()) {
0429             qDebug() << "mail results are empty";
0430         } else {
0431             const auto unitTestResult = FakeMessageQueueJob::sUnitTestResults.first();
0432             if (expectedTransportId != -1 && unitTestResult.transportId != expectedTransportId) {
0433                 qDebug() << "got " << unitTestResult.transportId << "; expected=" << expectedTransportId;
0434                 QVERIFY(false);
0435             }
0436 
0437             QCOMPARE(unitTestResult.from, expectedFrom);
0438             QCOMPARE(unitTestResult.to, expectedToList);
0439             QCOMPARE(unitTestResult.cc, expectedCcList);
0440             QCOMPARE(unitTestResult.bcc, expectedBccList);
0441             switch (expectedCrypto) {
0442             case CryptoState::Plain:
0443                 QCOMPARE(unitTestResult.message->contentType(false)->mimeType(), "text/plain");
0444                 break;
0445 
0446             case CryptoState::Signed:
0447                 QCOMPARE(unitTestResult.message->contentType(false)->mimeType(), "multipart/signed");
0448                 break;
0449 
0450             case CryptoState::Encrypted:
0451                 QCOMPARE(unitTestResult.message->contentType(false)->mimeType(), "multipart/encrypted");
0452                 break;
0453             }
0454         }
0455 
0456         if (!FakeITIPHandlerDialogDelegate::expectedWarningTwoActionsCancelDialogs.empty()) {
0457             QFAIL("An expected dialog wasn't seen");
0458         }
0459     }
0460 
0461     void testMailOrganizer_data()
0462     {
0463         QTest::addColumn<KCalendarCore::IncidenceBase::Ptr>("incidence");
0464         QTest::addColumn<KIdentityManagementCore::Identity>("identity");
0465         QTest::addColumn<QString>("from");
0466         QTest::addColumn<bool>("bccMe");
0467         QTest::addColumn<QString>("attachment");
0468         QTest::addColumn<QString>("subject");
0469         QTest::addColumn<QString>("transport");
0470         QTest::addColumn<MailClient::Result>("expectedResult");
0471         QTest::addColumn<int>("expectedTransportId");
0472         QTest::addColumn<QString>("expectedFrom");
0473         QTest::addColumn<QStringList>("expectedToList");
0474         QTest::addColumn<QStringList>("expectedBccList");
0475         QTest::addColumn<QString>("expectedSubject");
0476 
0477         KCalendarCore::IncidenceBase::Ptr incidence(new KCalendarCore::Event());
0478         KIdentityManagementCore::Identity identity;
0479         const QString from = s_ourEmail;
0480         bool bccMe = false;
0481         QString attachment;
0482         QString subject = QStringLiteral("subject1");
0483         QString transport;
0484         MailClient::Result expectedResult = MailClient::ResultSuccess;
0485         const int expectedTransportId = 69372773; // from tests/unittestenv/kdehome/share/config/mailtransports
0486         QString expectedFrom = from; // from tests/unittestenv/kdehome/share/config/emailidentities
0487         KCalendarCore::Person organizer(QStringLiteral("Organizer"), s_ourEmail);
0488         incidence->setOrganizer(organizer);
0489 
0490         QStringList toList;
0491         toList << s_ourEmail;
0492         QStringList toBccList;
0493         QString expectedSubject;
0494         //----------------------------------------------------------------------------------------------
0495         expectedSubject = subject;
0496         QTest::newRow("test1") << incidence << identity << from << bccMe << attachment << subject << transport << expectedResult << expectedTransportId
0497                                << expectedFrom << toList << toBccList << expectedSubject;
0498         //----------------------------------------------------------------------------------------------
0499         expectedSubject = QStringLiteral("Free Busy Message");
0500         incidence = KCalendarCore::IncidenceBase::Ptr(new KCalendarCore::FreeBusy());
0501         incidence->setOrganizer(organizer);
0502         QTest::newRow("FreeBusy") << incidence << identity << from << bccMe << attachment << subject << transport << expectedResult << expectedTransportId
0503                                   << expectedFrom << toList << toBccList << expectedSubject;
0504     }
0505 
0506     void testMailOrganizer()
0507     {
0508         QFETCH(KCalendarCore::IncidenceBase::Ptr, incidence);
0509         QFETCH(KIdentityManagementCore::Identity, identity);
0510         QFETCH(QString, from);
0511         QFETCH(bool, bccMe);
0512         QFETCH(QString, attachment);
0513         QFETCH(QString, subject);
0514         QFETCH(QString, transport);
0515         QFETCH(MailClient::Result, expectedResult);
0516         QFETCH(int, expectedTransportId);
0517         QFETCH(QString, expectedFrom);
0518         QFETCH(QStringList, expectedToList);
0519         QFETCH(QStringList, expectedBccList);
0520         QFETCH(QString, expectedSubject);
0521         FakeMessageQueueJob::sUnitTestResults.clear();
0522 
0523         mPendingSignals = 1;
0524         mMailClient->mailOrganizer(incidence, identity, from, KCalendarCore::iTIPReply, bccMe, attachment, subject, transport);
0525         waitForSignals();
0526         QCOMPARE(mLastResult, expectedResult);
0527 
0528         UnitTestResult unitTestResult = FakeMessageQueueJob::sUnitTestResults.first();
0529         if (expectedTransportId != -1) {
0530             QCOMPARE(unitTestResult.transportId, expectedTransportId);
0531         }
0532 
0533         QCOMPARE(unitTestResult.from, expectedFrom);
0534         QCOMPARE(unitTestResult.to, expectedToList);
0535         QCOMPARE(unitTestResult.bcc, expectedBccList);
0536         QCOMPARE(unitTestResult.message->subject()->asUnicodeString(), expectedSubject);
0537     }
0538 
0539     void testMailTo_data()
0540     {
0541         QTest::addColumn<KCalendarCore::IncidenceBase::Ptr>("incidence");
0542         QTest::addColumn<KIdentityManagementCore::Identity>("identity");
0543         QTest::addColumn<QString>("from");
0544         QTest::addColumn<bool>("bccMe");
0545         QTest::addColumn<QString>("recipients");
0546         QTest::addColumn<QString>("attachment");
0547         QTest::addColumn<QString>("transport");
0548         QTest::addColumn<MailClient::Result>("expectedResult");
0549         QTest::addColumn<int>("expectedTransportId");
0550         QTest::addColumn<QString>("expectedFrom");
0551         QTest::addColumn<QStringList>("expectedToList");
0552         QTest::addColumn<QStringList>("expectedBccList");
0553 
0554         KCalendarCore::IncidenceBase::Ptr incidence(new KCalendarCore::Event());
0555         KIdentityManagementCore::Identity identity;
0556         const QString from = s_ourEmail;
0557         bool bccMe = false;
0558         const QString recipients = s_ourEmail;
0559         QString attachment;
0560         QString transport;
0561         MailClient::Result expectedResult = MailClient::ResultSuccess;
0562         const int expectedTransportId = 69372773; // from tests/unittestenv/kdehome/share/config/mailtransports
0563         QString expectedFrom = from; // from tests/unittestenv/kdehome/share/config/emailidentities
0564         KCalendarCore::Person organizer(QStringLiteral("Organizer"), s_ourEmail);
0565         QStringList toList;
0566         toList << s_ourEmail;
0567         QStringList toBccList;
0568         //----------------------------------------------------------------------------------------------
0569         QTest::newRow("test1") << incidence << identity << from << bccMe << recipients << attachment << transport << expectedResult << expectedTransportId
0570                                << expectedFrom << toList << toBccList;
0571     }
0572 
0573     void testMailTo()
0574     {
0575         QFETCH(KCalendarCore::IncidenceBase::Ptr, incidence);
0576         QFETCH(KIdentityManagementCore::Identity, identity);
0577         QFETCH(QString, from);
0578         QFETCH(bool, bccMe);
0579         QFETCH(QString, recipients);
0580         QFETCH(QString, attachment);
0581         QFETCH(QString, transport);
0582         QFETCH(MailClient::Result, expectedResult);
0583         QFETCH(int, expectedTransportId);
0584         QFETCH(QString, expectedFrom);
0585         QFETCH(QStringList, expectedToList);
0586         QFETCH(QStringList, expectedBccList);
0587         FakeMessageQueueJob::sUnitTestResults.clear();
0588 
0589         mPendingSignals = 1;
0590         mMailClient->mailTo(incidence, identity, from, KCalendarCore::iTIPRequest, bccMe, recipients, attachment, transport);
0591         waitForSignals();
0592         QCOMPARE(mLastResult, expectedResult);
0593         UnitTestResult unitTestResult = FakeMessageQueueJob::sUnitTestResults.first();
0594         if (expectedTransportId != -1) {
0595             QCOMPARE(unitTestResult.transportId, expectedTransportId);
0596         }
0597 
0598         QCOMPARE(unitTestResult.from, expectedFrom);
0599         QCOMPARE(unitTestResult.to, expectedToList);
0600         QCOMPARE(unitTestResult.bcc, expectedBccList);
0601     }
0602 
0603     void handleFinished(Akonadi::MailClient::Result result, const QString &errorMessage)
0604     {
0605         qDebug() << "handleFinished: " << result << errorMessage;
0606         mLastResult = result;
0607         mLastErrorMessage = errorMessage;
0608         --mPendingSignals;
0609         QTestEventLoop::instance().exitLoop();
0610     }
0611 
0612     void waitForSignals()
0613     {
0614         if (mPendingSignals > 0) {
0615             QTestEventLoop::instance().enterLoop(5); // 5 seconds is enough
0616             QVERIFY(!QTestEventLoop::instance().timeout());
0617         }
0618     }
0619 };
0620 
0621 QTEST_AKONADIMAIN(MailClientTest)
0622 
0623 #include "mailclienttest.moc"