File indexing completed on 2025-03-09 04:53:55

0001 /*
0002   SPDX-FileCopyrightText: 2010 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
0003   SPDX-FileCopyrightText: 2010 Leo Franchi <lfranchi@kde.org>
0004   SPDX-FileCopyrightText: 2017-2024 Laurent Montel <montel@kde.org>
0005 
0006   SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "messagefactoryngtest.h"
0010 
0011 #include "cryptofunctions.h"
0012 #include "qtest_messagecomposer.h"
0013 #include "setupenv.h"
0014 
0015 #include <MessageCore/StringUtil>
0016 
0017 #include <MessageComposer/Composer>
0018 #include <MessageComposer/GlobalPart>
0019 #include <MessageComposer/MessageComposerSettings>
0020 #include <MessageComposer/MessageFactoryNG>
0021 #include <MessageComposer/Util>
0022 
0023 #include <MessageComposer/InfoPart>
0024 #include <MessageComposer/TextPart>
0025 
0026 #include <KMime/DateFormatter>
0027 
0028 #include <KIdentityManagementCore/Identity>
0029 #include <KIdentityManagementCore/IdentityManager>
0030 
0031 #include "globalsettings_templateparser.h"
0032 
0033 #include <QDateTime>
0034 #include <QDir>
0035 #include <QLocale>
0036 #include <QRegularExpression>
0037 #include <QRegularExpressionMatch>
0038 #include <QSignalSpy>
0039 #include <QTest>
0040 
0041 using namespace MessageComposer;
0042 
0043 MessageFactoryTest::MessageFactoryTest(QObject *parent)
0044     : QObject(parent)
0045 {
0046 }
0047 
0048 MessageFactoryTest::~MessageFactoryTest()
0049 {
0050     // Workaround QTestLib not flushing deleteLater()s on exit, which
0051     // leads to WebEngine asserts (view not deleted)
0052     QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
0053 }
0054 
0055 void MessageFactoryTest::initMain()
0056 {
0057 #ifndef Q_OS_WIN
0058     Test::setupFullEnv();
0059 #else
0060     Test::setupEnv();
0061 #endif
0062 }
0063 
0064 namespace
0065 {
0066 template<typename String>
0067 String very_simplistic_diff(const String &a, const String &b)
0068 {
0069     const QList<String> al = a.split('\n');
0070     const QList<String> bl = b.split('\n');
0071     String result;
0072     int ai = 0;
0073     int bi = 0;
0074     while (ai < al.size() && bi < bl.size()) {
0075         if (al[ai] == bl[bi]) {
0076             // qDebug( "found   equal line a@%d x b@%d", ai, bi );
0077             result += "  " + al[ai] + '\n';
0078             ++ai;
0079             ++bi;
0080         } else {
0081             // qDebug( "found unequal line a@%d x b@%d", ai, bi );
0082             const int b_in_a = al.indexOf(bl[bi], ai);
0083             const int a_in_b = bl.indexOf(al[ai], bi);
0084             // qDebug( "   b_in_a == %d", b_in_a );
0085             // qDebug( "   a_in_b == %d", a_in_b );
0086             if (b_in_a == -1) {
0087                 if (a_in_b == -1) {
0088                     // (at least) one line changed:
0089                     result += "- " + al[ai++] + '\n' + "+ " + bl[bi++] + '\n';
0090                 } else {
0091                     // some lines added:
0092                     while (bi < a_in_b) {
0093                         result += "+ " + bl[bi++] + '\n';
0094                     }
0095                 }
0096             } else {
0097                 // some lines removed:
0098                 while (ai < b_in_a) {
0099                     result += "- " + al[ai++] + '\n';
0100                 }
0101                 // some lines added:
0102                 while (bi < a_in_b) {
0103                     result += "+ " + bl[bi++] + '\n';
0104                 }
0105             }
0106             // qDebug( "result ( a@%d b@%d ):\n%s\n--end", ai, bi, result.constData() );
0107         }
0108     }
0109 
0110     const int sizeal(al.size());
0111     for (int i = ai; i < sizeal; ++i) {
0112         result += "- " + al[i] + '\n';
0113     }
0114     const int sizebl(bl.size());
0115     for (int i = bi; i < sizebl; ++i) {
0116         result += "+ " + bl[i] + '\n';
0117     }
0118     return result;
0119 }
0120 }
0121 
0122 #define QCOMPARE_OR_DIFF(a, b)                                                                                                                                 \
0123     if (a != b) {                                                                                                                                              \
0124         qDebug("diff:\n--begin--\n%s\n--end--", very_simplistic_diff(a, b).constData());                                                                       \
0125     }                                                                                                                                                          \
0126     QVERIFY(a == b)
0127 
0128 QTEST_MAIN(MessageFactoryTest)
0129 
0130 void MessageFactoryTest::cleanupTestCase()
0131 {
0132     delete mIdentMan;
0133     mIdentMan = nullptr;
0134     QDir dir(QDir::homePath() + QStringLiteral("/.qttest/"));
0135     dir.removeRecursively();
0136 }
0137 
0138 void MessageFactoryTest::initTestCase()
0139 {
0140     qRegisterMetaType<MessageComposer::MessageFactoryNG::MessageReply>();
0141     mIdentMan = new KIdentityManagementCore::IdentityManager;
0142 
0143     KIdentityManagementCore::Identity &ident = mIdentMan->modifyIdentityForUoid(mIdentMan->defaultIdentity().uoid());
0144     ident.setFullName(QStringLiteral("another"));
0145     ident.setPrimaryEmailAddress(QStringLiteral("another@another.com"));
0146 
0147     mIdentMan->newFromScratch(QStringLiteral("test1"));
0148     mIdentMan->newFromScratch(QStringLiteral("test2"));
0149     mIdentMan->newFromScratch(QStringLiteral("test3"));
0150     mIdentMan->commit();
0151 }
0152 
0153 void MessageFactoryTest::init()
0154 {
0155     TemplateParser::TemplateParserSettings::self()->setDefaults();
0156 }
0157 
0158 void MessageFactoryTest::testCreateReplyToAllWithUseSenderAndIdentityInCCAsync()
0159 {
0160     TemplateParser::TemplateParserSettings::self()->setTemplateReplyAll(QStringLiteral("%QUOTE"));
0161 
0162     const QString filename(QStringLiteral(MAIL_DATA_DIR) + QStringLiteral("/replyall_with_identity_message_and_identity_in_cc.mbox"));
0163     KMime::Message::Ptr msg = Test::loadMessage(filename);
0164     KIdentityManagementCore::Identity &i1 = mIdentMan->modifyIdentityForName(QStringLiteral("test1"));
0165     i1.setFullName(QStringLiteral("foo1"));
0166     i1.setPrimaryEmailAddress(QStringLiteral("identity1@bla.com"));
0167     KIdentityManagementCore::Identity &i2 = mIdentMan->modifyIdentityForName(QStringLiteral("test2"));
0168     i2.setFullName(QStringLiteral("foo2"));
0169     i2.setPrimaryEmailAddress(QStringLiteral("identity2@bla.com"));
0170     mIdentMan->commit();
0171 
0172     MessageFactoryNG factory(msg, 0);
0173     factory.setReplyStrategy(ReplyAll);
0174     factory.setIdentityManager(mIdentMan);
0175 
0176     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0177 
0178     factory.createReplyAsync();
0179     QVERIFY(spy.wait());
0180     QCOMPARE(spy.count(), 1);
0181 
0182     auto reply = spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0183 
0184     reply.replyAll = true;
0185 
0186     QString replyStr = QStringLiteral("> This is a mail for testing replyall and sender");
0187     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: Plain Message Test"));
0188     QCOMPARE_OR_DIFF(reply.msg->body(), replyStr.toUtf8());
0189 
0190     QString dateStr = reply.msg->date()->asUnicodeString();
0191     QString ba = QString::fromLatin1(
0192                      "From: foo1 <identity1@bla.com>\n"
0193                      "X-KMail-Identity: %1\n"
0194                      "Date: %2\n"
0195                      "Cc: blu <blu@blu.org>, bly <bly@bly.org>\n"
0196                      "To: blo <blo@blo.org>, bli <bli@bli.org>\n"
0197                      "Subject: Re: Plain Message Test\n"
0198                      "Content-Type: text/plain; charset=\"UTF-8\"\n"
0199                      "Content-Transfer-Encoding: 8Bit\nMIME-Version: 1.0\n"
0200                      "X-KMail-Link-Message: 0\n"
0201                      "X-KMail-Link-Type: reply\n\n"
0202                      "%3")
0203                      .arg(i1.uoid())
0204                      .arg(dateStr)
0205                      .arg(replyStr);
0206     QCOMPARE_OR_DIFF(reply.msg->encodedContent(), ba.toUtf8());
0207 }
0208 
0209 void MessageFactoryTest::testCreateReplyToAllWithUseSenderAsync()
0210 {
0211     TemplateParser::TemplateParserSettings::self()->setTemplateReplyAll(QStringLiteral("%QUOTE"));
0212 
0213     const QString filename(QStringLiteral(MAIL_DATA_DIR) + QStringLiteral("/replyall_with_identity_message.mbox"));
0214     KMime::Message::Ptr msg = Test::loadMessage(filename);
0215     KIdentityManagementCore::Identity &i1 = mIdentMan->modifyIdentityForName(QStringLiteral("test1"));
0216     i1.setFullName(QStringLiteral("foo1"));
0217     i1.setPrimaryEmailAddress(QStringLiteral("identity1@bla.com"));
0218     KIdentityManagementCore::Identity &i2 = mIdentMan->modifyIdentityForName(QStringLiteral("test2"));
0219     i2.setFullName(QStringLiteral("foo2"));
0220     i2.setPrimaryEmailAddress(QStringLiteral("identity2@bla.com"));
0221     mIdentMan->commit();
0222 
0223     MessageFactoryNG factory(msg, 0);
0224     factory.setReplyStrategy(ReplyAll);
0225     factory.setIdentityManager(mIdentMan);
0226 
0227     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0228 
0229     factory.createReplyAsync();
0230     QVERIFY(spy.wait());
0231     QCOMPARE(spy.count(), 1);
0232 
0233     auto reply = spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0234     reply.replyAll = true;
0235 
0236     QString replyStr = QStringLiteral("> This is a mail for testing replyall and sender");
0237     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: Plain Message Test"));
0238     QCOMPARE_OR_DIFF(reply.msg->body(), replyStr.toUtf8());
0239 
0240     QString dateStr = reply.msg->date()->asUnicodeString();
0241     QString ba = QString::fromLatin1(
0242                      "From: another <another@another.com>\n"
0243                      "Date: %1\n"
0244                      "Cc: blu <blu@blu.org>, bly <bly@bly.org>\n"
0245                      "To: blo <blo@blo.org>, bli <bli@bli.org>\n"
0246                      "Subject: Re: Plain Message Test\n"
0247                      "Content-Type: text/plain; charset=\"UTF-8\"\n"
0248                      "Content-Transfer-Encoding: 8Bit\nMIME-Version: 1.0\n"
0249                      "X-KMail-Link-Message: 0\n"
0250                      "X-KMail-Link-Type: reply\n\n"
0251                      "%2")
0252                      .arg(dateStr)
0253                      .arg(replyStr);
0254     QCOMPARE_OR_DIFF(reply.msg->encodedContent(), ba.toUtf8());
0255 }
0256 
0257 void MessageFactoryTest::testCreateReplyToAllWithUseSenderByNoSameIdentitiesAsync()
0258 {
0259     TemplateParser::TemplateParserSettings::self()->setTemplateReplyAll(QStringLiteral("%QUOTE"));
0260 
0261     const QString filename(QStringLiteral(MAIL_DATA_DIR) + QStringLiteral("/replyall_without_identity_message.mbox"));
0262     KMime::Message::Ptr msg = Test::loadMessage(filename);
0263     KIdentityManagementCore::Identity &i1 = mIdentMan->modifyIdentityForName(QStringLiteral("test1"));
0264     i1.setFullName(QStringLiteral("foo1"));
0265     i1.setPrimaryEmailAddress(QStringLiteral("identity1@bla.com"));
0266     KIdentityManagementCore::Identity &i2 = mIdentMan->modifyIdentityForName(QStringLiteral("test2"));
0267     i2.setFullName(QStringLiteral("foo2"));
0268     i2.setPrimaryEmailAddress(QStringLiteral("identity2@bla.com"));
0269     mIdentMan->commit();
0270 
0271     MessageFactoryNG factory(msg, 0);
0272     factory.setReplyStrategy(ReplyAll);
0273     factory.setIdentityManager(mIdentMan);
0274 
0275     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0276 
0277     factory.createReplyAsync();
0278     QVERIFY(spy.wait());
0279     QCOMPARE(spy.count(), 1);
0280 
0281     auto reply = spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0282     reply.replyAll = true;
0283 
0284     QString replyStr = QStringLiteral("> This is a mail for testing replyall and sender");
0285     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: Plain Message Test"));
0286     QCOMPARE_OR_DIFF(reply.msg->body(), replyStr.toUtf8());
0287 
0288     QString dateStr = reply.msg->date()->asUnicodeString();
0289     QString ba = QString::fromLatin1(
0290                      "From: another <another@another.com>\n"
0291                      "Date: %1\n"
0292                      "Cc: blu <blu@blu.org>, bly <bly@bly.org>\n"
0293                      "To: blo <blo@blo.org>, bli <bli@bli.org>, Bla <bloblo@bla.com>\n"
0294                      "Subject: Re: Plain Message Test\n"
0295                      "Content-Type: text/plain; charset=\"UTF-8\"\n"
0296                      "Content-Transfer-Encoding: 8Bit\nMIME-Version: 1.0\n"
0297                      "X-KMail-Link-Message: 0\n"
0298                      "X-KMail-Link-Type: reply\n\n"
0299                      "%2")
0300                      .arg(dateStr)
0301                      .arg(replyStr);
0302     QCOMPARE_OR_DIFF(reply.msg->encodedContent(), ba.toUtf8());
0303 }
0304 
0305 void MessageFactoryTest::testCreateReplyToListAsync()
0306 {
0307     TemplateParser::TemplateParserSettings::self()->setTemplateReplyAll(QStringLiteral("%QUOTE"));
0308 
0309     const QString filename(QStringLiteral(MAIL_DATA_DIR) + QStringLiteral("/list_message.mbox"));
0310     KMime::Message::Ptr msg = Test::loadMessage(filename);
0311 
0312     MessageFactoryNG factory(msg, 0);
0313     factory.setIdentityManager(mIdentMan);
0314     factory.setReplyStrategy(ReplyList);
0315 
0316     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0317 
0318     factory.createReplyAsync();
0319     QVERIFY(spy.wait());
0320     QCOMPARE(spy.count(), 1);
0321 
0322     auto reply = spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0323     reply.replyAll = true;
0324 
0325     QDateTime date = msg->date()->dateTime();
0326     QString datetime = QLocale::system().toString(date.date(), QLocale::LongFormat);
0327     datetime += QLatin1Char(' ') + QLocale::system().toString(date.time(), QLocale::LongFormat);
0328     QString replyStr = QString::fromLatin1(QByteArray("> This is a mail from ML"));
0329     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: Plain Message Test"));
0330     QCOMPARE_OR_DIFF(reply.msg->body(), replyStr.toUtf8());
0331     QString dateStr = reply.msg->date()->asUnicodeString();
0332     QString ba = QString::fromLatin1(
0333                      "From: another <another@another.com>\n"
0334                      "Date: %1\n"
0335                      "To: list@list.org\n"
0336                      "Subject: Re: Plain Message Test\n"
0337                      "Content-Type: text/plain; charset=\"UTF-8\"\n"
0338                      "Content-Transfer-Encoding: 8Bit\nMIME-Version: 1.0\n"
0339                      "X-KMail-Link-Message: 0\n"
0340                      "X-KMail-Link-Type: reply\n\n"
0341                      "%2")
0342                      .arg(dateStr)
0343                      .arg(replyStr);
0344     QCOMPARE_OR_DIFF(reply.msg->encodedContent(), ba.toUtf8());
0345 }
0346 
0347 void MessageFactoryTest::testCreateReplyToAuthorAsync()
0348 {
0349     KMime::Message::Ptr msg = createPlainTestMessage();
0350 
0351     MessageFactoryNG factory(msg, 0);
0352     factory.setIdentityManager(mIdentMan);
0353     factory.setReplyStrategy(ReplyAuthor);
0354 
0355     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0356 
0357     factory.createReplyAsync();
0358     QVERIFY(spy.wait());
0359     QCOMPARE(spy.count(), 1);
0360 
0361     auto reply = spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0362     reply.replyAll = true;
0363 
0364     QDateTime date = msg->date()->dateTime();
0365     QString datetime = QLocale::system().toString(date.date(), QLocale::LongFormat);
0366     datetime += QLatin1Char(' ') + QLocale::system().toString(date.time(), QLocale::LongFormat);
0367     QString replyStr = QString::fromUtf8(QByteArray(
0368         QByteArray("On ") + datetime.toUtf8() + QByteArray(" you wrote:\n> All happy families are alike; each unhappy family is unhappy in its own way.\n\n")));
0369     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: Test Email Subject"));
0370     QCOMPARE_OR_DIFF(reply.msg->body(), replyStr.toUtf8());
0371     QString replyTo = reply.msg->inReplyTo()->asUnicodeString();
0372     QString reference = reply.msg->references()->asUnicodeString();
0373     QString dateStr = reply.msg->date()->asUnicodeString();
0374     QString ba = QString::fromLatin1(
0375                      "From: another <another@another.com>\n"
0376                      "Date: %1\n"
0377                      "X-KMail-Transport: 0\n"
0378                      "To: me@me.me\n"
0379                      "References: %3\n"
0380                      "In-Reply-To: %2\n"
0381                      "Subject: Re: Test Email Subject\n"
0382                      "X-KMail-CursorPos: %5\n"
0383                      "Content-Type: text/plain; charset=\"UTF-8\"\n"
0384                      "Content-Transfer-Encoding: 8Bit\nMIME-Version: 1.0\n"
0385                      "X-KMail-Link-Message: 0\n"
0386                      "X-KMail-Link-Type: reply\n\n"
0387                      "%4")
0388                      .arg(dateStr)
0389                      .arg(replyTo)
0390                      .arg(reference)
0391                      .arg(replyStr)
0392                      .arg(replyStr.length() - 1);
0393     QCOMPARE_OR_DIFF(reply.msg->encodedContent(), ba.toUtf8());
0394     msg.clear();
0395 }
0396 
0397 void MessageFactoryTest::testCreateReplyAllWithMultiEmailsAsync()
0398 {
0399     KMime::Message::Ptr msg = createPlainTestMessageWithMultiEmails();
0400 
0401     TemplateParser::TemplateParserSettings::self()->setTemplateReplyAll(QStringLiteral("%QUOTE"));
0402 
0403     MessageFactoryNG factory(msg, 0);
0404     factory.setIdentityManager(mIdentMan);
0405     factory.setReplyStrategy(ReplyAll);
0406 
0407     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0408 
0409     factory.createReplyAsync();
0410     QVERIFY(spy.wait());
0411     QCOMPARE(spy.count(), 1);
0412 
0413     auto reply = spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0414     reply.replyAll = true;
0415 
0416     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: Test Email Subject"));
0417 
0418     QString replyTo = reply.msg->inReplyTo()->asUnicodeString();
0419     QString reference = reply.msg->references()->asUnicodeString();
0420     QString dateStr = reply.msg->date()->asUnicodeString();
0421     QString ba = QString::fromLatin1(
0422                      "From: another <another@another.com>\n"
0423                      "Date: %1\n"
0424                      "X-KMail-Transport: 0\n"
0425                      "Cc: cc@cc.cc, cc2@cc.cc\n"
0426                      "To: you@you.you, you2@you.you, me@me.me\n"
0427                      "References: %3\n"
0428                      "In-Reply-To: %2\n"
0429                      "Subject: Re: Test Email Subject\nContent-Type: text/plain; charset=\"UTF-8\"\n"
0430                      "Content-Transfer-Encoding: 8Bit\nMIME-Version: 1.0\n"
0431                      "X-KMail-Link-Message: 0\n"
0432                      "X-KMail-Link-Type: reply\n\n> All happy families are alike; each unhappy family is unhappy in its own way.")
0433                      .arg(dateStr, replyTo, reference);
0434     QCOMPARE_OR_DIFF(reply.msg->encodedContent(), ba.toUtf8());
0435     msg.clear();
0436 }
0437 
0438 void MessageFactoryTest::testCreateReplyAllAsync()
0439 {
0440     KMime::Message::Ptr msg = createPlainTestMessage();
0441     MessageFactoryNG factory(msg, 0);
0442     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0443     factory.setIdentityManager(mIdentMan);
0444 
0445     factory.createReplyAsync();
0446     QVERIFY(spy.wait());
0447     QCOMPARE(spy.count(), 1);
0448     auto reply = spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0449     reply.replyAll = true;
0450 
0451     QDateTime date = msg->date()->dateTime();
0452     QString datetime = QLocale::system().toString(date.date(), QLocale::LongFormat);
0453     datetime += QLatin1Char(' ') + QLocale::system().toString(date.time(), QLocale::LongFormat);
0454     QString replyStr = QString::fromUtf8(QByteArray(
0455         QByteArray("On ") + datetime.toUtf8() + QByteArray(" you wrote:\n> All happy families are alike; each unhappy family is unhappy in its own way.\n\n")));
0456     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: Test Email Subject"));
0457     QCOMPARE_OR_DIFF(reply.msg->body(), replyStr.toUtf8());
0458     msg.clear();
0459 }
0460 
0461 void MessageFactoryTest::testCreateReplyHtmlAsync()
0462 {
0463     KMime::Message::Ptr msg = Test::loadMessageFromDataDir(QStringLiteral("html_utf8_encoded.mbox"));
0464 
0465     // qDebug() << "html message:" << msg->encodedContent();
0466 
0467     MessageFactoryNG factory(msg, 0);
0468     factory.setIdentityManager(mIdentMan);
0469     TemplateParser::TemplateParserSettings::self()->setReplyUsingVisualFormat(true);
0470     factory.setReplyAsHtml(true);
0471 
0472     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0473     factory.setIdentityManager(mIdentMan);
0474 
0475     factory.createReplyAsync();
0476     QVERIFY(spy.wait());
0477     QCOMPARE(spy.count(), 1);
0478     auto reply = spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0479     reply.replyAll = true;
0480 
0481     QDateTime date = msg->date()->dateTime().toLocalTime();
0482     QString datetime = QLocale().toString(date.date(), QLocale::LongFormat);
0483     datetime += QLatin1Char(' ') + QLocale().toString(date.time(), QLocale::LongFormat);
0484     QString replyStr = QString::fromUtf8(QByteArray(QByteArray("On ") + datetime.toUtf8() + QByteArray(" you wrote:\n> encoded?\n\n")));
0485     QCOMPARE(reply.msg->contentType()->mimeType(), QByteArrayLiteral("multipart/alternative"));
0486     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: reply to please"));
0487     QCOMPARE(reply.msg->contents().count(), 2);
0488     QCOMPARE_OR_DIFF(reply.msg->contents().at(0)->body(), replyStr.toUtf8());
0489 
0490     TemplateParser::TemplateParserSettings::self()->setReplyUsingVisualFormat(false);
0491     factory.setReplyAsHtml(false);
0492 
0493     factory.createReplyAsync();
0494     QVERIFY(spy.wait());
0495     QCOMPARE(spy.count(), 2);
0496     reply = spy.at(1).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0497 
0498     reply.replyAll = true;
0499     datetime = QLocale::system().toString(date.date(), QLocale::LongFormat);
0500     datetime += QLatin1Char(' ') + QLocale::system().toString(date.time(), QLocale::LongFormat);
0501     QCOMPARE(reply.msg->contentType()->mimeType(), QByteArrayLiteral("text/plain"));
0502     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: reply to please"));
0503     QCOMPARE(reply.msg->contents().count(), 0);
0504     msg.clear();
0505 }
0506 
0507 void MessageFactoryTest::testCreateReplyUTF16Base64Async()
0508 {
0509     KMime::Message::Ptr msg = Test::loadMessageFromDataDir(QStringLiteral("plain_utf16.mbox"));
0510     MessageFactoryNG factory(msg, 0);
0511     factory.setIdentityManager(mIdentMan);
0512 
0513     TemplateParser::TemplateParserSettings::self()->setReplyUsingVisualFormat(true);
0514     factory.setReplyAsHtml(true);
0515 
0516     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0517     factory.setIdentityManager(mIdentMan);
0518 
0519     factory.createReplyAsync();
0520     QVERIFY(spy.wait());
0521     QCOMPARE(spy.count(), 1);
0522     auto reply = spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0523     reply.replyAll = true;
0524 
0525     QDateTime date = msg->date()->dateTime().toLocalTime();
0526     QString datetime = QLocale().toString(date.date(), QLocale::LongFormat);
0527     datetime += QLatin1Char(' ') + QLocale().toString(date.time(), QLocale::LongFormat);
0528     QString replyStr = QString::fromUtf8(QByteArray(QByteArray("On ") + datetime.toUtf8() + QByteArray(" you wrote:\n> quote me please.\n\n")));
0529     QCOMPARE(reply.msg->contentType()->mimeType(), QByteArrayLiteral("multipart/alternative"));
0530     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: asking for reply"));
0531     QCOMPARE_OR_DIFF(reply.msg->contents().at(0)->body(), replyStr.toUtf8());
0532     msg.clear();
0533 }
0534 
0535 void MessageFactoryTest::testCreateForwardMultiEmailsAsync()
0536 {
0537     KMime::Message::Ptr msg = createPlainTestMessageWithMultiEmails();
0538 
0539     MessageFactoryNG factory(msg, 0);
0540     factory.setIdentityManager(mIdentMan);
0541     QSignalSpy spy(&factory, &MessageFactoryNG::createForwardDone);
0542     factory.createForwardAsync();
0543     QVERIFY(spy.wait());
0544     QCOMPARE(spy.count(), 1);
0545 
0546     auto fw = spy.at(0).at(0).value<KMime::Message::Ptr>();
0547     QDateTime date = msg->date()->dateTime();
0548     QString datetime = QLocale::system().toString(date.date(), QLocale::LongFormat);
0549     datetime += QLatin1StringView(", ") + QLocale::system().toString(date.time(), QLocale::LongFormat);
0550 
0551     QString fwdMsg = QString::fromLatin1(
0552         "From: another <another@another.com>\n"
0553         "Date: %2\n"
0554         "X-KMail-Transport: 0\n"
0555         "MIME-Version: 1.0\n"
0556         "Subject: Fwd: Test Email Subject\n"
0557         "Content-Type: text/plain; charset=\"UTF-8\"\n"
0558         "Content-Transfer-Encoding: 8Bit\n"
0559         "X-KMail-Link-Message: 0\n"
0560         "X-KMail-Link-Type: forward\n"
0561         "\n"
0562         "----------  Forwarded Message  ----------\n"
0563         "\n"
0564         "Subject: Test Email Subject\n"
0565         "Date: %1\n"
0566         "From: me@me.me\n"
0567         "To: you@you.you, you2@you.you\n"
0568         "CC: cc@cc.cc, cc2@cc.cc\n"
0569         "\n"
0570         "All happy families are alike; each unhappy family is unhappy in its own way.\n"
0571         "-----------------------------------------");
0572     fwdMsg = fwdMsg.arg(datetime).arg(fw->date()->asUnicodeString());
0573 
0574     QCOMPARE(fw->subject()->asUnicodeString(), QStringLiteral("Fwd: Test Email Subject"));
0575     QCOMPARE_OR_DIFF(fw->encodedContent(), fwdMsg.toUtf8());
0576     msg.clear();
0577 }
0578 
0579 void MessageFactoryTest::testCreateForwardAsync()
0580 {
0581     KMime::Message::Ptr msg = createPlainTestMessage();
0582 
0583     MessageFactoryNG factory(msg, 0);
0584     factory.setIdentityManager(mIdentMan);
0585     QSignalSpy spy(&factory, &MessageFactoryNG::createForwardDone);
0586     factory.createForwardAsync();
0587     QVERIFY(spy.wait());
0588     QCOMPARE(spy.count(), 1);
0589 
0590     auto fw = spy.at(0).at(0).value<KMime::Message::Ptr>();
0591 
0592     QDateTime date = msg->date()->dateTime();
0593     QString datetime = QLocale::system().toString(date.date(), QLocale::LongFormat);
0594     datetime += QLatin1StringView(", ") + QLocale::system().toString(date.time(), QLocale::LongFormat);
0595 
0596     QString fwdMsg = QString::fromLatin1(
0597         "From: another <another@another.com>\n"
0598         "Date: %2\n"
0599         "X-KMail-Transport: 0\n"
0600         "MIME-Version: 1.0\n"
0601         "Subject: Fwd: Test Email Subject\n"
0602         "Content-Type: text/plain; charset=\"UTF-8\"\n"
0603         "Content-Transfer-Encoding: 8Bit\n"
0604         "X-KMail-Link-Message: 0\n"
0605         "X-KMail-Link-Type: forward\n"
0606         "\n"
0607         "----------  Forwarded Message  ----------\n"
0608         "\n"
0609         "Subject: Test Email Subject\n"
0610         "Date: %1\n"
0611         "From: me@me.me\n"
0612         "To: you@you.you\n"
0613         "CC: cc@cc.cc\n"
0614         "\n"
0615         "All happy families are alike; each unhappy family is unhappy in its own way.\n"
0616         "-----------------------------------------");
0617     fwdMsg = fwdMsg.arg(datetime).arg(fw->date()->asUnicodeString());
0618 
0619     QCOMPARE(fw->subject()->asUnicodeString(), QStringLiteral("Fwd: Test Email Subject"));
0620     QCOMPARE_OR_DIFF(fw->encodedContent(), fwdMsg.toUtf8());
0621     msg.clear();
0622 }
0623 
0624 void MessageFactoryTest::testCreateRedirectToAndCCAndBCC()
0625 {
0626     KMime::Message::Ptr msg = createPlainTestMessage();
0627 
0628     MessageFactoryNG factory(msg, 0);
0629     factory.setIdentityManager(mIdentMan);
0630 
0631     QString redirectTo = QStringLiteral("redir@redir.com");
0632     QString redirectCc = QStringLiteral("redircc@redircc.com, redircc2@redircc.com");
0633     QString redirectBcc = QStringLiteral("redirbcc@redirbcc.com, redirbcc2@redirbcc.com");
0634     KMime::Message::Ptr rdir = factory.createRedirect(redirectTo, redirectCc, redirectBcc);
0635 
0636     QString datetime = rdir->date()->asUnicodeString();
0637 
0638     const QRegularExpression rx(QStringLiteral("Resent-Message-ID: ([^\n]*)"));
0639     const QRegularExpressionMatch rxMatch = rx.match(QString::fromLatin1(rdir->head()));
0640     QVERIFY(rxMatch.hasMatch());
0641 
0642     const QRegularExpression rxmessageid(QStringLiteral("Message-ID: ([^\n]+)"));
0643     const QRegularExpressionMatch rxmessageidMatch = rxmessageid.match(QString::fromLatin1(rdir->head()));
0644     QVERIFY(rxmessageidMatch.hasMatch());
0645 
0646     QString baseline = QString::fromLatin1(
0647         "From: me@me.me\n"
0648         "Cc: cc@cc.cc\n"
0649         "Bcc: bcc@bcc.bcc\n"
0650         "Subject: Test Email Subject\n"
0651         "Date: %1\n"
0652         "X-KMail-Transport: 0\n"
0653         "Message-ID: %2\n"
0654         "Disposition-Notification-To: me@me.me\n"
0655         "MIME-Version: 1.0\n"
0656         "Content-Transfer-Encoding: 7Bit\n"
0657         "Content-Type: text/plain; charset=\"us-ascii\"\n"
0658         "Resent-Message-ID: %3\n"
0659         "Resent-Date: %4\n"
0660         "Resent-From: %5\n"
0661         "To: you@you.you\n"
0662         "Resent-To: redir@redir.com\n"
0663         "Resent-Cc: redircc@redircc.com, redircc2@redircc.com\n"
0664         "Resent-Bcc: redirbcc@redirbcc.com, redirbcc2@redirbcc.com\n"
0665         "X-KMail-Redirect-From: me@me.me (by way of another <another@another.com>)\n"
0666         "\n"
0667         "All happy families are alike; each unhappy family is unhappy in its own way.");
0668     baseline =
0669         baseline.arg(datetime).arg(rxmessageidMatch.captured(1)).arg(rxMatch.captured(1)).arg(datetime).arg(QStringLiteral("another <another@another.com>"));
0670 
0671     QCOMPARE(rdir->subject()->asUnicodeString(), QStringLiteral("Test Email Subject"));
0672     QCOMPARE_OR_DIFF(rdir->encodedContent(), baseline.toUtf8());
0673     msg.clear();
0674 }
0675 
0676 void MessageFactoryTest::testCreateRedirectToAndCC()
0677 {
0678     KMime::Message::Ptr msg = createPlainTestMessage();
0679 
0680     MessageFactoryNG factory(msg, 0);
0681     factory.setIdentityManager(mIdentMan);
0682 
0683     QString redirectTo = QStringLiteral("redir@redir.com");
0684     QString redirectCc = QStringLiteral("redircc@redircc.com, redircc2@redircc.com");
0685     KMime::Message::Ptr rdir = factory.createRedirect(redirectTo, redirectCc);
0686 
0687     QString datetime = rdir->date()->asUnicodeString();
0688 
0689     const QRegularExpression rx(QStringLiteral("Resent-Message-ID: ([^\n]*)"));
0690     const QRegularExpressionMatch rxMatch = rx.match(QString::fromLatin1(rdir->head()));
0691     QVERIFY(rxMatch.hasMatch());
0692 
0693     const QRegularExpression rxmessageid(QStringLiteral("Message-ID: ([^\n]+)"));
0694     const QRegularExpressionMatch rxmessageidMatch = rxmessageid.match(QString::fromLatin1(rdir->head()));
0695     QVERIFY(rxmessageidMatch.hasMatch());
0696 
0697     // qWarning() << "messageid:" << rxmessageid.cap(1) << "(" << rdir->head() << ")";
0698     QString baseline = QString::fromLatin1(
0699         "From: me@me.me\n"
0700         "Cc: cc@cc.cc\n"
0701         "Bcc: bcc@bcc.bcc\n"
0702         "Subject: Test Email Subject\n"
0703         "Date: %1\n"
0704         "X-KMail-Transport: 0\n"
0705         "Message-ID: %2\n"
0706         "Disposition-Notification-To: me@me.me\n"
0707         "MIME-Version: 1.0\n"
0708         "Content-Transfer-Encoding: 7Bit\n"
0709         "Content-Type: text/plain; charset=\"us-ascii\"\n"
0710         "Resent-Message-ID: %3\n"
0711         "Resent-Date: %4\n"
0712         "Resent-From: %5\n"
0713         "To: you@you.you\n"
0714         "Resent-To: redir@redir.com\n"
0715         "Resent-Cc: redircc@redircc.com, redircc2@redircc.com\n"
0716         "X-KMail-Redirect-From: me@me.me (by way of another <another@another.com>)\n"
0717         "\n"
0718         "All happy families are alike; each unhappy family is unhappy in its own way.");
0719     baseline =
0720         baseline.arg(datetime).arg(rxmessageidMatch.captured(1)).arg(rxMatch.captured(1)).arg(datetime).arg(QStringLiteral("another <another@another.com>"));
0721 
0722     QCOMPARE(rdir->subject()->asUnicodeString(), QStringLiteral("Test Email Subject"));
0723     QCOMPARE_OR_DIFF(rdir->encodedContent(), baseline.toUtf8());
0724     msg.clear();
0725 }
0726 
0727 void MessageFactoryTest::testCreateRedirect()
0728 {
0729     KMime::Message::Ptr msg = createPlainTestMessage();
0730 
0731     MessageFactoryNG factory(msg, 0);
0732     factory.setIdentityManager(mIdentMan);
0733 
0734     QString redirectTo = QStringLiteral("redir@redir.com");
0735     KMime::Message::Ptr rdir = factory.createRedirect(redirectTo);
0736 
0737     QString datetime = rdir->date()->asUnicodeString();
0738 
0739     const QRegularExpression rx(QStringLiteral("Resent-Message-ID: ([^\n]*)"));
0740     const QRegularExpressionMatch rxMatch = rx.match(QString::fromLatin1(rdir->head()));
0741     QVERIFY(rxMatch.hasMatch());
0742 
0743     const QRegularExpression rxmessageid(QStringLiteral("Message-ID: ([^\n]+)"));
0744     const QRegularExpressionMatch rxmessageidMatch = rxmessageid.match(QString::fromLatin1(rdir->head()));
0745     QVERIFY(rxmessageidMatch.hasMatch());
0746 
0747     QString baseline = QString::fromLatin1(
0748         "From: me@me.me\n"
0749         "Cc: cc@cc.cc\n"
0750         "Bcc: bcc@bcc.bcc\n"
0751         "Subject: Test Email Subject\n"
0752         "Date: %1\n"
0753         "X-KMail-Transport: 0\n"
0754         "Message-ID: %2\n"
0755         "Disposition-Notification-To: me@me.me\n"
0756         "MIME-Version: 1.0\n"
0757         "Content-Transfer-Encoding: 7Bit\n"
0758         "Content-Type: text/plain; charset=\"us-ascii\"\n"
0759         "Resent-Message-ID: %3\n"
0760         "Resent-Date: %4\n"
0761         "Resent-From: %5\n"
0762         "To: you@you.you\n"
0763         "Resent-To: redir@redir.com\n"
0764         "X-KMail-Redirect-From: me@me.me (by way of another <another@another.com>)\n"
0765         "\n"
0766         "All happy families are alike; each unhappy family is unhappy in its own way.");
0767     baseline =
0768         baseline.arg(datetime).arg(rxmessageidMatch.captured(1)).arg(rxMatch.captured(1)).arg(datetime).arg(QStringLiteral("another <another@another.com>"));
0769 
0770     QCOMPARE(rdir->subject()->asUnicodeString(), QStringLiteral("Test Email Subject"));
0771     QCOMPARE_OR_DIFF(rdir->encodedContent(), baseline.toUtf8());
0772     msg.clear();
0773 }
0774 
0775 void MessageFactoryTest::testCreateResend()
0776 {
0777     KMime::Message::Ptr msg = createPlainTestMessage();
0778 
0779     MessageFactoryNG factory(msg, 0);
0780     factory.setIdentityManager(mIdentMan);
0781 
0782     KMime::Message::Ptr rdir = factory.createResend();
0783 
0784     QString datetime = rdir->date()->asUnicodeString();
0785 
0786     const QRegularExpression rx(QStringLiteral("Resent-Message-ID: ([^\n]*)"));
0787     const QRegularExpressionMatch rxMatch = rx.match(QString::fromLatin1(rdir->head()));
0788     QVERIFY(!rxMatch.hasMatch());
0789 
0790     const QRegularExpression rxmessageid(QStringLiteral("Message-ID: ([^\n]+)"));
0791     const QRegularExpressionMatch rxmessageidMatch = rxmessageid.match(QString::fromLatin1(rdir->head()));
0792     QVERIFY(rxmessageidMatch.hasMatch());
0793 
0794     QString baseline = QString::fromLatin1(
0795         "From: me@me.me\n"
0796         "To: %1\n"
0797         "Cc: cc@cc.cc\n"
0798         "Bcc: bcc@bcc.bcc\n"
0799         "Subject: Test Email Subject\n"
0800         "Date: %2\n"
0801         "X-KMail-Transport: 0\n"
0802         "Message-ID: %3\n"
0803         "Disposition-Notification-To: me@me.me\n"
0804         "MIME-Version: 1.0\n"
0805         "Content-Transfer-Encoding: 7Bit\n"
0806         "Content-Type: text/plain; charset=\"us-ascii\"\n"
0807         "\n"
0808         "All happy families are alike; each unhappy family is unhappy in its own way.");
0809     baseline = baseline.arg(msg->to()->asUnicodeString()).arg(datetime).arg(rxmessageidMatch.captured(1));
0810 
0811     QCOMPARE(rdir->subject()->asUnicodeString(), QStringLiteral("Test Email Subject"));
0812     QCOMPARE_OR_DIFF(rdir->encodedContent(), baseline.toUtf8());
0813     msg.clear();
0814 }
0815 
0816 void MessageFactoryTest::testCreateMDN()
0817 {
0818     KMime::Message::Ptr msg = createPlainTestMessage();
0819 
0820     MessageFactoryNG factory(msg, 0);
0821 
0822     factory.setIdentityManager(mIdentMan);
0823 
0824     KMime::Message::Ptr mdn = factory.createMDN(KMime::MDN::AutomaticAction, KMime::MDN::Displayed, KMime::MDN::SentAutomatically);
0825 
0826     QVERIFY(mdn.data());
0827 
0828     QString mdnContent = QString::fromLatin1(
0829         "The message sent on %1 to %2 with subject \"%3\" has been displayed. "
0830         "This is no guarantee that the message has been read or understood.");
0831     mdnContent = mdnContent.arg(KMime::DateFormatter::formatDate(KMime::DateFormatter::Localized, msg->date()->dateTime()))
0832                      .arg(msg->to()->asUnicodeString(), msg->subject()->asUnicodeString());
0833 
0834     QCOMPARE_OR_DIFF(Util::findTypeInMessage(mdn.data(), "multipart", "report")->contents().at(0)->body(), mdnContent.toUtf8());
0835     msg.clear();
0836 }
0837 
0838 KMime::Message::Ptr MessageFactoryTest::createPlainTestMessage()
0839 {
0840     auto composer = new Composer;
0841     composer->globalPart()->setFallbackCharsetEnabled(true);
0842     composer->infoPart()->setFrom(QStringLiteral("me@me.me"));
0843     composer->infoPart()->setTo(QStringList(QStringLiteral("you@you.you")));
0844     composer->infoPart()->setCc(QStringList(QStringLiteral("cc@cc.cc")));
0845     composer->infoPart()->setBcc(QStringList(QStringLiteral("bcc@bcc.bcc")));
0846     composer->textPart()->setWrappedPlainText(QStringLiteral("All happy families are alike; each unhappy family is unhappy in its own way."));
0847     composer->infoPart()->setSubject(QStringLiteral("Test Email Subject"));
0848     composer->globalPart()->setMDNRequested(true);
0849     composer->exec();
0850 
0851     KMime::Message::Ptr message = KMime::Message::Ptr(composer->resultMessages().first());
0852     delete composer;
0853 
0854     return message;
0855 }
0856 
0857 KMime::Message::Ptr MessageFactoryTest::createPlainTestMessageWithMultiEmails()
0858 {
0859     auto composer = new Composer;
0860     composer->globalPart()->setFallbackCharsetEnabled(true);
0861     composer->infoPart()->setFrom(QStringLiteral("me@me.me"));
0862     composer->infoPart()->setTo(QStringList() << QStringLiteral("you@you.you") << QStringLiteral("you2@you.you"));
0863     composer->infoPart()->setCc(QStringList() << QStringLiteral("cc@cc.cc") << QStringLiteral("cc2@cc.cc"));
0864     composer->infoPart()->setBcc(QStringList() << QStringLiteral("bcc@bcc.bcc") << QStringLiteral("bcc2@bcc.bcc"));
0865     composer->textPart()->setWrappedPlainText(QStringLiteral("All happy families are alike; each unhappy family is unhappy in its own way."));
0866     composer->infoPart()->setSubject(QStringLiteral("Test Email Subject"));
0867     composer->globalPart()->setMDNRequested(true);
0868     composer->exec();
0869 
0870     const KMime::Message::Ptr message = KMime::Message::Ptr(composer->resultMessages().constFirst());
0871     delete composer;
0872 
0873     return message;
0874 }
0875 
0876 void MessageFactoryTest::test_multipartAlternative_data()
0877 {
0878     QTest::addColumn<QString>("mailFileName");
0879     QTest::addColumn<int>("contentAt");
0880     QTest::addColumn<QString>("selection");
0881     QTest::addColumn<QString>("expected");
0882 
0883     QDir dir(QStringLiteral(MAIL_DATA_DIR));
0884     const QStringList lst = dir.entryList(QStringList(QStringLiteral("plain_message.mbox")), QDir::Files | QDir::Readable | QDir::NoSymLinks);
0885     for (const QString &file : lst) {
0886         QTest::newRow(file.toLatin1().constData()) << QString(dir.path() + QLatin1Char('/') + file) << 0 << ""
0887                                                    << "> This *is* the *message* text *from* Sudhendu Kumar<dontspamme@yoohoo.com>\n"
0888                                                       "> \n"
0889                                                       "> --\n"
0890                                                       "> Thanks & Regards\n"
0891                                                       "> Sudhendu Kumar";
0892         QTest::newRow(file.toLatin1().constData())
0893             << QString(dir.path() + QLatin1Char('/') + file) << 1 << ""
0894             << "<html><head></head><body>"
0895                "<blockquote>This <i>is</i> the <b>message</b> text <u>from</u> Sudhendu Kumar&lt;dontspamme@yoohoo.com&gt;<br>"
0896                "<br>-- <br>Thanks &amp; Regards<br>Sudhendu Kumar<br><br></blockquote><br/></body></html>";
0897 
0898         QTest::newRow(file.toLatin1().constData()) << QString(dir.path() + QLatin1Char('/') + file) << 0 << "This *is* the *message* text *from*"
0899                                                    << "> This *is* the *message* text *from*";
0900 
0901         QTest::newRow(file.toLatin1().constData())
0902             << QString(dir.path() + QLatin1Char('/') + file) << 1 << "This *is* the *message* text *from*"
0903             << "<html><head></head><body><blockquote>This *is* the *message* text *from*</blockquote><br/></body></html>";
0904     }
0905 }
0906 
0907 void MessageFactoryTest::test_multipartAlternative()
0908 {
0909     QFETCH(QString, mailFileName);
0910     QFETCH(int, contentAt);
0911     QFETCH(QString, selection);
0912     QFETCH(QString, expected);
0913 
0914     KMime::Message::Ptr origMsg = Test::loadMessage(mailFileName);
0915 
0916     MessageFactoryNG factory(origMsg, 0);
0917     factory.setIdentityManager(mIdentMan);
0918     factory.setSelection(selection);
0919     factory.setQuote(true);
0920     factory.setReplyStrategy(ReplyAll);
0921     TemplateParser::TemplateParserSettings::self()->setTemplateReplyAll(QStringLiteral("%QUOTE"));
0922     TemplateParser::TemplateParserSettings::self()->setReplyUsingVisualFormat(true);
0923     factory.setReplyAsHtml(true);
0924 
0925     QString str;
0926     str = TemplateParser::TemplateParserSettings::self()->templateReplyAll();
0927     factory.setTemplate(str);
0928 
0929     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0930 
0931     factory.createReplyAsync();
0932     QVERIFY(spy.wait());
0933     QCOMPARE(spy.count(), 1);
0934     auto reply = spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>();
0935     reply.replyAll = true;
0936     QCOMPARE(reply.msg->contentType()->mimeType(), QByteArrayLiteral("multipart/alternative"));
0937     QCOMPARE(reply.msg->subject()->asUnicodeString(), QLatin1StringView("Re: Plain Message Test"));
0938     QCOMPARE(reply.msg->contents().at(contentAt)->encodedBody().data(), expected.toUtf8().data());
0939     origMsg.clear();
0940 }
0941 
0942 KMime::Message::Ptr MessageFactoryTest::createReplyAllForMessage(KMime::Message::Ptr origMsg)
0943 {
0944     MessageFactoryNG factory(origMsg, 0);
0945     factory.setIdentityManager(mIdentMan);
0946     factory.setQuote(true);
0947     factory.setReplyStrategy(ReplyAll);
0948 
0949     QSignalSpy spy(&factory, &MessageFactoryNG::createReplyDone);
0950     factory.createReplyAsync();
0951     spy.wait();
0952     return spy.at(0).at(0).value<MessageComposer::MessageFactoryNG::MessageReply>().msg;
0953 }
0954 
0955 void MessageFactoryTest::testCreateReplyWithForcedCharset()
0956 {
0957     KMime::Message::Ptr origMsg(new KMime::Message);
0958     QByteArray origMail =
0959         "From: from@example.com\n"
0960         "To: to@example.com\n"
0961         "Sender: from@example.com\n"
0962         "Subject: Test\n"
0963         "Content-Type: text/plain; charset=iso-8859-1\n"
0964         "\n"
0965         "Test \xC4\n";
0966     origMsg->setContent(origMail);
0967     origMsg->parse();
0968 
0969     QCOMPARE(origMsg->contentType()->charset(), QByteArray("iso-8859-1"));
0970     QCOMPARE(origMsg->body(), QByteArray("Test \xC4\n"));
0971 
0972     TemplateParser::TemplateParserSettings::self()->setTemplateReplyAll(QString::fromUtf8("%QUOTE"));
0973 
0974     // The Euro symbol can't be encoded in ISO-8859-1, so it has to choose UTF-8 instead
0975     TemplateParser::TemplateParserSettings::self()->setTemplateReplyAll(QString::fromUtf8("\xE2\x82\xAC%QUOTE"));
0976 
0977     {
0978         // Use the preferred charset, UTF-8
0979         auto msg = createReplyAllForMessage(origMsg);
0980         QCOMPARE(msg->contentType()->charset(), QByteArray("UTF-8"));
0981         QCOMPARE(msg->body(), QByteArray("\xE2\x82\xAC> Test \xC3\x84"));
0982     }
0983 }
0984 
0985 #include "moc_messagefactoryngtest.cpp"