File indexing completed on 2025-03-09 04:54:32
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 "grantleeheaderstyletest.h" 0007 0008 #include <MessageViewer/GrantleeHeaderStyle> 0009 #include <MimeTreeParser/NodeHelper> 0010 0011 #include <GrantleeTheme/GrantleeThemeManager> 0012 0013 #include <QFile> 0014 #include <QProcess> 0015 #include <QRegularExpression> 0016 #include <QStandardPaths> 0017 #include <QStringList> 0018 #include <QTest> 0019 0020 using namespace MessageViewer; 0021 0022 QTEST_MAIN(GrantleeHeaderStyleTest) 0023 0024 void testHeaderFile(const HeaderStyle &style, KMime::Message *msg, const QString &name) 0025 { 0026 QString header = QStringLiteral( 0027 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" 0028 "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n" 0029 "<body>\n"); 0030 header += style.format(msg) + QStringLiteral("</div>"); 0031 header += QStringLiteral("\n</body>\n</html>\n"); 0032 0033 header.replace(QStringLiteral("file://") + style.theme().absolutePath(), QStringLiteral("file://PATHTOSTYLE")); 0034 header.replace(QRegularExpression(QStringLiteral("[\t ]+")), QStringLiteral(" ")); 0035 header.replace(QRegularExpression(QStringLiteral("[\t ]*\n+[\t ]*")), QStringLiteral("\n")); 0036 header.replace(QRegularExpression(QStringLiteral("([\n\t ])\\1+")), QStringLiteral("\\1")); 0037 header.replace(QRegularExpression(QStringLiteral(">\n+[\t ]*")), QStringLiteral(">")); 0038 header.replace(QRegularExpression(QStringLiteral("[\t ]*\n+[\t ]*<")), QStringLiteral("<")); 0039 header.replace(QLatin1StringView(" "), QLatin1StringView("NBSP_ENTITY_PLACEHOLDER")); // xmlling chokes on 0040 0041 QString outName = name + QStringLiteral(".out.html"); 0042 QString fName = name + QStringLiteral(".html"); 0043 0044 QVERIFY(QFile(QStringLiteral(HEADER_DATA_DIR "/") + fName).exists()); 0045 0046 { 0047 QFile f(outName); 0048 f.open(QIODevice::WriteOnly); 0049 f.write(header.toUtf8()); 0050 f.close(); 0051 } 0052 // TODO add proper cmake check for xmllint and diff 0053 { 0054 const QStringList args = QStringList() << QStringLiteral("--format") << QStringLiteral("--encode") << QStringLiteral("UTF8") 0055 << QStringLiteral("--output") << fName << outName; 0056 QCOMPARE(QProcess::execute(QStringLiteral("xmllint"), args), 0); 0057 } 0058 0059 { 0060 // compare to reference file 0061 const QStringList args = QStringList() << QStringLiteral("-u") << fName << QStringLiteral(HEADER_DATA_DIR "/") + fName; 0062 QProcess proc; 0063 proc.setProcessChannelMode(QProcess::ForwardedChannels); 0064 proc.start(QStringLiteral("diff"), args); 0065 QVERIFY(proc.waitForFinished()); 0066 0067 QCOMPARE(proc.exitCode(), 0); 0068 } 0069 } 0070 0071 KMime::Message::Ptr readAndParseMail(const QString &mailFile) 0072 { 0073 QFile file(QStringLiteral(HEADER_DATA_DIR) + QLatin1Char('/') + mailFile); 0074 bool openFile = file.open(QIODevice::ReadOnly); 0075 Q_ASSERT(openFile); 0076 const QByteArray data = KMime::CRLFtoLF(file.readAll()); 0077 Q_ASSERT(!data.isEmpty()); 0078 KMime::Message::Ptr msg(new KMime::Message); 0079 msg->setContent(data); 0080 msg->parse(); 0081 return msg; 0082 } 0083 0084 void GrantleeHeaderStyleTest::initTestCase() 0085 { 0086 qputenv("LC_ALL", "en_US.UTF-8"); 0087 QStandardPaths::setTestModeEnabled(true); 0088 expectedDataLocation = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); 0089 expectedDataLocation += QStringLiteral("/messageviewer/defaultthemes"); 0090 QDir targetDir(expectedDataLocation); 0091 QDir sourceDir(QStringLiteral(GRANTLEETHEME_DATA_DIR)); 0092 const auto themeDirs = sourceDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); 0093 0094 if (targetDir.exists()) { 0095 QVERIFY(targetDir.removeRecursively()); // Start with a fresh copy 0096 } 0097 0098 for (const auto &themeDir : themeDirs) { 0099 const QString &dirName = targetDir.filePath(themeDir.fileName()); 0100 QVERIFY(targetDir.mkpath(themeDir.fileName())); 0101 const auto files = QDir(themeDir.absoluteFilePath()).entryInfoList(QDir::Files | QDir::Readable | QDir::NoSymLinks); 0102 for (const auto &file : files) { 0103 const QString &newPath = dirName + QLatin1Char('/') + file.fileName(); 0104 QVERIFY(QFile(file.absoluteFilePath()).copy(newPath)); 0105 } 0106 } 0107 const auto configDir = QDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); 0108 if (!configDir.exists()) { 0109 QVERIFY(configDir.mkpath(QStringLiteral("."))); 0110 } 0111 QFile antispamFile(QStringLiteral(HEADER_DATA_DIR "/kmail.antispamrc")); 0112 const QString &newPath = configDir.filePath(QStringLiteral("kmail.antispamrc")); 0113 antispamFile.copy(newPath); 0114 } 0115 0116 void GrantleeHeaderStyleTest::cleanupTestCase() 0117 { 0118 QDir targetDir(expectedDataLocation); 0119 0120 if (targetDir.exists()) { 0121 QVERIFY(targetDir.removeRecursively()); // Start with a fresh copy 0122 } 0123 } 0124 0125 const GrantleeTheme::Theme defaultTheme(const QString &name = QStringLiteral("5.2")) 0126 { 0127 const QStringList defaultThemePath = 0128 QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("messageviewer/defaultthemes/"), QStandardPaths::LocateDirectory); 0129 return GrantleeTheme::ThemeManager::loadTheme(defaultThemePath.at(0) + QStringLiteral("/") + name, name, QStringLiteral("kmail_default.desktop")); 0130 } 0131 0132 void GrantleeHeaderStyleTest::testName() 0133 { 0134 auto style = GrantleeHeaderStyle(); 0135 QCOMPARE(style.name(), "grantlee"); 0136 } 0137 0138 void GrantleeHeaderStyleTest::testRenderHeaderNoMessage() 0139 { 0140 auto style = GrantleeHeaderStyle(); 0141 QCOMPARE(style.format(nullptr), QString()); 0142 } 0143 0144 void GrantleeHeaderStyleTest::testRenderHeaderInvalidTheme() 0145 { 0146 auto style = GrantleeHeaderStyle(); 0147 auto aMsg = new KMime::Message(); 0148 QCOMPARE(style.theme().isValid(), false); 0149 QCOMPARE(style.format(aMsg), QStringLiteral("Grantlee theme \"\" is not valid.")); 0150 delete aMsg; 0151 } 0152 0153 void GrantleeHeaderStyleTest::testRenderHeaderEmpty() 0154 { 0155 auto style = GrantleeHeaderStyle(); 0156 auto aMsg = new KMime::Message(); 0157 MimeTreeParser::NodeHelper nodeHelper; 0158 style.setTheme(defaultTheme()); 0159 style.setNodeHelper(&nodeHelper); 0160 0161 testHeaderFile(style, aMsg, QStringLiteral("empty")); 0162 delete aMsg; 0163 } 0164 0165 void GrantleeHeaderStyleTest::testRenderHeaderVCard() 0166 { 0167 auto style = GrantleeHeaderStyle(); 0168 auto aMsg = new KMime::Message(); 0169 MimeTreeParser::NodeHelper nodeHelper; 0170 style.setTheme(defaultTheme()); 0171 style.setNodeHelper(&nodeHelper); 0172 style.setVCardName(QStringLiteral("nofile.vcd")); 0173 0174 testHeaderFile(style, aMsg, QStringLiteral("vcard")); 0175 delete aMsg; 0176 } 0177 0178 void GrantleeHeaderStyleTest::testRenderHeader_data() 0179 { 0180 QTest::addColumn<QString>("mailFileName"); 0181 0182 QDir dir(QStringLiteral(HEADER_DATA_DIR)); 0183 const auto l = dir.entryList(QStringList(QStringLiteral("*.mbox")), QDir::Files | QDir::Readable | QDir::NoSymLinks); 0184 for (const QString &file : l) { 0185 if (!QFile::exists(dir.path() + QLatin1Char('/') + file + QStringLiteral(".html"))) { 0186 continue; 0187 } 0188 QTest::newRow(file.toLatin1().constData()) << file; 0189 } 0190 } 0191 0192 void GrantleeHeaderStyleTest::testRenderHeader() 0193 { 0194 QFETCH(QString, mailFileName); 0195 0196 auto style = GrantleeHeaderStyle(); 0197 MimeTreeParser::NodeHelper nodeHelper; 0198 style.setNodeHelper(&nodeHelper); 0199 auto aMsg = readAndParseMail(mailFileName); 0200 style.setTheme(defaultTheme()); 0201 0202 testHeaderFile(style, aMsg.data(), mailFileName); 0203 aMsg.clear(); 0204 } 0205 0206 #include "moc_grantleeheaderstyletest.cpp"