File indexing completed on 2025-01-05 04:54:56

0001 #include <QTest>
0002 #include <QDebug>
0003 #include <functional>
0004 #include <QStandardPaths>
0005 #include <QDir>
0006 #include <QtWebEngine>
0007 
0008 
0009 #include "mailtemplates.h"
0010 #include "mailcrypto.h"
0011 
0012 static KMime::Content *getSubpart(KMime::Content *msg, const QByteArray &mimeType)
0013 {
0014     for (const auto c : msg->contents()) {
0015         if (c->contentType(false)->mimeType() == mimeType) {
0016             return c;
0017         }
0018     }
0019     return nullptr;
0020 }
0021 
0022 static QByteArray readMailFromFile(const QString &mailFile)
0023 {
0024     Q_ASSERT(!QString::fromLatin1(MAIL_DATA_DIR).isEmpty());
0025     QFile file(QLatin1String(MAIL_DATA_DIR) + QLatin1Char('/') + mailFile);
0026     file.open(QIODevice::ReadOnly);
0027     Q_ASSERT(file.isOpen());
0028     return file.readAll();
0029 }
0030 
0031 
0032 static KMime::Message::Ptr readMail(const QString &mailFile)
0033 {
0034     auto msg = KMime::Message::Ptr::create();
0035     msg->setContent(readMailFromFile(mailFile));
0036     msg->parse();
0037     return msg;
0038 }
0039 
0040 static QString removeFirstLine(const QString &s)
0041 {
0042     return s.mid(s.indexOf("\n") + 1);
0043 }
0044 
0045 static QString normalize(const QString &s)
0046 {
0047     auto text = s;
0048     text.replace(">", "");
0049     text.replace("\n", "");
0050     text.replace("=", "");
0051     text.replace(" ", "");
0052     return text;
0053 }
0054 
0055 static QString unquote(const QString &s)
0056 {
0057     auto text = s;
0058     text.replace("> ", "");
0059     return text;
0060 }
0061 
0062 class MailTemplateTest : public QObject
0063 {
0064     Q_OBJECT
0065 
0066     bool validate(KMime::Message::Ptr msg)
0067     {
0068         const auto data = msg->encodedContent();
0069         //IMAP compat: The ASCII NUL character, %x00, MUST NOT be used at any time.
0070         if (data.contains('\0')) {
0071             return false;
0072         }
0073         return true;
0074     }
0075 
0076 private slots:
0077 
0078     void initTestCase()
0079     {
0080         QtWebEngine::initialize();
0081     }
0082 
0083 
0084     //Ensures we don't crash on garbage
0085     void testEmpty()
0086     {
0087         MailTemplates::reply(KMime::Message::Ptr::create(), [&] (const KMime::Message::Ptr &) {
0088         });
0089     }
0090 
0091     void testPlainReply()
0092     {
0093         auto msg = readMail("plaintext.mbox");
0094         KMime::Message::Ptr result;
0095         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0096             result = r;
0097         });
0098         QTRY_VERIFY(result);
0099         QCOMPARE(normalize(removeFirstLine(result->body())), normalize(msg->body()));
0100         QCOMPARE(result->to()->addresses(), {{"konqi@example.org"}});
0101         QCOMPARE(result->subject()->asUnicodeString(), QLatin1String{"RE: A random subject with alternative contenttype"});
0102     }
0103 
0104     void testHtmlReply()
0105     {
0106         auto msg = readMail("html.mbox");
0107         KMime::Message::Ptr result;
0108         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0109             result = r;
0110         });
0111         QTRY_VERIFY(result);
0112         QCOMPARE(unquote(removeFirstLine(result->body())), QLatin1String("HTML text"));
0113     }
0114 
0115     void testStripSignatureReply()
0116     {
0117         auto msg = readMail("plaintext-with-signature.mbox");
0118         KMime::Message::Ptr result;
0119         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0120             result = r;
0121         });
0122         QTRY_VERIFY(result);
0123         QVERIFY(!result->body().contains("This is a signature"));
0124     }
0125 
0126     void testStripSignatureHtmlReply()
0127     {
0128         auto msg = readMail("html-with-signature.mbox");
0129         KMime::Message::Ptr result;
0130         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0131             result = r;
0132         });
0133         QTRY_VERIFY(result);
0134         QVERIFY(!result->body().contains("This is a signature"));
0135     }
0136 
0137     //We can't test this because we can't commit a CRLF file due to commit hooks.
0138     // void testStripSignatureCrlfReply()
0139     // {
0140     //     auto msg = readMail("crlf-with-signature.mbox");
0141     //     KMime::Message::Ptr result;
0142     //     MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0143     //         result = r;
0144     //     });
0145     //     QTRY_VERIFY(result);
0146     //     QVERIFY(!result->body().contains("This is a signature"));
0147     // }
0148 
0149     void testStripEncryptedCRLFReply()
0150     {
0151         auto msg = readMail("crlf-encrypted-with-signature.mbox");
0152         KMime::Message::Ptr result;
0153         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0154             result = r;
0155         });
0156         QTRY_VERIFY(result);
0157         QVERIFY(!result->body().contains("This is a signature"));
0158     }
0159 
0160     void testHtml8BitEncodedReply()
0161     {
0162         auto msg = readMail("8bitencoded.mbox");
0163         KMime::Message::Ptr result;
0164         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0165             result = r;
0166         });
0167         QTRY_VERIFY(result);
0168         QVERIFY(MailTemplates::plaintextContent(result).contains(QString::fromUtf8("Why Pisa’s Tower")));
0169     }
0170 
0171     void testMultipartSignedReply()
0172     {
0173         auto msg = readMail("openpgp-signed-mailinglist.mbox");
0174         KMime::Message::Ptr result;
0175         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0176             result = r;
0177         });
0178         QTRY_VERIFY(result);
0179         auto content = removeFirstLine(result->body());
0180         QVERIFY(!content.isEmpty());
0181         QVERIFY(content.contains("i noticed a new branch"));
0182     }
0183 
0184     void testMultipartAlternativeReply()
0185     {
0186         auto msg = readMail("alternative.mbox");
0187         KMime::Message::Ptr result;
0188         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0189             result = r;
0190         });
0191         QTRY_VERIFY(result);
0192         auto content = removeFirstLine(result->body());
0193         QVERIFY(!content.isEmpty());
0194         QCOMPARE(unquote(content), QLatin1String("If you can see this text it means that your email client couldn't display our newsletter properly.\nPlease visit this link to view the newsletter on our website: http://www.gog.com/newsletter/\n"));
0195     }
0196 
0197     void testAttachmentReply()
0198     {
0199         auto msg = readMail("plaintextattachment.mbox");
0200         KMime::Message::Ptr result;
0201         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0202             result = r;
0203         });
0204         QTRY_VERIFY(result);
0205         auto content = removeFirstLine(result->body());
0206         QVERIFY(!content.isEmpty());
0207         QCOMPARE(unquote(content), QLatin1String("sdlkjsdjf"));
0208     }
0209 
0210     void testMultiRecipientReply()
0211     {
0212         auto msg = readMail("multirecipients.mbox");
0213         KMime::Message::Ptr result;
0214         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0215             result = r;
0216         });
0217         QTRY_VERIFY(result);
0218         auto content = removeFirstLine(result->body());
0219         QVERIFY(!content.isEmpty());
0220         QCOMPARE(unquote(content), QLatin1String("test"));
0221         QCOMPARE(result->to()->addresses(), {{"from@example.org"}});
0222         auto l = QVector<QByteArray>{{"to1@example.org"}, {"to2@example.org"}, {"cc1@example.org"}, {"cc2@example.org"}};
0223         QCOMPARE(result->cc()->addresses(), l);
0224     }
0225 
0226     void testMultiRecipientReplyFilteringMe()
0227     {
0228         KMime::Types::AddrSpecList me;
0229         KMime::Types::Mailbox mb;
0230         mb.setAddress("to1@example.org");
0231         me << mb.addrSpec();
0232 
0233         auto msg = readMail("multirecipients.mbox");
0234         KMime::Message::Ptr result;
0235         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0236             result = r;
0237         }, me);
0238         QTRY_VERIFY(result);
0239         QCOMPARE(result->to()->addresses(), {{"from@example.org"}});
0240         auto l = QVector<QByteArray>{{"to2@example.org"}, {"cc1@example.org"}, {"cc2@example.org"}};
0241         QCOMPARE(result->cc()->addresses(), l);
0242     }
0243 
0244     void testMultiRecipientReplyOwnMessage()
0245     {
0246         KMime::Types::AddrSpecList me;
0247         KMime::Types::Mailbox mb;
0248         mb.setAddress("from@example.org");
0249         me << mb.addrSpec();
0250 
0251         auto msg = readMail("multirecipients.mbox");
0252         KMime::Message::Ptr result;
0253         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0254             result = r;
0255         }, me);
0256         QTRY_VERIFY(result);
0257 
0258         auto to = QVector<QByteArray>{{"to1@example.org"}, {"to2@example.org"}};
0259         QCOMPARE(result->to()->addresses(), to);
0260         auto cc = QVector<QByteArray>{{"cc1@example.org"}, {"cc2@example.org"}};
0261         QCOMPARE(result->cc()->addresses(), cc);
0262     }
0263 
0264     void testReplyList()
0265     {
0266         KMime::Types::AddrSpecList me;
0267         KMime::Types::Mailbox mb;
0268         mb.setAddress("me@example.org");
0269         me << mb.addrSpec();
0270 
0271         auto msg = readMail("listmessage.mbox");
0272         KMime::Message::Ptr result;
0273         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0274             result = r;
0275         }, me);
0276         QTRY_VERIFY(result);
0277 
0278         auto to = QVector<QByteArray>{{"list@example.org"}};
0279         QCOMPARE(result->to()->addresses(), to);
0280         auto cc = QVector<QByteArray>{{"to@example.org"}, {"cc1@example.org"}};
0281         QCOMPARE(result->cc()->addresses(), cc);
0282     }
0283 
0284     void testForwardAsAttachment()
0285     {
0286         auto msg = readMail("plaintext.mbox");
0287         KMime::Message::Ptr result;
0288         MailTemplates::forward(msg, [&] (const KMime::Message::Ptr &r) {
0289             result = r;
0290         });
0291         QTRY_VERIFY(result);
0292         QCOMPARE(result->subject(false)->asUnicodeString(), QLatin1String{"FW: A random subject with alternative contenttype"});
0293         QCOMPARE(result->to()->addresses(), {});
0294         QCOMPARE(result->cc()->addresses(), {});
0295         QCOMPARE(result->references()->identifiers(), {"1505824.VT1nqpAGu0@vkpc5"});
0296         QCOMPARE(result->inReplyTo()->identifiers(), {});
0297 
0298         auto attachments = result->attachments();
0299         QCOMPARE(attachments.size(), 1);
0300         auto attachment = attachments[0];
0301         QCOMPARE(attachment->contentDisposition(false)->disposition(), KMime::Headers::CDinline);
0302         QCOMPARE(attachment->contentDisposition(false)->filename(), QLatin1String{"A random subject with alternative contenttype.eml"});
0303         QVERIFY(attachment->bodyIsMessage());
0304 
0305         attachment->parse();
0306         auto origMsg = attachment->bodyAsMessage();
0307         QCOMPARE(origMsg->subject(false)->asUnicodeString(), QLatin1String{"A random subject with alternative contenttype"});
0308     }
0309 
0310     void testEncryptedForwardAsAttachment()
0311     {
0312         auto msg = readMail("openpgp-encrypted.mbox");
0313         KMime::Message::Ptr result;
0314         MailTemplates::forward(msg, [&](const KMime::Message::Ptr &r) { result = r; });
0315         QTRY_VERIFY(result);
0316         QCOMPARE(result->subject(false)->asUnicodeString(), QLatin1String{"FW: OpenPGP encrypted"});
0317         QCOMPARE(result->to()->addresses(), {});
0318         QCOMPARE(result->cc()->addresses(), {});
0319         QCOMPARE(result->references()->identifiers(), {"1505824.VT2nqpAGu0@vkpc5"});
0320         QCOMPARE(result->inReplyTo()->identifiers(), {});
0321 
0322         auto attachments = result->attachments();
0323         QCOMPARE(attachments.size(), 1);
0324         auto attachment = attachments[0];
0325         QCOMPARE(attachment->contentDisposition(false)->disposition(), KMime::Headers::CDinline);
0326         QCOMPARE(attachment->contentDisposition(false)->filename(), QLatin1String{"OpenPGP encrypted.eml"});
0327         QVERIFY(attachment->bodyIsMessage());
0328 
0329         attachment->parse();
0330         auto origMsg = attachment->bodyAsMessage();
0331         QCOMPARE(origMsg->subject(false)->asUnicodeString(), QLatin1String{"OpenPGP encrypted"});
0332     }
0333 
0334     void testEncryptedWithAttachmentsForwardAsAttachment()
0335     {
0336         auto msg = readMail("openpgp-encrypted-two-attachments.mbox");
0337         KMime::Message::Ptr result;
0338         MailTemplates::forward(msg, [&](const KMime::Message::Ptr &r) { result = r; });
0339         QTRY_VERIFY(result);
0340         QCOMPARE(result->subject(false)->asUnicodeString(), QLatin1String{"FW: OpenPGP encrypted with 2 text attachments"});
0341         QCOMPARE(result->to()->addresses(), {});
0342         QCOMPARE(result->cc()->addresses(), {});
0343         QCOMPARE(result->references()->identifiers(), {"1505824.VT0nqpAGu0@vkpc5"});
0344         QCOMPARE(result->inReplyTo()->identifiers(), {});
0345 
0346         auto attachments = result->attachments();
0347         QCOMPARE(attachments.size(), 1);
0348         auto attachment = attachments[0];
0349         QCOMPARE(attachment->contentDisposition(false)->disposition(), KMime::Headers::CDinline);
0350         QCOMPARE(attachment->contentDisposition(false)->filename(), QLatin1String{"OpenPGP encrypted with 2 text attachments.eml"});
0351         QVERIFY(attachment->bodyIsMessage());
0352 
0353         attachment->parse();
0354         auto origMsg = attachment->bodyAsMessage();
0355         QCOMPARE(origMsg->subject(false)->asUnicodeString(), QLatin1String{"OpenPGP encrypted with 2 text attachments"});
0356 
0357         auto attattachments = origMsg->attachments();
0358         QCOMPARE(attattachments.size(), 2);
0359         QCOMPARE(attattachments[0]->contentDisposition(false)->filename(), QLatin1String{"attachment1.txt"});
0360         QCOMPARE(attattachments[1]->contentDisposition(false)->filename(), QLatin1String{"attachment2.txt"});
0361     }
0362 
0363     void testForwardAlreadyForwarded()
0364     {
0365         auto msg = readMail("cid-links-forwarded-inline.mbox");
0366         KMime::Message::Ptr result;
0367         MailTemplates::forward(msg, [&] (const KMime::Message::Ptr &r) {
0368             result = r;
0369         });
0370         QTRY_VERIFY(result);
0371         QCOMPARE(result->subject(false)->asUnicodeString(), QLatin1String{"FW: Html Hello (inlin)"});
0372         QCOMPARE(result->to()->addresses(), {});
0373         QCOMPARE(result->cc()->addresses(), {});
0374         const QVector references{QByteArray{"a1777ec781546ccc5dcd4918a5e4e03d@info"}, QByteArray{"46b164308eb6056361c866932a740a3c@info"}};
0375         QCOMPARE(result->references()->identifiers(), references);
0376         QCOMPARE(result->inReplyTo()->identifiers(), {});
0377     }
0378 
0379     void testCreatePlainMail()
0380     {
0381         QStringList to = {{"to@example.org"}};
0382         QStringList cc = {{"cc@example.org"}};
0383         QStringList bcc = {{"bcc@example.org"}};;
0384         KMime::Types::Mailbox from;
0385         from.fromUnicodeString("from@example.org");
0386         QString subject = "subject";
0387         QString body = "body";
0388         QList<Attachment> attachments;
0389 
0390         auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, false, attachments);
0391 
0392         QVERIFY(result);
0393         QVERIFY(validate(result));
0394         QCOMPARE(result->subject()->asUnicodeString(), subject);
0395         QCOMPARE(result->body(), body.toUtf8());
0396         QVERIFY(result->date(false)->dateTime().isValid());
0397         QVERIFY(result->contentType()->isMimeType("text/plain"));
0398         QVERIFY(result->messageID(false) && !result->messageID(false)->isEmpty());
0399     }
0400 
0401     void testCreateHtmlMail()
0402     {
0403         QStringList to = {{"to@example.org"}};
0404         QStringList cc = {{"cc@example.org"}};
0405         QStringList bcc = {{"bcc@example.org"}};;
0406         KMime::Types::Mailbox from;
0407         from.fromUnicodeString("from@example.org");
0408         QString subject = "subject";
0409         QString body = "body";
0410         QList<Attachment> attachments;
0411 
0412         auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, true, attachments);
0413 
0414         QVERIFY(result);
0415         QVERIFY(validate(result));
0416         QCOMPARE(result->subject()->asUnicodeString(), subject);
0417         QVERIFY(result->date(false)->dateTime().isValid());
0418         QVERIFY(result->contentType()->isMimeType("multipart/alternative"));
0419         const auto contents = result->contents();
0420         //1 Plain + 1 Html
0421         QCOMPARE(contents.size(), 2);
0422     }
0423 
0424     void testCreatePlainMailWithAttachments()
0425     {
0426         QStringList to = {{"to@example.org"}};
0427         QStringList cc = {{"cc@example.org"}};;
0428         QStringList bcc = {{"bcc@example.org"}};;
0429         KMime::Types::Mailbox from;
0430         from.fromUnicodeString("from@example.org");
0431         QString subject = "subject";
0432         QString body = "body";
0433         QList<Attachment> attachments = {{"name", "filename", "mimetype", true, "inlineAttachment"}, {"name", "filename", "mimetype", false, "nonInlineAttachment"}};
0434 
0435         auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, false, attachments);
0436 
0437         QVERIFY(result);
0438         QVERIFY(validate(result));
0439         QCOMPARE(result->subject()->asUnicodeString(), subject);
0440         QVERIFY(result->contentType()->isMimeType("multipart/mixed"));
0441         QVERIFY(result->date(false)->dateTime().isValid());
0442         const auto contents = result->contents();
0443         //1 Plain + 2 Attachments
0444         QCOMPARE(contents.size(), 3);
0445         auto p = getSubpart(result.data(), "text/plain");
0446         QVERIFY(p);
0447     }
0448 
0449     void testCreateHtmlMailWithAttachments()
0450     {
0451         QStringList to = {{"to@example.org"}};
0452         QStringList cc = {{"cc@example.org"}};;
0453         QStringList bcc = {{"bcc@example.org"}};;
0454         KMime::Types::Mailbox from;
0455         from.fromUnicodeString("from@example.org");
0456         QString subject = "subject";
0457         QString body = "body";
0458         QList<Attachment> attachments = {{"name", "filename", "mimetype", true, "inlineAttachment"}, {"name", "filename", "mimetype", false, "nonInlineAttachment"}};
0459 
0460         auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, true, attachments);
0461 
0462         QVERIFY(result);
0463         QVERIFY(validate(result));
0464         QCOMPARE(result->subject()->asUnicodeString(), subject);
0465         QVERIFY(result->contentType()->isMimeType("multipart/mixed"));
0466         QVERIFY(result->date(false)->dateTime().isValid());
0467         const auto contents = result->contents();
0468         //1 alternative + 2 Attachments
0469         QCOMPARE(contents.size(), 3);
0470         auto p = getSubpart(result.data(), "multipart/alternative");
0471         QVERIFY(p);
0472     }
0473 
0474     void testCreatePlainMailSigned()
0475     {
0476         QStringList to = {{"to@example.org"}};
0477         QStringList cc = {{"cc@example.org"}};;
0478         QStringList bcc = {{"bcc@example.org"}};;
0479         KMime::Types::Mailbox from;
0480         from.fromUnicodeString("from@example.org");
0481         QString subject = "subject";
0482         QString body = "body";
0483         QList<Attachment> attachments;
0484 
0485         auto keys = Crypto::findKeys({}, true, false);
0486         auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, false, attachments, keys, {}, keys[0]);
0487 
0488         QVERIFY(result);
0489         QVERIFY(validate(result));
0490         // qWarning() << "---------------------------------";
0491         // qWarning().noquote() << result->encodedContent();
0492         // qWarning() << "---------------------------------";
0493         QCOMPARE(result->subject()->asUnicodeString(), subject);
0494         QVERIFY(result->date(false)->dateTime().isValid());
0495 
0496         QCOMPARE(result->contentType()->mimeType(), QByteArray{"multipart/signed"});
0497         QCOMPARE(result->attachments().size(), 1);
0498         QCOMPARE(result->attachments()[0]->contentDisposition()->filename(), QLatin1String{"0x8F246DE6.asc"});
0499         QCOMPARE(result->contents().size(), 2);
0500 
0501         auto signedMessage = result->contents()[0];
0502         QVERIFY(signedMessage->contentType()->isMimeType("multipart/mixed"));
0503         const auto contents = signedMessage->contents();
0504         QCOMPARE(contents.size(), 2);
0505         QCOMPARE(contents[0]->contentType()->mimeType(), QByteArray{"text/plain"});
0506         QCOMPARE(contents[1]->contentType()->mimeType(), QByteArray{"application/pgp-keys"});
0507         QCOMPARE(contents[1]->contentDisposition()->filename(), QLatin1String{"0x8F246DE6.asc"});
0508 
0509         auto signature = result->contents()[1];
0510         QCOMPARE(signature->contentDisposition()->filename(), QLatin1String{"signature.asc"});
0511         QVERIFY(signature->contentType()->isMimeType("application/pgp-signature"));
0512     }
0513 
0514     void testCreatePlainMailWithAttachmentsSigned()
0515     {
0516         QStringList to = {{"to@example.org"}};
0517         QStringList cc = {{"cc@example.org"}};;
0518         QStringList bcc = {{"bcc@example.org"}};;
0519         KMime::Types::Mailbox from;
0520         from.fromUnicodeString("from@example.org");
0521         QString subject = "subject";
0522         QString body = "body";
0523         QList<Attachment> attachments = {{"name", "filename1", "mimetype1", true, "inlineAttachment"}, {"name", "filename2", "mimetype2", false, "nonInlineAttachment"}};
0524 
0525         auto signingKeys = Crypto::findKeys({}, true, false);
0526         auto result = MailTemplates::createMessage({}, to, cc, bcc, from, subject, body, false, attachments, signingKeys, {}, signingKeys[0]);
0527 
0528         QVERIFY(result);
0529         QVERIFY(validate(result));
0530         qWarning() << "---------------------------------";
0531         qWarning().noquote() << result->encodedContent();
0532         qWarning() << "---------------------------------";
0533         QCOMPARE(result->subject()->asUnicodeString(), subject);
0534         QVERIFY(result->date(false)->dateTime().isValid());
0535 
0536         QCOMPARE(result->contentType()->mimeType(), QByteArray{"multipart/signed"});
0537         QCOMPARE(result->attachments().size(), 3);
0538         QCOMPARE(result->attachments()[0]->contentDisposition()->filename(), QLatin1String{"filename1"});
0539         QCOMPARE(result->attachments()[1]->contentDisposition()->filename(), QLatin1String{"filename2"});
0540         QCOMPARE(result->attachments()[2]->contentDisposition()->filename(), QLatin1String{"0x8F246DE6.asc"});
0541 
0542         QCOMPARE(result->contents().size(), 2);
0543 
0544         auto signedMessage = result->contents()[0];
0545         QVERIFY(signedMessage->contentType()->isMimeType("multipart/mixed"));
0546         const auto contents = signedMessage->contents();
0547         QCOMPARE(contents.size(), 4);
0548         QCOMPARE(contents[0]->contentType()->mimeType(), QByteArray{"text/plain"});
0549         QCOMPARE(contents[1]->contentDisposition()->filename(), QLatin1String{"filename1"});
0550         QCOMPARE(contents[2]->contentDisposition()->filename(), QLatin1String{"filename2"});
0551         QCOMPARE(contents[3]->contentType()->mimeType(), QByteArray{"application/pgp-keys"});
0552         QCOMPARE(contents[3]->contentDisposition()->filename(), QLatin1String{"0x8F246DE6.asc"});
0553     }
0554 
0555     void testCreateIMipMessage()
0556     {
0557         QStringList to = {{"to@example.org"}};
0558         QStringList cc = {{"cc@example.org"}};
0559         QStringList bcc = {{"bcc@example.org"}};
0560         QString from = {"from@example.org"};
0561         QString subject = "subject";
0562         QString body = "body";
0563 
0564         QString ical = "ical";
0565 
0566         auto result = MailTemplates::createIMipMessage(from, {to, cc, bcc}, subject, body, ical);
0567 
0568         QVERIFY(result);
0569         QVERIFY(validate(result));
0570         qWarning() << "---------------------------------";
0571         qWarning().noquote() << result->encodedContent();
0572         qWarning() << "---------------------------------";
0573 
0574         QCOMPARE(result->contentType()->mimeType(), QByteArray{"multipart/alternative"});
0575 
0576         QCOMPARE(result->attachments().size(), 0);
0577 
0578         QCOMPARE(result->contents().size(), 2);
0579         QVERIFY(result->contents()[0]->contentType()->isMimeType("text/plain"));
0580         QVERIFY(result->contents()[1]->contentType()->isMimeType("text/calendar"));
0581         QCOMPARE(result->contents()[1]->contentType()->name(), QLatin1String{"event.ics"});
0582     }
0583 
0584     void testEncryptedWithProtectedHeadersReply()
0585     {
0586 
0587         KMime::Types::AddrSpecList me;
0588         KMime::Types::Mailbox mb;
0589         mb.setAddress("to1@example.org");
0590         me << mb.addrSpec();
0591 
0592         auto msg = readMail("openpgp-encrypted-memoryhole2.mbox");
0593         KMime::Message::Ptr result;
0594         MailTemplates::reply(msg, [&] (const KMime::Message::Ptr &r) {
0595             result = r;
0596         }, me);
0597         QTRY_VERIFY(result);
0598         QCOMPARE(result->subject()->asUnicodeString(), QLatin1String{"RE: This is the subject"});
0599         QCOMPARE(result->to()->addresses(), {{"jane@doe.com"}});
0600         QCOMPARE(result->cc()->addresses(), {{"john@doe.com"}});
0601         QCOMPARE(result->inReplyTo()->asUnicodeString(), QLatin1String{"<03db3530-0000-0000-95a2-8a148f00000@example.com>"});
0602         QCOMPARE(result->references()->asUnicodeString(), QLatin1String{"<dbe9d22b-0a3f-cb1e-e883-8a148f00000@example.com> <03db3530-0000-0000-95a2-8a148f00000@example.com>"});
0603         QCOMPARE(normalize(removeFirstLine(result->body())), QLatin1String{"FsdflkjdslfjHappyMonday!Belowyouwillfindaquickoverviewofthecurrenton-goings.Remember"});
0604     }
0605 
0606 
0607     void testEncryptedWithProtectedHeadersForwardAsAttachment()
0608     {
0609         auto msg = readMail("openpgp-encrypted-memoryhole2.mbox");
0610         KMime::Message::Ptr result;
0611         MailTemplates::forward(msg, [&](const KMime::Message::Ptr &r) { result = r; });
0612         QTRY_VERIFY(result);
0613         QCOMPARE(result->subject()->asUnicodeString(), QLatin1String{"FW: This is the subject"});
0614         QCOMPARE(result->to()->addresses(), {});
0615         QCOMPARE(result->cc()->addresses(), {});
0616         QCOMPARE(result->references()->asUnicodeString(), QLatin1String{"<dbe9d22b-0a3f-cb1e-e883-8a148f00000@example.com> <03db3530-0000-0000-95a2-8a148f00000@example.com>"});
0617         QCOMPARE(result->inReplyTo()->identifiers(), {});
0618 
0619         auto attachments = result->attachments();
0620         QCOMPARE(attachments.size(), 1);
0621         auto attachment = attachments[0];
0622         QCOMPARE(attachment->contentDisposition(false)->disposition(), KMime::Headers::CDinline);
0623         QCOMPARE(attachment->contentDisposition(false)->filename(), QLatin1String{"This is the subject.eml"});
0624         QVERIFY(attachment->bodyIsMessage());
0625 
0626         attachment->parse();
0627         auto origMsg = attachment->bodyAsMessage();
0628         QCOMPARE(origMsg->subject(false)->asUnicodeString(), QLatin1String{"..."});
0629     }
0630 };
0631 
0632 QTEST_MAIN(MailTemplateTest)
0633 #include "mailtemplatetest.moc"