File indexing completed on 2024-12-01 04:35:28
0001 /* 0002 SPDX-FileCopyrightText: 2005 Ingo Kloecker <kloecker@kde.org> 0003 SPDX-FileCopyrightText: 2007 Allen Winter <winter@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only 0006 */ 0007 0008 #include "ruqolaktexttohtmltest.h" 0009 0010 #include "ktexttohtmlfork/ruqolaktexttohtml.h" 0011 #include "ktexttohtmlfork/ruqolaktexttohtml_p.h" 0012 0013 #include <QDebug> 0014 #include <QTest> 0015 #include <QUrl> 0016 0017 QTEST_MAIN(KTextToHTMLTest) 0018 0019 Q_DECLARE_METATYPE(RuqolaKTextToHTML::Options) 0020 0021 #ifndef Q_OS_WIN 0022 void initLocale() 0023 { 0024 setenv("LC_ALL", "en_US.utf-8", 1); 0025 } 0026 Q_CONSTRUCTOR_FUNCTION(initLocale) 0027 #endif 0028 0029 void KTextToHTMLTest::testGetEmailAddress() 0030 { 0031 // empty input 0032 const QString emptyQString; 0033 KTextToHTMLHelper ll1(emptyQString, 0); 0034 QVERIFY(ll1.getEmailAddress().isEmpty()); 0035 0036 // no '@' at scan position 0037 KTextToHTMLHelper ll2(QStringLiteral("foo@bar.baz"), 0); 0038 QVERIFY(ll2.getEmailAddress().isEmpty()); 0039 0040 // '@' in local part 0041 KTextToHTMLHelper ll3(QStringLiteral("foo@bar@bar.baz"), 7); 0042 QVERIFY(ll3.getEmailAddress().isEmpty()); 0043 0044 // empty local part 0045 KTextToHTMLHelper ll4(QStringLiteral("@bar.baz"), 0); 0046 QVERIFY(ll4.getEmailAddress().isEmpty()); 0047 KTextToHTMLHelper ll5(QStringLiteral(".@bar.baz"), 1); 0048 QVERIFY(ll5.getEmailAddress().isEmpty()); 0049 KTextToHTMLHelper ll6(QStringLiteral(" @bar.baz"), 1); 0050 QVERIFY(ll6.getEmailAddress().isEmpty()); 0051 KTextToHTMLHelper ll7(QStringLiteral(".!#$%&'*+-/=?^_`{|}~@bar.baz"), qstrlen(".!#$%&'*+-/=?^_`{|}~")); 0052 QVERIFY(ll7.getEmailAddress().isEmpty()); 0053 0054 // allowed special chars in local part of address 0055 KTextToHTMLHelper ll8(QStringLiteral("a.!#$%&'*+-/=?^_`{|}~@bar.baz"), qstrlen("a.!#$%&'*+-/=?^_`{|}~")); 0056 QCOMPARE(ll8.getEmailAddress(), QStringLiteral("a.!#$%&'*+-/=?^_`{|}~@bar.baz")); 0057 0058 // '@' in domain part 0059 KTextToHTMLHelper ll9(QStringLiteral("foo@bar@bar.baz"), 3); 0060 QVERIFY(ll9.getEmailAddress().isEmpty()); 0061 0062 // domain part without dot 0063 KTextToHTMLHelper lla(QStringLiteral("foo@bar"), 3); 0064 QVERIFY(lla.getEmailAddress().isEmpty()); 0065 KTextToHTMLHelper llb(QStringLiteral("foo@bar."), 3); 0066 QVERIFY(llb.getEmailAddress().isEmpty()); 0067 KTextToHTMLHelper llc(QStringLiteral(".foo@bar"), 4); 0068 QVERIFY(llc.getEmailAddress().isEmpty()); 0069 KTextToHTMLHelper lld(QStringLiteral("foo@bar "), 3); 0070 QVERIFY(lld.getEmailAddress().isEmpty()); 0071 KTextToHTMLHelper lle(QStringLiteral(" foo@bar"), 4); 0072 QVERIFY(lle.getEmailAddress().isEmpty()); 0073 KTextToHTMLHelper llf(QStringLiteral("foo@bar-bar"), 3); 0074 QVERIFY(llf.getEmailAddress().isEmpty()); 0075 0076 // empty domain part 0077 KTextToHTMLHelper llg(QStringLiteral("foo@"), 3); 0078 QVERIFY(llg.getEmailAddress().isEmpty()); 0079 KTextToHTMLHelper llh(QStringLiteral("foo@."), 3); 0080 QVERIFY(llh.getEmailAddress().isEmpty()); 0081 KTextToHTMLHelper lli(QStringLiteral("foo@-"), 3); 0082 QVERIFY(lli.getEmailAddress().isEmpty()); 0083 0084 // simple address 0085 KTextToHTMLHelper llj(QStringLiteral("foo@bar.baz"), 3); 0086 QCOMPARE(llj.getEmailAddress(), QStringLiteral("foo@bar.baz")); 0087 KTextToHTMLHelper llk(QStringLiteral("foo@bar.baz."), 3); 0088 QCOMPARE(llk.getEmailAddress(), QStringLiteral("foo@bar.baz")); 0089 KTextToHTMLHelper lll(QStringLiteral(".foo@bar.baz"), 4); 0090 QCOMPARE(lll.getEmailAddress(), QStringLiteral("foo@bar.baz")); 0091 KTextToHTMLHelper llm(QStringLiteral("foo@bar.baz-"), 3); 0092 QCOMPARE(llm.getEmailAddress(), QStringLiteral("foo@bar.baz")); 0093 KTextToHTMLHelper lln(QStringLiteral("-foo@bar.baz"), 4); 0094 QCOMPARE(lln.getEmailAddress(), QStringLiteral("foo@bar.baz")); 0095 KTextToHTMLHelper llo(QStringLiteral("foo@bar.baz "), 3); 0096 QCOMPARE(llo.getEmailAddress(), QStringLiteral("foo@bar.baz")); 0097 KTextToHTMLHelper llp(QStringLiteral(" foo@bar.baz"), 4); 0098 QCOMPARE(llp.getEmailAddress(), QStringLiteral("foo@bar.baz")); 0099 KTextToHTMLHelper llq(QStringLiteral("foo@bar-bar.baz"), 3); 0100 QCOMPARE(llq.getEmailAddress(), QStringLiteral("foo@bar-bar.baz")); 0101 } 0102 0103 void KTextToHTMLTest::testGetUrl() 0104 { 0105 QStringList brackets; 0106 brackets << QString() << QString(); // no brackets 0107 brackets << QStringLiteral("<") << QStringLiteral(">"); 0108 brackets << QStringLiteral("[") << QStringLiteral("]"); 0109 brackets << QStringLiteral("\"") << QStringLiteral("\""); 0110 brackets << QStringLiteral("<link>") << QStringLiteral("</link>"); 0111 0112 for (int i = 0; i < brackets.count(); i += 2) { 0113 testGetUrl2(brackets[i], brackets[i + 1]); 0114 } 0115 } 0116 0117 void KTextToHTMLTest::testGetUrl2(const QString &left, const QString &right) 0118 { 0119 QStringList schemas; 0120 schemas << QStringLiteral("http://"); 0121 schemas << QStringLiteral("https://"); 0122 schemas << QStringLiteral("vnc://"); 0123 schemas << QStringLiteral("fish://"); 0124 schemas << QStringLiteral("ftp://"); 0125 schemas << QStringLiteral("ftps://"); 0126 schemas << QStringLiteral("sftp://"); 0127 schemas << QStringLiteral("smb://"); 0128 schemas << QStringLiteral("file://"); 0129 schemas << QStringLiteral("irc://"); 0130 schemas << QStringLiteral("ircs://"); 0131 0132 QStringList urls; 0133 urls << QStringLiteral("en.wikipedia.org/wiki/%C3%98_(disambiguation)"); 0134 urls << QStringLiteral("www.kde.org"); 0135 urls << QStringLiteral("user@www.kde.org"); 0136 urls << QStringLiteral("user:pass@www.kde.org"); 0137 urls << QStringLiteral("user:pass@www.kde.org:1234"); 0138 urls << QStringLiteral("user:pass@www.kde.org:1234/sub/path"); 0139 urls << QStringLiteral("user:pass@www.kde.org:1234/sub/path?a=1"); 0140 urls << QStringLiteral("user:pass@www.kde.org:1234/sub/path?a=1#anchor"); 0141 urls << QStringLiteral("user:pass@www.kde.org:1234/sub/\npath \n /long/ path \t ?a=1#anchor"); 0142 urls << QStringLiteral("user:pass@www.kde.org:1234/sub/path/special(123)?a=1#anchor"); 0143 urls << QStringLiteral("user:pass@www.kde.org:1234/sub/path:with:colon/special(123)?a=1#anchor"); 0144 urls << QStringLiteral("user:pass@www.kde.org:1234/sub/path:with:colon/special(123)?a=1#anchor[bla"); 0145 urls << QStringLiteral("user:pass@www.kde.org:1234/sub/path:with:colon/special(123)?a=1#anchor[bla]"); 0146 urls << QStringLiteral("user:pass@www.kde.org:1234/\nsub/path:with:colon/\nspecial(123)?\na=1#anchor[bla]"); 0147 urls << QStringLiteral("user:pass@www.kde.org:1234/ \n sub/path:with:colon/ \n\t \t special(123)?") + QStringLiteral("\n\t \n\t a=1#anchor[bla]"); 0148 0149 for (const QString &schema : std::as_const(schemas)) { 0150 for (QString url : std::as_const(urls)) { 0151 // by definition: if the URL is enclosed in brackets, the URL itself is not allowed 0152 // to contain the closing bracket, as this would be detected as the end of the URL 0153 if ((left.length() == 1) && (url.contains(right[0]))) { 0154 continue; 0155 } 0156 0157 // if the url contains a whitespace, it must be enclosed with brackets 0158 if ((url.contains(QLatin1Char('\n')) || url.contains(QLatin1Char('\t')) || url.contains(QLatin1Char(' '))) && left.isEmpty()) { 0159 continue; 0160 } 0161 0162 QString test(left + schema + url + right); 0163 KTextToHTMLHelper ll(test, left.length()); 0164 QString gotUrl = ll.getUrl(); 0165 0166 // we want to have the url without whitespace 0167 url.remove(QLatin1Char(' ')); 0168 url.remove(QLatin1Char('\n')); 0169 url.remove(QLatin1Char('\t')); 0170 0171 bool ok = (gotUrl == (schema + url)); 0172 if (!ok) { 0173 qDebug() << "got:" << gotUrl; 0174 } 0175 QVERIFY2(ok, qPrintable(test)); 0176 } 0177 } 0178 0179 QStringList urlsWithoutSchema; 0180 urlsWithoutSchema << QStringLiteral(".kde.org"); 0181 urlsWithoutSchema << QStringLiteral(".kde.org:1234/sub/path"); 0182 urlsWithoutSchema << QStringLiteral(".kde.org:1234/sub/path?a=1"); 0183 urlsWithoutSchema << QStringLiteral(".kde.org:1234/sub/path?a=1#anchor"); 0184 urlsWithoutSchema << QStringLiteral(".kde.org:1234/sub/path/special(123)?a=1#anchor"); 0185 urlsWithoutSchema << QStringLiteral(".kde.org:1234/sub/path:with:colon/special(123)?a=1#anchor"); 0186 urlsWithoutSchema << QStringLiteral(".kde.org:1234/sub/path:with:colon/special(123)?a=1#anchor[bla"); 0187 urlsWithoutSchema << QStringLiteral(".kde.org:1234/sub/path:with:colon/special(123)?a=1#anchor[bla]"); 0188 urlsWithoutSchema << QStringLiteral(".kde.org:1234/\nsub/path:with:colon/\nspecial(123)?\na=1#anchor[bla]"); 0189 urlsWithoutSchema << QStringLiteral(".kde.org:1234/ \n sub/path:with:colon/ \n\t \t special(123)?") + QStringLiteral("\n\t \n\t a=1#anchor[bla]"); 0190 0191 QStringList starts; 0192 starts << QStringLiteral("www") << QStringLiteral("ftp") << QStringLiteral("news:www"); 0193 0194 for (const QString &start : std::as_const(starts)) { 0195 for (QString url : std::as_const(urlsWithoutSchema)) { 0196 // by definition: if the URL is enclosed in brackets, the URL itself is not allowed 0197 // to contain the closing bracket, as this would be detected as the end of the URL 0198 if ((left.length() == 1) && (url.contains(right[0]))) { 0199 continue; 0200 } 0201 0202 // if the url contains a whitespace, it must be enclosed with brackets 0203 if ((url.contains(QLatin1Char('\n')) || url.contains(QLatin1Char('\t')) || url.contains(QLatin1Char(' '))) && left.isEmpty()) { 0204 continue; 0205 } 0206 0207 QString test(left + start + url + right); 0208 KTextToHTMLHelper ll(test, left.length()); 0209 QString gotUrl = ll.getUrl(); 0210 0211 // we want to have the url without whitespace 0212 url.remove(QLatin1Char(' ')); 0213 url.remove(QLatin1Char('\n')); 0214 url.remove(QLatin1Char('\t')); 0215 0216 bool ok = (gotUrl == (start + url)); 0217 if (!ok) { 0218 qDebug() << "got:" << gotUrl; 0219 } 0220 QVERIFY2(ok, qPrintable(gotUrl)); 0221 } 0222 } 0223 0224 // test max url length 0225 QString url = QStringLiteral("https://www.kde.org/this/is/a_very_loooooong_url/test/test/test"); 0226 { 0227 KTextToHTMLHelper ll(url, 0, 10); 0228 QVERIFY(ll.getUrl().isEmpty()); // url too long 0229 } 0230 { 0231 KTextToHTMLHelper ll(url, 0, url.length() - 1); 0232 QVERIFY(ll.getUrl().isEmpty()); // url too long 0233 } 0234 { 0235 KTextToHTMLHelper ll(url, 0, url.length()); 0236 QCOMPARE(ll.getUrl(), url); 0237 } 0238 { 0239 KTextToHTMLHelper ll(url, 0, url.length() + 1); 0240 QCOMPARE(ll.getUrl(), url); 0241 } 0242 0243 // mailto 0244 { 0245 QString addr = QStringLiteral("mailto:test@kde.org"); 0246 QString test(left + addr + right); 0247 KTextToHTMLHelper ll(test, left.length()); 0248 0249 QString gotUrl = ll.getUrl(); 0250 0251 bool ok = (gotUrl == addr); 0252 if (!ok) { 0253 qDebug() << "got:" << gotUrl; 0254 } 0255 QVERIFY2(ok, qPrintable(gotUrl)); 0256 } 0257 } 0258 0259 void KTextToHTMLTest::testHtmlConvert_data() 0260 { 0261 QTest::addColumn<QString>("plainText"); 0262 QTest::addColumn<RuqolaKTextToHTML::Options>("flags"); 0263 QTest::addColumn<QString>("htmlText"); 0264 // Linker error when using PreserveSpaces, therefore the hardcoded 0x01 or 0x09 0265 0266 // Test preserving whitespace correctly 0267 QTest::newRow("") << " foo" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << " foo"; 0268 QTest::newRow("") << " foo" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << " foo"; 0269 QTest::newRow("") << " foo " << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << " foo "; 0270 QTest::newRow("") << " foo " << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << " foo "; 0271 QTest::newRow("") << "bla bla bla bla bla" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << "bla bla bla bla bla"; 0272 QTest::newRow("") << "bla bla bla \n bla bla bla " << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0273 << "bla bla bla <br />\n bla bla bla "; 0274 QTest::newRow("") << "bla bla bla" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << "bla bla bla"; 0275 QTest::newRow("") << " bla bla \n bla bla a\n bla bla " << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0276 << " bla bla <br />\n bla bla a<br />\n" 0277 " bla bla "; 0278 0279 // Test highlighting with *, / and _ 0280 QTest::newRow("") << "Ce paragraphe _contient_ des mots ou des _groupes de mots_ à mettre en" 0281 " forme…" 0282 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0283 << "Ce paragraphe <i>contient</i> des mots ou des" 0284 " <i>groupes de mots</i> à mettre en forme…"; 0285 QTest::newRow("punctation-bug") << "Ce texte *a l'air* de _fonctionner_, à condition" 0286 " d’utiliser le guillemet ASCII." 0287 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0288 << "Ce texte <b>*a l'air*</b> de <u>_fonctionner_</u>, à" 0289 " condition d’utiliser le guillemet ASCII."; 0290 QTest::newRow("punctation-bug") << "Un répertoire /est/ un *dossier* où on peut mettre des" 0291 " *fichiers*." 0292 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0293 << "Un répertoire <i>/est/</i> un" 0294 " <b>*dossier*</b> où on peut mettre des <b>*fichiers*</b>."; 0295 QTest::newRow("punctation-bug") << "*BLA BLA BLA BLA*." << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0296 << "<b>BLA BLA BLA BLA</b>."; 0297 QTest::newRow("") << "Je vais tenter de repérer des faux positif*" 0298 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0299 << "Je vais tenter de repérer des faux positif*"; 0300 QTest::newRow("") << "*Ouais !* *Yes!*" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0301 << "<b>Ouais !</b> <b>Yes!</b>"; 0302 0303 QTest::newRow("multispace") << "*Ouais foo*" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0304 << "<b>Ouais foo</b>"; 0305 0306 QTest::newRow("multispace3") << "*Ouais: foo*" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0307 << "<b>Ouais: foo</b>"; 0308 0309 QTest::newRow("multi-") << "** Ouais: foo **" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0310 << "** Ouais: foo **"; 0311 0312 QTest::newRow("multi-") << "*** Ouais: foo ***" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0313 << "*** Ouais: foo ***"; 0314 0315 QTest::newRow("nohtmlversion") << "* Ouais: foo *" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0316 << "<b>Ouais: foo</b>"; 0317 0318 QTest::newRow("nohtmlversion2") << "*Ouais: foo *" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0319 << "<b>Ouais: foo</b>"; 0320 0321 QTest::newRow("nohtmlversion3") << "* Ouais: foo*" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0322 << "<b>Ouais: foo</b>"; 0323 0324 QTest::newRow("nohtmlversion4") << "* Ouais: *ff sfsdf* foo *" 0325 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0326 << "* Ouais: <b>ff sfsdf</b> foo *"; 0327 0328 QTest::newRow("") << "the /etc/{rsyslog.d,syslog-ng.d}/package.rpmnew file" 0329 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0330 << "the /etc/{rsyslog.d,syslog-ng.d}/package.rpmnew file"; 0331 0332 // This test has problems with the encoding, apparently. 0333 // QTest::newRow( "" ) << "*Ça fait plaisir de pouvoir utiliser des lettres accentuées dans du" 0334 // " texte mis en forme*." << 0x09 << "<b>Ça fait plaisir de pouvoir" 0335 // " utiliser des lettres accentuées dans du texte mis en forme</b>."; 0336 0337 // Bug reported by dfaure, the <hostname> would get lost 0338 QTest::newRow("") << "QUrl url(\"http://strange<hostname>/\");" 0339 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::ReplaceSmileys | RuqolaKTextToHTML::HighlightText) 0340 << "QUrl url("<a href=\"http://strange<hostname>/\">" 0341 "http://strange<hostname>/</a>");"; 0342 0343 // Bug: 211128 - plain text emails should not replace ampersand & with & 0344 QTest::newRow("bug211128") << "https://green-site/?Ticket=85&Page=next" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0345 << "<a href=\"https://green-site/?Ticket=85&Page=next\">" 0346 "https://green-site/?Ticket=85&Page=next</a>"; 0347 0348 QTest::newRow("dotBeforeEnd") << "Look at this file: www.example.com/example.h" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0349 << "Look at this file: <a href=\"http://www.example.com/example.h\">" 0350 "www.example.com/example.h</a>"; 0351 QTest::newRow("dotInMiddle") << "Look at this file: www.example.com/.bashrc" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0352 << "Look at this file: <a href=\"http://www.example.com/.bashrc\">" 0353 "www.example.com/.bashrc</a>"; 0354 0355 // A dot at the end of an URL is explicitly ignored 0356 QTest::newRow("dotAtEnd") << "Look at this file: www.example.com/test.cpp." << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0357 << "Look at this file: <a href=\"http://www.example.com/test.cpp\">" 0358 "www.example.com/test.cpp</a>."; 0359 0360 // Bug 313719 - URL in parenthesis 0361 QTest::newRow("url-in-parenthesis-1") << "KDE (website https://www.kde.org)" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0362 << "KDE (website <a href=\"https://www.kde.org\">https://www.kde.org</a>)"; 0363 QTest::newRow("url-in-parenthesis-2") << "KDE website (https://www.kde.org)" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0364 << "KDE website (<a href=\"https://www.kde.org\">https://www.kde.org</a>)"; 0365 QTest::newRow("url-in-parenthesis-3") << "bla (https://www.kde.org - section 5.2)" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0366 << "bla (<a href=\"https://www.kde.org\">https://www.kde.org</a> - section 5.2)"; 0367 0368 // Fix url as foo <<url> <url>> when we concatened them. 0369 QTest::newRow("url-with-url") 0370 << "foo <https://www.kde.org/ <https://www.kde.org/>>" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0371 << "foo <<a href=\"https://www.kde.org/ \">https://www.kde.org/ </a><<a href=\"https://www.kde.org/\">https://www.kde.org/</a>>>"; 0372 0373 // Fix url exploit 0374 QTest::newRow("url-exec-html") << "https://\"><!--" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << "https://"><!--"; 0375 0376 QTest::newRow("url-exec-html-2") << "https://192.168.1.1:\"><!--" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0377 << "https://192.168.1.1:"><!--"; 0378 0379 QTest::newRow("url-exec-html-3") << "https://<IP>:\"><!--" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0380 << "https://<IP>:"><!--"; 0381 0382 QTest::newRow("url-exec-html-4") << "https://<IP>:/\"><!--" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0383 << "https://<IP>:/"><!--"; 0384 0385 QTest::newRow("url-exec-html-5") << "https://<IP>:/\"><script>alert(1);</script><!--" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0386 << "https://<IP>:/"><script>alert(1);</script><!--"; 0387 0388 QTest::newRow("url-exec-html-6") << "https://<IP>:/\"><script>alert(1);</script><!--\nTest2" 0389 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0390 << "https://<IP>:/"><script>alert(1);</script><!--\nTest2"; 0391 0392 QTest::newRow("url-with-ref-in-[") << "https://www.kde.org[1]" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0393 << "<a href=\"https://www.kde.org\">https://www.kde.org</a>[1]"; 0394 0395 QTest::newRow("url-with-ref-in-[2") << "[http://www.example.org/][whatever]" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0396 << "[<a href=\"http://www.example.org/\">http://www.example.org/</a>][whatever]"; 0397 // Bug 346132 0398 QTest::newRow("url-with-ref-in-<") << "http://www.foo.bar<http://foo.bar/>" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0399 << "<a href=\"http://www.foo.bar\">http://www.foo.bar</a><<a href=\"http://foo.bar/\">http://foo.bar/</a>>"; 0400 0401 QTest::newRow("url-with-ref-in-]") << "[Please visit our booth 24-25 http://example.com/]" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0402 << "[Please visit our booth 24-25 <a href=\"http://example.com/\">http://example.com/</a>]"; 0403 0404 QTest::newRow("two url with space") << "http://www.kde.org/standards/kcfg/1.0 http://www.kde.org/" 0405 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0406 << "<a href=\"http://www.kde.org/standards/kcfg/1.0\">http://www.kde.org/standards/kcfg/1.0</a> <a " 0407 "href=\"http://www.kde.org/\">http://www.kde.org/</a>"; 0408 0409 // Bug kmail 0410 QTest::newRow("two url with space-2") 0411 << "@@ -55,6 +55,10 @@ xsi:schemaLocation=\"http://www.kde.org/standards/kcfg/1.0 http://www.kde.org/" 0412 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0413 << "@@ -55,6 +55,10 @@ xsi:schemaLocation="<a href=\"http://www.kde.org/standards/kcfg/1.0\">http://www.kde.org/standards/kcfg/1.0</a> <a " 0414 "href=\"http://www.kde.org/\">http://www.kde.org/</a>"; 0415 0416 const auto opt = RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::ConvertPhoneNumbers; 0417 // tel: urls 0418 QTest::newRow("tel url compact") << "bla bla <tel:+491234567890> bla bla" << opt 0419 << "bla bla <<a href=\"tel:+491234567890\">tel:+491234567890</a>> bla bla"; 0420 QTest::newRow("tel url fancy") << "bla bla tel:+49-321-123456 bla bla" << opt << "bla bla <a href=\"tel:+49-321-123456\">tel:+49-321-123456</a> bla bla"; 0421 0422 // negative tel: url tests 0423 QTest::newRow("empty tel url") << "bla tel: blub" << opt << "bla tel: blub"; 0424 0425 // phone numbers 0426 QTest::newRow("tel compact international") << "call +49123456789, then hang up" << opt 0427 << "call <a href=\"tel:+49123456789\">+49123456789</a>, then hang up"; 0428 QTest::newRow("tel parenthesis/spaces international") 0429 << "phone:+33 (01) 12 34 56 78 blub" << opt << "phone:<a href=\"tel:+330112345678\">+33 (01) 12 34 56 78</a> blub"; 0430 QTest::newRow("tel dashes international") << "bla +44-321-1-234-567" << opt << "bla <a href=\"tel:+443211234567\">+44-321-1-234-567</a>"; 0431 QTest::newRow("tel dashes/spaces international") << "+1 123-456-7000 blub" << opt << "<a href=\"tel:+11234567000\">+1 123-456-7000</a> blub"; 0432 QTest::newRow("tel spaces international") << "bla +32 1 234 5678 blub" << opt << "bla <a href=\"tel:+3212345678\">+32 1 234 5678</a> blub"; 0433 QTest::newRow("tel slash domestic") << "bla 030/12345678 blub" << opt << "bla <a href=\"tel:03012345678\">030/12345678</a> blub"; 0434 QTest::newRow("tel slash/space domestic") << "Tel.: 089 / 12 34 56 78" << opt << "Tel.: <a href=\"tel:08912345678\">089 / 12 34 56 78</a>"; 0435 QTest::newRow("tel follow by parenthesis") << "Telefon: 0 18 05 / 12 23 46 (14 Cent/Min.*)" << opt 0436 << "Telefon: <a href=\"tel:01805122346\">0 18 05 / 12 23 46</a> (14 Cent/Min.*)"; 0437 QTest::newRow("tel space single digit at end") << "0123/123 456 7" << opt << "<a href=\"tel:01231234567\">0123/123 456 7</a>"; 0438 QTest::newRow("tel space around dash") << "bla +49 (0) 12 23 - 45 6000 blub" << opt 0439 << "bla <a href=\"tel:+4901223456000\">+49 (0) 12 23 - 45 6000</a> blub"; 0440 QTest::newRow("tel two numbers speparated by dash") 0441 << "bla +49 (0) 12 23 46 78 - +49 0123/123 456 78 blub" << opt 0442 << "bla <a href=\"tel:+49012234678\">+49 (0) 12 23 46 78</a> - <a href=\"tel:+49012312345678\">+49 0123/123 456 78</a> blub"; 0443 0444 // negative tests for phone numbers 0445 QTest::newRow("non-tel number") << "please send 1200 cakes" << opt << "please send 1200 cakes"; 0446 QTest::newRow("non-tel alpha-numeric") << "bla 1-123-456-ABCD blub" << opt << "bla 1-123-456-ABCD blub"; 0447 QTest::newRow("non-tel alpha prefix") << "ABCD0123-456-789" << opt << "ABCD0123-456-789"; 0448 QTest::newRow("non-tel date") << "bla 02/03/2019 blub" << opt << "bla 02/03/2019 blub"; 0449 QTest::newRow("non-tel too long") << "bla +012-4567890123456 blub" << opt << "bla +012-4567890123456 blub"; 0450 QTest::newRow("non-tel unbalanced") << "bla +012-456789(01 blub" << opt << "bla +012-456789(01 blub"; 0451 QTest::newRow("non-tel nested") << "bla +012-4(56(78)90)1 blub" << opt << "bla +012-4(56(78)90)1 blub"; 0452 QTest::newRow("tel extraction disabled") << "call +49123456789 now" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0453 << "call +49123456789 now"; 0454 0455 QTest::newRow("bug-414360") 0456 << "https://www.openstreetmap.org/directions?engine=graphhopper_foot&route=44.85765%2C-0.55931%3B44.85713%2C-0.56117#map=18/44.85756/-0.56094" 0457 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0458 << "<a " 0459 "href=\"https://www.openstreetmap.org/directions?engine=graphhopper_foot&route=44.85765%2C-0.55931%3B44.85713%2C-0.56117#map=18/44.85756/" 0460 "-0.56094\">https://www.openstreetmap.org/directions?engine=graphhopper_foot&route=44.85765%2C-0.55931%3B44.85713%2C-0.56117#map=18/44.85756/" 0461 "-0.56094</a>"; 0462 0463 // xmpp bug 422291 0464 QTest::newRow("xmpp1") << "xmpp:username@server.tld" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0465 << "<a href=\"xmpp:username@server.tld\">xmpp:username@server.tld</a>"; 0466 QTest::newRow("xmpp2") << "xmpp:conversations@conference.siacs.eu" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0467 << "<a href=\"xmpp:conversations@conference.siacs.eu\">xmpp:conversations@conference.siacs.eu</a>"; 0468 QTest::newRow("xmpp3") << "xmpp:conversations@conference.siacs.eu?join" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) 0469 << "<a href=\"xmpp:conversations@conference.siacs.eu?join\">xmpp:conversations@conference.siacs.eu?join</a>"; 0470 0471 // Test news: only 0472 QTest::newRow("news") << "news: " << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << "news: "; 0473 0474 QTest::newRow("ftp") << "ftp: " << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << "ftp: "; 0475 QTest::newRow("mailto") << "mailto: " << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << "mailto: "; 0476 QTest::newRow("empty") << "" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces) << ""; 0477 0478 QTest::newRow("spaceafter") << "_test1: test2 _" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0479 << "<i>test1: test2</i>"; 0480 QTest::newRow("spacebefore") << "_ test1: bla_" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0481 << "<i>test1: bla</i>"; 0482 QTest::newRow("spacebeforeandafter") << "_ test1: blo _" << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0483 << "<i>test1: blo</i>"; 0484 QTest::newRow("spacebeforeandafter2") << "__ test1: blo _" 0485 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0486 << "<i>test1: blo</i>"; 0487 QTest::newRow("spacebeforeandafter3") << "__ test1: blo __" 0488 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0489 << "<i>test1: blo</i>"; 0490 QTest::newRow("spacebeforeandafter4") << "___ test1: blo _" 0491 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0492 << "<i>test1: blo</i>"; 0493 QTest::newRow("spacebeforeandafter5") << "_ test1: blo __" 0494 << RuqolaKTextToHTML::Options(RuqolaKTextToHTML::PreserveSpaces | RuqolaKTextToHTML::HighlightText) 0495 << "<i>test1: blo</i>"; 0496 } 0497 0498 void KTextToHTMLTest::testHtmlConvert() 0499 { 0500 QFETCH(QString, plainText); 0501 QFETCH(RuqolaKTextToHTML::Options, flags); 0502 QFETCH(QString, htmlText); 0503 0504 QEXPECT_FAIL("punctation-bug", "Linklocator does not properly detect punctation as boundaries", Continue); 0505 QEXPECT_FAIL("spacebeforeandafter3", "multi _/*/~ at end is not supported yet because we use InvertedGreedinessOption", Continue); 0506 QEXPECT_FAIL("spacebeforeandafter5", "multi _/*/~ at end is not supported yet because we use InvertedGreedinessOption", Continue); 0507 0508 const QString actualHtml = RuqolaKTextToHTML::convertToHtml(plainText, flags); 0509 QCOMPARE(actualHtml, htmlText); 0510 } 0511 0512 #define s(x) QStringLiteral(x) 0513 0514 void KTextToHTMLTest::testEmoticons_data() 0515 { 0516 QTest::addColumn<QString>("input"); 0517 QTest::addColumn<QString>("output"); 0518 QTest::newRow("empty") << QString() << QString(); 0519 QTest::newRow("trailing") << s("Hello :-)") << s("Hello :-)"); 0520 QTest::newRow("embedded") << s("Hello :-) How are you?") << s("Hello :-) How are you?"); 0521 QTest::newRow("leading") << s(":-( Bye") << s(":-( Bye"); 0522 QTest::newRow("embedded-html") << s("<b>:(</b>") << s("<b>:(</b>"); 0523 QTest::newRow("html-attribute") << s("<img src=\"...\" title=\":-)\" />") << s("<img src="..." title=":-)" />"); 0524 QTest::newRow("broken-1") << s(":))") << s(":))"); 0525 QTest::newRow("broken-4") << s(":D and :-D are not the same as :d and :-d") << s(":D and :-D are not the same as :d and :-d"); 0526 QTest::newRow("broken-5") << s("4d:D>:)F:/>:-(:Pu:d9") << s("4d:D>:)F:/&gt;:-(:Pu:d9"); 0527 QTest::newRow("broken-6") << s("<::pvar:: test=1>") << s("&lt;::pvar:: test=1&gt;"); 0528 QTest::newRow("working-5") << s("(&)") << s("(&amp;)"); 0529 QTest::newRow("working-6") << s("Bla ( )") << s("Bla (&nbsp;)"); 0530 QTest::newRow("working-7") << s("a non-breaking space ( ) character") << s("a non-breaking space (&nbsp;) character"); 0531 0532 QTest::newRow("angle-bracket-1") << s(">:)") << s(">:)"); 0533 QTest::newRow("angle-bracket-2") << s("<b>:)") << s("<b>:)"); 0534 } 0535 0536 void KTextToHTMLTest::testEmoticons() 0537 { 0538 QFETCH(QString, input); 0539 QFETCH(QString, output); 0540 QCOMPARE(RuqolaKTextToHTML::convertToHtml(input, RuqolaKTextToHTML::ReplaceSmileys | RuqolaKTextToHTML::IgnoreUrls), output); 0541 } 0542 0543 void KTextToHTMLTest::testEmoticonsNoReplace_data() 0544 { 0545 QTest::addColumn<QString>("input"); 0546 QTest::newRow("empty") << QString(); 0547 QTest::newRow("no-space-spearator") << s("Very happy! :-):-)"); 0548 QTest::newRow("broken-2") << s("In a sentence:practical example"); 0549 QTest::newRow("broken-8") << s("-+-[-:-(-:-)-:-]-+-"); 0550 QTest::newRow("broken-9") << s("::shrugs::"); 0551 QTest::newRow("broken-10") << s(":Ptesting:P"); 0552 QTest::newRow("working-1") << s(":):)"); 0553 QTest::newRow("working-4") << s("http://www.kde.org"); 0554 QTest::newRow("working-3") << s("End of sentence:p"); 0555 QTest::newRow("xmpp-1") << s("an xmpp emoticon (%)"); 0556 } 0557 0558 void KTextToHTMLTest::testEmoticonsNoReplace() 0559 { 0560 QFETCH(QString, input); 0561 QCOMPARE(RuqolaKTextToHTML::convertToHtml(input, RuqolaKTextToHTML::ReplaceSmileys | RuqolaKTextToHTML::IgnoreUrls), input); 0562 } 0563 0564 #include "moc_ruqolaktexttohtmltest.cpp"