File indexing completed on 2025-03-09 04:54:31

0001 /*
0002    SPDX-FileCopyrightText: 2018 Sandro Knauß <sknauss@kde.org>
0003 
0004    SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 #include "grantleeheaderformattertest.h"
0007 
0008 #include "../grantleeheaderformatter.h"
0009 #include <MessageViewer/GrantleeHeaderStyle>
0010 #include <MimeTreeParser/NodeHelper>
0011 
0012 #include <QFile>
0013 #include <QProcess>
0014 #include <QRegularExpression>
0015 #include <QStandardPaths>
0016 #include <QStringList>
0017 #include <QTest>
0018 
0019 using namespace MessageViewer;
0020 
0021 QTEST_MAIN(GrantleeHeaderFormatterTest)
0022 
0023 GrantleeHeaderFormatterTest::GrantleeHeaderFormatterTest(QObject *parent)
0024     : QObject(parent)
0025 {
0026     qputenv("LC_ALL", "en_US.UTF-8");
0027     QStandardPaths::setTestModeEnabled(true);
0028 }
0029 
0030 void testHeaderFile(const QString &data, const QString &absolutePath, const QString &name)
0031 {
0032     QString header = QStringLiteral(
0033         "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"
0034         "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
0035         "<body>\n");
0036     header += data + QStringLiteral("</div>\n</div>");
0037     header += QStringLiteral("\n</body>\n</html>\n");
0038 
0039     header.replace(QStringLiteral("file://") + absolutePath, QStringLiteral("file://PATHTOSTYLE"));
0040     header.replace(QRegularExpression(QStringLiteral("[\t ]+")), QStringLiteral(" "));
0041     header.replace(QRegularExpression(QStringLiteral("[\t ]*\n+[\t ]*")), QStringLiteral("\n"));
0042     header.replace(QRegularExpression(QStringLiteral("([\n\t ])\\1+")), QStringLiteral("\\1"));
0043     header.replace(QRegularExpression(QStringLiteral(">\n+[\t ]*")), QStringLiteral(">"));
0044     header.replace(QRegularExpression(QStringLiteral("[\t ]*\n+[\t ]*<")), QStringLiteral("<"));
0045     header.replace(QLatin1StringView("&nbsp;"), QLatin1StringView("NBSP_ENTITY_PLACEHOLDER")); // xmlling chokes on &nbsp;
0046 
0047     QString outName = name + QStringLiteral(".out.html");
0048     QString fName = name + QStringLiteral(".html");
0049 
0050     QVERIFY(QFile(QStringLiteral(HEADER_DATA_DIR "/") + fName).exists());
0051 
0052     {
0053         QFile f(outName);
0054         f.open(QIODevice::WriteOnly);
0055         f.write(header.toUtf8());
0056         f.close();
0057     }
0058     // TODO add proper cmake check for xmllint and diff
0059     {
0060         const QStringList args = QStringList() << QStringLiteral("--format") << QStringLiteral("--encode") << QStringLiteral("UTF8")
0061                                                << QStringLiteral("--output") << fName << outName;
0062         QCOMPARE(QProcess::execute(QStringLiteral("xmllint"), args), 0);
0063     }
0064 
0065     {
0066         // compare to reference file
0067         const QStringList args = QStringList() << QStringLiteral("-u") << fName << QStringLiteral(HEADER_DATA_DIR "/") + fName;
0068         QProcess proc;
0069         proc.setProcessChannelMode(QProcess::ForwardedChannels);
0070         proc.start(QStringLiteral("diff"), args);
0071         QVERIFY(proc.waitForFinished());
0072 
0073         QCOMPARE(proc.exitCode(), 0);
0074     }
0075 }
0076 
0077 KMime::Message::Ptr readAndParseMail(const QString &mailFile)
0078 {
0079     QFile file(QStringLiteral(HEADER_DATA_DIR) + QLatin1Char('/') + mailFile);
0080     bool openFile = file.open(QIODevice::ReadOnly);
0081     Q_ASSERT(openFile);
0082     const QByteArray data = KMime::CRLFtoLF(file.readAll());
0083     Q_ASSERT(!data.isEmpty());
0084     KMime::Message::Ptr msg(new KMime::Message);
0085     msg->setContent(data);
0086     msg->parse();
0087     return msg;
0088 }
0089 
0090 void GrantleeHeaderFormatterTest::testInvalid()
0091 {
0092     auto style = GrantleeHeaderStyle();
0093     auto formatter = GrantleeHeaderFormatter();
0094     MimeTreeParser::NodeHelper nodeHelper;
0095     style.setNodeHelper(&nodeHelper);
0096     auto aMsg = readAndParseMail(QStringLiteral("allheaders.mbox"));
0097 
0098     QString filename = QStringLiteral("invalid");
0099     QString absolutePath = QStringLiteral(HEADER_DATA_DIR) + QLatin1Char('/') + filename;
0100     QString data = formatter.toHtml(QStringList(), absolutePath, filename, &style, aMsg.data(), false);
0101 
0102     QCOMPARE(data, QStringLiteral("Template not found, invalid"));
0103 }
0104 
0105 void GrantleeHeaderFormatterTest::testPrint()
0106 {
0107     QString tmplName = QStringLiteral("printtest.tmpl");
0108 
0109     auto style = GrantleeHeaderStyle();
0110     auto formatter = GrantleeHeaderFormatter();
0111     MimeTreeParser::NodeHelper nodeHelper;
0112     style.setNodeHelper(&nodeHelper);
0113     KMime::Message::Ptr aMsg(new KMime::Message);
0114 
0115     const QString &absolutePath = QStringLiteral(HEADER_DATA_DIR) + QLatin1Char('/') + tmplName;
0116 
0117     {
0118         const QString &data = formatter.toHtml(QStringList(), QStringLiteral(HEADER_DATA_DIR), tmplName, &style, aMsg.data(), false);
0119         testHeaderFile(QStringLiteral("<div><div>") + data, absolutePath, QStringLiteral("printtest.off"));
0120     }
0121 
0122     {
0123         const QString &data = formatter.toHtml(QStringList(), QStringLiteral(HEADER_DATA_DIR), tmplName, &style, aMsg.data(), true);
0124         testHeaderFile(QStringLiteral("<div><div>") + data, absolutePath, QStringLiteral("printtest.on"));
0125     }
0126 }
0127 
0128 void GrantleeHeaderFormatterTest::testFancyDate()
0129 {
0130     QString tmplName = QStringLiteral("fancydate.tmpl");
0131 
0132     auto style = GrantleeHeaderStyle();
0133     auto formatter = GrantleeHeaderFormatter();
0134     MimeTreeParser::NodeHelper nodeHelper;
0135     style.setNodeHelper(&nodeHelper);
0136     KMime::Message::Ptr msg(new KMime::Message);
0137 
0138     {
0139         auto datetime(QDateTime::currentDateTime());
0140         datetime.setTime(QTime(12, 34, 56));
0141         datetime = datetime.addDays(-1);
0142 
0143         const QByteArray data = "From: from@example.com\nDate: " + datetime.toString(Qt::RFC2822Date).toLocal8Bit() + "\nTo: to@example.com\n\ncontent";
0144         msg->setContent(KMime::CRLFtoLF(data));
0145         msg->parse();
0146     }
0147 
0148     const QString &absolutePath = QStringLiteral(HEADER_DATA_DIR) + QLatin1Char('/') + tmplName;
0149 
0150     const QString &data = formatter.toHtml(QStringList(), QStringLiteral(HEADER_DATA_DIR), tmplName, &style, msg.data(), false);
0151     testHeaderFile(QStringLiteral("<div><div>") + data, absolutePath, QStringLiteral("fancydate"));
0152 }
0153 
0154 void GrantleeHeaderFormatterTest::testBlock_data()
0155 {
0156     QTest::addColumn<QString>("tmplName");
0157 
0158     QDir dir(QStringLiteral(HEADER_DATA_DIR));
0159     const auto l = dir.entryList(QStringList(QStringLiteral("*.tmpl")), QDir::Files | QDir::Readable | QDir::NoSymLinks);
0160     for (const QString &file : l) {
0161         if (!QFile::exists(dir.path() + QLatin1Char('/') + file + QStringLiteral(".html"))) {
0162             continue;
0163         }
0164         QTest::newRow(file.toLatin1().constData()) << file;
0165     }
0166 }
0167 
0168 void GrantleeHeaderFormatterTest::testBlock()
0169 {
0170     QFETCH(QString, tmplName);
0171 
0172     auto style = GrantleeHeaderStyle();
0173     auto formatter = GrantleeHeaderFormatter();
0174     MimeTreeParser::NodeHelper nodeHelper;
0175     style.setNodeHelper(&nodeHelper);
0176     auto aMsg = readAndParseMail(QStringLiteral("headertest.mbox"));
0177 
0178     QString absolutePath = QStringLiteral(HEADER_DATA_DIR) + QLatin1Char('/') + tmplName;
0179     QString data = formatter.toHtml(QStringList(), QStringLiteral(HEADER_DATA_DIR), tmplName, &style, aMsg.data(), false);
0180 
0181     testHeaderFile(QStringLiteral("<div><div>") + data, absolutePath, tmplName);
0182 }
0183 
0184 #include "moc_grantleeheaderformattertest.cpp"