File indexing completed on 2024-05-05 05:01:19
0001 // SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com> 0002 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0003 0004 #include <QObject> 0005 #include <QTest> 0006 0007 #include "texthandler.h" 0008 0009 #include <Quotient/quotient_common.h> 0010 #include <Quotient/syncdata.h> 0011 #include <qnamespace.h> 0012 0013 #include "models/customemojimodel.h" 0014 #include "neochatconnection.h" 0015 #include "utils.h" 0016 0017 #include "testutils.h" 0018 0019 using namespace Quotient; 0020 0021 class TextHandlerTest : public QObject 0022 { 0023 Q_OBJECT 0024 0025 private: 0026 Connection *connection = nullptr; 0027 TestUtils::TestRoom *room = nullptr; 0028 0029 private Q_SLOTS: 0030 void initTestCase(); 0031 0032 void allowedAttributes(); 0033 void stripDisallowedTags(); 0034 void stripDisallowedAttributes(); 0035 void emptyCodeTags(); 0036 void formatBlockQuote(); 0037 0038 void sendSimpleStringCase(); 0039 void sendSingleParaMarkup(); 0040 void sendMultipleSectionMarkup(); 0041 void sendBadLinks(); 0042 void sendEscapeCode(); 0043 void sendCodeClass(); 0044 void sendCustomEmoji(); 0045 void sendCustomEmojiCode_data(); 0046 void sendCustomEmojiCode(); 0047 0048 void receiveStripReply(); 0049 void receivePlainTextIn(); 0050 0051 void receiveRichInPlainOut_data(); 0052 void receiveRichInPlainOut(); 0053 void receivePlainStripHtml(); 0054 void receivePlainStripMarkup(); 0055 void receiveStripNewlines(); 0056 0057 void receiveRichUserPill(); 0058 void receiveRichStrikethrough(); 0059 void receiveRichtextIn(); 0060 void receiveRichMxcUrl(); 0061 void receiveRichPlainUrl(); 0062 void receiveRichEmote(); 0063 void receiveRichEdited_data(); 0064 void receiveRichEdited(); 0065 void receiveLineSeparator(); 0066 void receiveRichCodeUrl(); 0067 }; 0068 0069 void TextHandlerTest::initTestCase() 0070 { 0071 connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org")); 0072 connection->setAccountData("im.ponies.user_emotes"_ls, 0073 QJsonObject{{"images"_ls, 0074 QJsonObject{{"test"_ls, 0075 QJsonObject{{"body"_ls, "Test custom emoji"_ls}, 0076 {"url"_ls, "mxc://example.org/test"_ls}, 0077 {"usage"_ls, QJsonArray{"emoticon"_ls}}}}}}}); 0078 CustomEmojiModel::instance().setConnection(static_cast<NeoChatConnection *>(connection)); 0079 0080 room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-texthandler-sync.json")); 0081 } 0082 0083 void TextHandlerTest::allowedAttributes() 0084 { 0085 const QString testInputString1 = QStringLiteral("<p><span data-mx-spoiler><font color=#FFFFFF>Test</font><span></p>"); 0086 const QString testOutputString1 = QStringLiteral("<p><span data-mx-spoiler><font color=#FFFFFF>Test</font><span></p>"); 0087 // Handle urls where the href has either single (') or double (") quotes. 0088 const QString testInputString2 = QStringLiteral("<p><a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a></p>"); 0089 const QString testOutputString2 = QStringLiteral("<p><a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a></p>"); 0090 0091 TextHandler testTextHandler; 0092 testTextHandler.setData(testInputString1); 0093 0094 QCOMPARE(testTextHandler.handleSendText(), testOutputString1); 0095 QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString1); 0096 0097 testTextHandler.setData(testInputString2); 0098 QCOMPARE(testTextHandler.handleSendText(), testOutputString2); 0099 QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString2); 0100 } 0101 0102 void TextHandlerTest::stripDisallowedTags() 0103 { 0104 const QString testInputString = QStringLiteral("<p>Allowed</p> <span>Allowed</span> <body>Disallowed</body>"); 0105 const QString testOutputString = QStringLiteral("<p>Allowed</p> <span>Allowed</span> Disallowed"); 0106 0107 TextHandler testTextHandler; 0108 testTextHandler.setData(testInputString); 0109 0110 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0111 QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString); 0112 } 0113 0114 void TextHandlerTest::stripDisallowedAttributes() 0115 { 0116 const QString testInputString = QStringLiteral("<p style=\"font-size:50px;\" color=#FFFFFF>Test</p>"); 0117 const QString testOutputString = QStringLiteral("<p>Test</p>"); 0118 0119 TextHandler testTextHandler; 0120 testTextHandler.setData(testInputString); 0121 0122 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0123 QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString); 0124 } 0125 0126 /** 0127 * Make sure that empty code tags are handled. 0128 * (this was a bug during development hence the test) 0129 */ 0130 void TextHandlerTest::emptyCodeTags() 0131 { 0132 const QString testInputString = QStringLiteral("<pre><code></code></pre>"); 0133 const QString testOutputString = QStringLiteral("<pre><code></code></pre>"); 0134 0135 TextHandler testTextHandler; 0136 testTextHandler.setData(testInputString); 0137 0138 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0139 QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString); 0140 } 0141 0142 void TextHandlerTest::formatBlockQuote() 0143 { 0144 auto input = QStringLiteral("<blockquote>\n<p>Lorem Ispum</p>\n</blockquote>"); 0145 auto expectedOutput = QStringLiteral("<blockquote><table><tr><td>\u201CLorem Ispum\u201D</td></tr></table></blockquote>"); 0146 0147 TextHandler testTextHandler; 0148 testTextHandler.setData(input); 0149 QCOMPARE(testTextHandler.handleRecieveRichText(), expectedOutput); 0150 } 0151 0152 void TextHandlerTest::sendSimpleStringCase() 0153 { 0154 const QString testInputString = QStringLiteral("This data should just be put in a paragraph."); 0155 const QString testOutputString = QStringLiteral("<p>This data should just be put in a paragraph.</p>"); 0156 0157 TextHandler testTextHandler; 0158 testTextHandler.setData(testInputString); 0159 0160 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0161 } 0162 0163 void TextHandlerTest::sendSingleParaMarkup() 0164 { 0165 const QString testInputString = QStringLiteral( 0166 "Text para with **bold**, *italic*, [link](https://kde.org), ![image](mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e), `inline code`."); 0167 const QString testOutputString = QStringLiteral( 0168 "<p>Text para with <strong>bold</strong>, <em>italic</em>, <a href=\"https://kde.org\">link</a>, <img " 0169 "src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\">, <code>inline code</code>.</p>"); 0170 0171 TextHandler testTextHandler; 0172 testTextHandler.setData(testInputString); 0173 0174 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0175 } 0176 0177 void TextHandlerTest::sendMultipleSectionMarkup() 0178 { 0179 const QString testInputString = 0180 QStringLiteral("Text para\n> blockquote\n* List 1\n* List 2\n1. one\n2. two\n# Heading 1\n## Heading 2\nhorizontal rule\n\n---\n```\ncodeblock\n```"); 0181 const QString testOutputString = QStringLiteral( 0182 "<p>Text para</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>\n<ul>\n<li>List 1</li>\n<li>List " 0183 "2</li>\n</ul>\n<ol>\n<li>one</li>\n<li>two</li>\n</ol>\n<h1>Heading 1</h1>\n<h2>Heading 2</h2>\n<p>horizontal " 0184 "rule</p>\n<hr>\n<pre><code>codeblock\n</code></pre>"); 0185 0186 TextHandler testTextHandler; 0187 testTextHandler.setData(testInputString); 0188 0189 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0190 } 0191 0192 void TextHandlerTest::sendBadLinks() 0193 { 0194 const QString testInputString = QStringLiteral("[link](kde.org), ![image](https://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e)"); 0195 const QString testOutputString = QStringLiteral("<p><a>link</a>, <img alt=\"image\"></p>"); 0196 0197 TextHandler testTextHandler; 0198 testTextHandler.setData(testInputString); 0199 0200 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0201 } 0202 0203 /** 0204 * All text between code tags is treated as plain so it should get escaped. 0205 */ 0206 void TextHandlerTest::sendEscapeCode() 0207 { 0208 const QString testInputString = QStringLiteral("```\n<p>Test <span style=\"font-size:50px;\">some</span> code</p>\n```"); 0209 const QString testOutputString = 0210 QStringLiteral("<pre><code><p>Test <span style="font-size:50px;">some</span> code</p>\n</code></pre>"); 0211 0212 TextHandler testTextHandler; 0213 testTextHandler.setData(testInputString); 0214 0215 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0216 } 0217 0218 void TextHandlerTest::sendCodeClass() 0219 { 0220 const QString testInputString = QStringLiteral("```html\nsome code\n```\n<pre><code class=\"code-underline\">some more code</code></pre>"); 0221 const QString testOutputString = QStringLiteral("<pre><code class=\"language-html\">some code\n</code></pre>\n<pre><code>some more code</code></pre>"); 0222 0223 TextHandler testTextHandler; 0224 testTextHandler.setData(testInputString); 0225 0226 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0227 } 0228 0229 void TextHandlerTest::sendCustomEmoji() 0230 { 0231 const QString testInputString = QStringLiteral(":test:"); 0232 const QString testOutputString = QStringLiteral( 0233 "<p><img data-mx-emoticon=\"\" src=\"mxc://example.org/test\" alt=\":test:\" title=\":test:\" height=\"32\" vertical-align=\"middle\" /></p>"); 0234 0235 TextHandler testTextHandler; 0236 testTextHandler.setData(testInputString); 0237 0238 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0239 } 0240 0241 void TextHandlerTest::sendCustomEmojiCode_data() 0242 { 0243 QTest::addColumn<QString>("testInputString"); 0244 QTest::addColumn<QString>("testOutputString"); 0245 0246 QTest::newRow("inline") << QStringLiteral("`:test:`") << QStringLiteral("<p><code>:test:</code></p>"); 0247 QTest::newRow("block") << QStringLiteral("```\n:test:\n```") << QStringLiteral("<pre><code>:test:\n</code></pre>"); 0248 } 0249 0250 // Custom emojis in code blocks should be left alone. 0251 void TextHandlerTest::sendCustomEmojiCode() 0252 { 0253 QFETCH(QString, testInputString); 0254 QFETCH(QString, testOutputString); 0255 0256 TextHandler testTextHandler; 0257 testTextHandler.setData(testInputString); 0258 0259 QCOMPARE(testTextHandler.handleSendText(), testOutputString); 0260 } 0261 0262 void TextHandlerTest::receiveStripReply() 0263 { 0264 const QString testInputString = QStringLiteral( 0265 "<mx-reply><blockquote><a href=\"https://matrix.to/#/!somewhere:example.org/$event:example.org\">In reply to</a><a " 0266 "href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a><br />Message replied to.</blockquote></mx-reply>Reply message."); 0267 const QString testOutputString = QStringLiteral("Reply message."); 0268 0269 TextHandler testTextHandler; 0270 testTextHandler.setData(testInputString); 0271 0272 QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString); 0273 QCOMPARE(testTextHandler.handleRecievePlainText(), testOutputString); 0274 } 0275 0276 void TextHandlerTest::receiveRichInPlainOut_data() 0277 { 0278 QTest::addColumn<QString>("testInputString"); 0279 QTest::addColumn<QString>("testOutputString"); 0280 0281 QTest::newRow("ampersand") << QStringLiteral("a & b") << QStringLiteral("a & b"); 0282 QTest::newRow("quote") << QStringLiteral(""a and b"") << QStringLiteral("\"a and b\""); 0283 QTest::newRow("new line") << QStringLiteral("new<br>line") << QStringLiteral("new\nline"); 0284 } 0285 0286 void TextHandlerTest::receiveRichInPlainOut() 0287 { 0288 QFETCH(QString, testInputString); 0289 QFETCH(QString, testOutputString); 0290 0291 TextHandler testTextHandler; 0292 testTextHandler.setData(testInputString); 0293 0294 QCOMPARE(testTextHandler.handleRecievePlainText(Qt::RichText), testOutputString); 0295 } 0296 0297 void TextHandlerTest::receivePlainTextIn() 0298 { 0299 const QString testInputString = QStringLiteral("<plain text in tag bracket>\nTest link https://kde.org."); 0300 const QString testOutputStringRich = QStringLiteral("<plain text in tag bracket><br>Test link <a href=\"https://kde.org\">https://kde.org</a>."); 0301 QString testOutputStringPlain = QStringLiteral("<plain text in tag bracket>\nTest link https://kde.org."); 0302 0303 // Make sure quotes are maintained in a plain string. 0304 const QString testInputString2 = QStringLiteral("last line is \"Time to switch to a new topic.\""); 0305 const QString testOutputString2 = QStringLiteral("last line is \"Time to switch to a new topic.\""); 0306 0307 TextHandler testTextHandler; 0308 testTextHandler.setData(testInputString); 0309 0310 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::PlainText), testOutputStringRich); 0311 QCOMPARE(testTextHandler.handleRecievePlainText(), testOutputStringPlain); 0312 0313 testTextHandler.setData(testInputString2); 0314 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::PlainText), testOutputString2); 0315 QCOMPARE(testTextHandler.handleRecievePlainText(), testOutputString2); 0316 } 0317 0318 void TextHandlerTest::receiveStripNewlines() 0319 { 0320 const QString testInputStringPlain = QStringLiteral("Test\nmany\nnew\nlines."); 0321 const QString testInputStringRich = QStringLiteral("Test<br>many<br />new<br>lines."); 0322 const QString testOutputString = QStringLiteral("Test many new lines."); 0323 0324 const QString testInputStringPlain2 = QStringLiteral("* List\n* Items"); 0325 const QString testOutputString2 = QStringLiteral("List Items"); 0326 0327 TextHandler testTextHandler; 0328 testTextHandler.setData(testInputStringPlain); 0329 0330 QCOMPARE(testTextHandler.handleRecievePlainText(Qt::PlainText, true), testOutputString); 0331 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::PlainText, nullptr, nullptr, true), testOutputString); 0332 0333 testTextHandler.setData(testInputStringRich); 0334 QCOMPARE(testTextHandler.handleRecievePlainText(Qt::RichText, true), testOutputString); 0335 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, nullptr, nullptr, true), testOutputString); 0336 0337 testTextHandler.setData(testInputStringPlain2); 0338 QCOMPARE(testTextHandler.handleRecievePlainText(Qt::RichText, true), testOutputString2); 0339 } 0340 0341 /** 0342 * For a plain text output of a received string all html is stripped except for 0343 * code which is unescaped if it's html. 0344 */ 0345 void TextHandlerTest::receivePlainStripHtml() 0346 { 0347 const QString testInputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>"); 0348 const QString testOutputString = QStringLiteral("Test Some code <strong>with tags</strong>"); 0349 0350 TextHandler testTextHandler; 0351 testTextHandler.setData(testInputString); 0352 0353 QCOMPARE(testTextHandler.handleRecievePlainText(Qt::RichText), testOutputString); 0354 } 0355 0356 void TextHandlerTest::receivePlainStripMarkup() 0357 { 0358 const QString testInputString = QStringLiteral("**bold** `<p>inline code</p>` *italic*"); 0359 const QString testOutputString = QStringLiteral("bold <p>inline code</p> italic"); 0360 0361 TextHandler testTextHandler; 0362 testTextHandler.setData(testInputString); 0363 0364 QCOMPARE(testTextHandler.handleRecievePlainText(), testOutputString); 0365 } 0366 0367 void TextHandlerTest::receiveRichUserPill() 0368 { 0369 const QString testInputString = QStringLiteral("<p><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></p>"); 0370 const QString testOutputString = QStringLiteral("<p><b><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></b></p>"); 0371 0372 TextHandler testTextHandler; 0373 testTextHandler.setData(testInputString); 0374 0375 QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString); 0376 } 0377 0378 void TextHandlerTest::receiveRichStrikethrough() 0379 { 0380 const QString testInputString = QStringLiteral("<p><del>Test</del></p>"); 0381 const QString testOutputString = QStringLiteral("<p><s>Test</s></p>"); 0382 0383 TextHandler testTextHandler; 0384 testTextHandler.setData(testInputString); 0385 0386 QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString); 0387 } 0388 0389 void TextHandlerTest::receiveRichtextIn() 0390 { 0391 const QString testInputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>"); 0392 const QString testOutputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>"); 0393 0394 TextHandler testTextHandler; 0395 testTextHandler.setData(testInputString); 0396 0397 QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString); 0398 } 0399 0400 void TextHandlerTest::receiveRichMxcUrl() 0401 { 0402 const QString testInputString = QStringLiteral( 0403 "<img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\"><img src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73\" " 0404 "alt=\"image\">"); 0405 const QString testOutputString = QStringLiteral( 0406 "<img " 0407 "src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e?user_id=@bob:kde.org&room_id=%23myroom:kde.org&event_id=$143273582443PhrSn:example.org\" " 0408 "alt=\"image\"><img " 0409 "src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73?user_id=@bob:kde.org&room_id=%23myroom:kde.org&event_id=$143273582443PhrSn:example.org\" " 0410 "alt=\"image\">"); 0411 0412 TextHandler testTextHandler; 0413 testTextHandler.setData(testInputString); 0414 0415 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(0).get()), testOutputString); 0416 } 0417 0418 /** 0419 * For when your rich input string has a plain text url left in. 0420 * 0421 * This test is to show that a url that is already rich will be left alone but a 0422 * plain one will be linkified. 0423 */ 0424 void TextHandlerTest::receiveRichPlainUrl() 0425 { 0426 // This is an actual link that caused trouble which is why it's so long. Keeping 0427 // so we can confirm consistent behaviour for complex urls. 0428 const QString testInputStringLink1 = QStringLiteral( 0429 "https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im " 0430 "<a " 0431 "href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/" 0432 "$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">Link already rich</a>"); 0433 const QString testOutputStringLink1 = QStringLiteral( 0434 "<a " 0435 "href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/" 0436 "$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">https://matrix.to/#/" 0437 "!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im</a> <a " 0438 "href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/" 0439 "$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">Link already rich</a>"); 0440 0441 // Another real case. The linkification wasn't handling it when a single link 0442 // contains what looks like and email. It was been broken into 3 but needs to 0443 // be just single link. 0444 const QString testInputStringLink2 = QStringLiteral("https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/"); 0445 const QString testOutputStringLink2 = QStringLiteral( 0446 "<a " 0447 "href=\"https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/\">https://lore.kernel.org/lkml/" 0448 "CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/</a>"); 0449 0450 QString testInputStringEmail = QStringLiteral(R"(email@example.com <a href="mailto:email@example.com">Link already rich</a>)"); 0451 QString testOutputStringEmail = 0452 QStringLiteral(R"(<a href="mailto:email@example.com">email@example.com</a> <a href="mailto:email@example.com">Link already rich</a>)"); 0453 0454 QString testInputStringMxId = QStringLiteral("@user:kde.org <a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a>"); 0455 QString testOutputStringMxId = QStringLiteral( 0456 "<b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> <b><a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a></b>"); 0457 0458 TextHandler testTextHandler; 0459 testTextHandler.setData(testInputStringLink1); 0460 0461 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), testOutputStringLink1); 0462 0463 testTextHandler.setData(testInputStringLink2); 0464 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), testOutputStringLink2); 0465 0466 testTextHandler.setData(testInputStringEmail); 0467 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), testOutputStringEmail); 0468 0469 testTextHandler.setData(testInputStringMxId); 0470 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), testOutputStringMxId); 0471 } 0472 0473 // Test that user pill is add to an emote message. 0474 // N.B. The second message in the test timeline is marked as an emote. 0475 void TextHandlerTest::receiveRichEmote() 0476 { 0477 auto event = room->messageEvents().at(1).get(); 0478 auto author = room->user(event->senderId()); 0479 const QString testInputString = QStringLiteral("This is an emote."); 0480 const QString testOutputString = QStringLiteral("* <a href=\"https://matrix.to/#/@example:example.org\" style=\"color:") 0481 + Utils::getUserColor(author->hueF()).name() + QStringLiteral("\">@example:example.org</a> This is an emote."); 0482 0483 TextHandler testTextHandler; 0484 testTextHandler.setData(testInputString); 0485 0486 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, event), testOutputString); 0487 } 0488 0489 void TextHandlerTest::receiveRichEdited_data() 0490 { 0491 QTest::addColumn<QString>("testInputString"); 0492 QTest::addColumn<QString>("testOutputString"); 0493 0494 QTest::newRow("basic") << QStringLiteral("Edited") << QStringLiteral("Edited <span style=\"color:#000000\">(edited)</span>"); 0495 QTest::newRow("multiple paragraphs") << QStringLiteral("<p>Edited</p>\n<p>Edited</p>") 0496 << QStringLiteral("<p>Edited</p>\n<p>Edited <span style=\"color:#000000\">(edited)</span></p>"); 0497 QTest::newRow("blockquote") 0498 << QStringLiteral("<blockquote>Edited</blockquote>") 0499 << QStringLiteral("<blockquote><table><tr><td>\u201CEdited\u201D</td></tr></table></blockquote><p> <span style=\"color:#000000\">(edited)</span></p>"); 0500 } 0501 0502 void TextHandlerTest::receiveRichEdited() 0503 { 0504 QFETCH(QString, testInputString); 0505 QFETCH(QString, testOutputString); 0506 0507 TextHandler testTextHandler; 0508 testTextHandler.setData(testInputString); 0509 0510 QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(2).get()), testOutputString); 0511 } 0512 0513 void TextHandlerTest::receiveLineSeparator() 0514 { 0515 auto text = QStringLiteral("foo\u2028bar"); 0516 TextHandler textHandler; 0517 textHandler.setData(text); 0518 QCOMPARE(textHandler.handleRecievePlainText(Qt::PlainText, true), QStringLiteral("foo bar")); 0519 } 0520 0521 void TextHandlerTest::receiveRichCodeUrl() 0522 { 0523 auto input = QStringLiteral("<code>https://kde.org</code>"); 0524 TextHandler testTextHandler; 0525 testTextHandler.setData(input); 0526 QCOMPARE(testTextHandler.handleRecieveRichText(), input); 0527 } 0528 0529 QTEST_MAIN(TextHandlerTest) 0530 #include "texthandlertest.moc"