File indexing completed on 2024-05-05 05:04:13
0001 // SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu> 0002 // SPDX-License-Identifier: GPL-3.0-or-later 0003 0004 #include <QtTest/QtTest> 0005 0006 #include "mockaccount.h" 0007 0008 using namespace Qt::Literals::StringLiterals; 0009 0010 class PostTest : public QObject 0011 { 0012 Q_OBJECT 0013 0014 private Q_SLOTS: 0015 void initTestCase() 0016 { 0017 } 0018 0019 void testFromJson() 0020 { 0021 MockAccount account; 0022 0023 QFile statusExampleApi; 0024 statusExampleApi.setFileName(QLatin1String(DATA_DIR) + QLatin1Char('/') + "status.json"_L1); 0025 statusExampleApi.open(QIODevice::ReadOnly); 0026 0027 const auto doc = QJsonDocument::fromJson(statusExampleApi.readAll()); 0028 Post post(&account, doc.object()); 0029 0030 QCOMPARE(post.spoilerText(), QStringLiteral("SPOILER")); 0031 QCOMPARE(post.content(), QStringLiteral("<p>LOREM</p>")); 0032 QVERIFY(post.card()); 0033 QCOMPARE(post.contentType(), QString()); 0034 QCOMPARE(post.sensitive(), false); 0035 QCOMPARE(post.visibility(), Post::Visibility::Public); 0036 QCOMPARE(post.wasEdited(), false); 0037 0038 QCOMPARE(post.authorIdentity()->displayName(), QStringLiteral("Eugen :kde:")); 0039 QCOMPARE(post.authorIdentity()->displayNameHtml(), QStringLiteral("Eugen <img height=\"16\" align=\"middle\" width=\"16\" src=\"https://kde.org\">")); 0040 } 0041 0042 void testFromJsonWithPoll() 0043 { 0044 MockAccount account; 0045 0046 QFile statusExampleApi; 0047 statusExampleApi.setFileName(QLatin1String(DATA_DIR) + QLatin1Char('/') + "status-poll.json"_L1); 0048 statusExampleApi.open(QIODevice::ReadOnly); 0049 0050 const auto doc = QJsonDocument::fromJson(statusExampleApi.readAll()); 0051 Post post(&account, doc.object()); 0052 0053 QCOMPARE(post.wasEdited(), true); 0054 QVERIFY(post.poll()); 0055 const auto poll = post.poll(); 0056 QCOMPARE(poll->id(), QStringLiteral("34830")); 0057 QCOMPARE(poll->expiresAt().date().year(), 2019); 0058 QCOMPARE(poll->expired(), true); 0059 QCOMPARE(poll->multiple(), false); 0060 QCOMPARE(poll->votesCount(), 10); 0061 QCOMPARE(poll->votersCount(), -1); 0062 QCOMPARE(poll->voted(), true); 0063 const auto ownVotes = poll->ownVotes(); 0064 QCOMPARE(ownVotes.count(), 1); 0065 QCOMPARE(ownVotes[0], 1); 0066 const auto options = poll->options(); 0067 QCOMPARE(options.count(), 2); 0068 QCOMPARE(options[0]["title"_L1], QStringLiteral("accept")); 0069 QCOMPARE(options[0]["votesCount"_L1], 6); 0070 QCOMPARE(options[1]["title"_L1], QStringLiteral("deny <img height=\"16\" align=\"middle\" width=\"16\" src=\"https://kde.org\">")); 0071 QCOMPARE(options[1]["votesCount"_L1], 4); 0072 } 0073 0074 // Normal case 0075 void testContentParsing() 0076 { 0077 MockAccount account; 0078 0079 QFile statusExampleApi; 0080 statusExampleApi.setFileName(QLatin1String(DATA_DIR) + QLatin1Char('/') + "status-tags.json"_L1); 0081 statusExampleApi.open(QIODevice::ReadOnly); 0082 0083 const auto doc = QJsonDocument::fromJson(statusExampleApi.readAll()); 0084 Post post(&account, doc.object()); 0085 0086 const QVector<QString> standaloneTags = {QStringLiteral("blackandwhite"), 0087 QStringLiteral("photo"), 0088 QStringLiteral("monochrome"), 0089 QStringLiteral("landscape"), 0090 QStringLiteral("photography")}; 0091 0092 QCOMPARE(post.content(), QStringLiteral("<p>Yosemite Valley reflections with rock</p>")); 0093 QCOMPARE(post.standaloneTags(), standaloneTags); 0094 } 0095 0096 // Ensure that extra <p>'s are removed 0097 void testContentParsingEdgeCaseOne() 0098 { 0099 const QString testHtml = QStringLiteral( 0100 "<p>Boris Karloff (again) as Imhotep</p><p><a href=\"https://mastodon.art/tags/Inktober\" class=\"mention hashtag\" " 0101 "rel=\"tag\">#<span>Inktober</span></a> <a href=\"https://mastodon.art/tags/Halloween\" class=\"mention hashtag\" " 0102 "rel=\"tag\">#<span>Halloween</span></a> <a href=\"https://mastodon.art/tags/TheMummy\" class=\"mention hashtag\" " 0103 "rel=\"tag\">#<span>TheMummy</span></a></p>"); 0104 0105 const auto [content, tags] = Post::parseContent(testHtml); 0106 0107 QCOMPARE(content, QStringLiteral("<p>Boris Karloff (again) as Imhotep</p>")); 0108 } 0109 0110 // Ensure that unicode/non-english characters (like Japanese) are picked up by the parser 0111 void testContentParsingEdgeCaseTwo() 0112 { 0113 const QString testHtml = QStringLiteral( 0114 R"(<p>cropping of homura and madoka <br />\uD83C\uDF80\uD83E\uDDA2\uD83C\uDF38\uD83C\uDFF9✨</p><p>finished version here - <a href=\"https://floodkiss.tumblr.com/post/682418812978659328/even-if-you-cant-see-me-even-if-you-cant-hear\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">floodkiss.tumblr.com/post/6824</span><span class=\"invisible\">18812978659328/even-if-you-cant-see-me-even-if-you-cant-hear</span></a></p><p><a href=\"https://mastodon.art/tags/MadokaMagica\" class=\"mention hashtag\" rel=\"tag\">#<span>MadokaMagica</span></a> <a href=\"https://mastodon.art/tags/%E9%AD%94%E6%B3%95%E5%B0%91%E5%A5%B3%E3%81%BE%E3%81%A9%E3%81%8B%E3%83%9E%E3%82%AE%E3%82%AB\" class=\"mention hashtag\" rel=\"tag\">#<span>魔法少女まどかマギカ</span></a> <a href=\"https://mastodon.art/tags/FediArt\" class=\"mention hashtag\" rel=\"tag\">#<span>FediArt</span></a> <a href=\"https://mastodon.art/tags/MastoArt\" class=\"mention hashtag\" rel=\"tag\">#<span>MastoArt</span></a> <a href=\"https://mastodon.art/tags/FanArt\" class=\"mention hashtag\" rel=\"tag\">#<span>FanArt</span></a> <a href=\"https://mastodon.art/tags/HomuraAkemi\" class=\"mention hashtag\" rel=\"tag\">#<span>HomuraAkemi</span></a> <a href=\"https://mastodon.art/tags/MadokaKaname\" class=\"mention hashtag\" rel=\"tag\">#<span>MadokaKaname</span></a></p>)"); 0115 0116 const auto [content, tags] = Post::parseContent(testHtml); 0117 0118 const QString expected = QStringLiteral( 0119 R"(<p>cropping of homura and madoka <br />\uD83C\uDF80\uD83E\uDDA2\uD83C\uDF38\uD83C\uDFF9✨</p><p>finished version here - <a href=\"https://floodkiss.tumblr.com/post/682418812978659328/even-if-you-cant-see-me-even-if-you-cant-hear\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">floodkiss.tumblr.com/post/6824</span><span class=\"invisible\">18812978659328/even-if-you-cant-see-me-even-if-you-cant-hear</span></a></p>)"); 0120 0121 QCOMPARE(tags[1], QStringLiteral("魔法少女まどかマギカ")); 0122 QCOMPARE(content, expected); 0123 } 0124 0125 // Ensure that posts that separate the tags not in a separate paragraph, but with a <br> for some reason 0126 void testContentParsingEdgeCaseThree() 0127 { 0128 const QString testHtml = QStringLiteral( 0129 R"(<p>Made a small FPS demo in @godotengine</p><p>Walls were made in <a href=\"/tags/MaterialMaker\" class=\"mention hashtag status-link\" rel=\"tag\">#<span>MaterialMaker</span></a> but it seems godot has trouble with the normal maps :( One common trick I use is to flip faces to break repetition but even if you don't it makes those weird light artefacts<br><a href=\"/tags/indiedev\" class=\"mention hashtag status-link\" rel=\"tag\">#<span>indiedev</span></a> <a href=\"/tags/gamedev\" class=\"mention hashtag status-link\" rel=\"tag\">#<span>gamedev</span></a> <a href=\"/tags/GodotEngine\" class=\"mention hashtag status-link\" rel=\"tag\">#<span>GodotEngine</span></a></p>)"); 0130 0131 const auto [content, tags] = Post::parseContent(testHtml); 0132 0133 const QString expected = QStringLiteral( 0134 R"(<p>Made a small FPS demo in @godotengine</p><p>Walls were made in <a href=\"/tags/MaterialMaker\" class=\"mention hashtag status-link\" rel=\"tag\">#<span>MaterialMaker</span></a> but it seems godot has trouble with the normal maps :( One common trick I use is to flip faces to break repetition but even if you don't it makes those weird light artefacts</p>)"); 0135 0136 QCOMPARE(tags[1], QStringLiteral("gamedev")); 0137 QCOMPARE(content, expected); 0138 } 0139 0140 // Ensure that posts that paragraphs that have a mix of tags and text don't get snipped 0141 void testContentParsingEdgeCaseFour() 0142 { 0143 const QString testHtml = QStringLiteral( 0144 R"(<p>I never got around to writing my <a href=\"/tags/introduction\" class=\"mention hashtag status-link\" rel=\"tag\">#<span>introduction</span></a>, so here it is then.</p><p><a href=\"/tags/Books\" class=\"mention hashtag status-link\" rel=\"tag\">#<span>Books</span></a> & <a href=\"/tags/movies\" class=\"mention hashtag status-link\" rel=\"tag\">#<span>movies</span></a> recommendations are always welcome!</p>)"); 0145 0146 const auto [content, tags] = Post::parseContent(testHtml); 0147 0148 // Nothing should happen to this text 0149 QVERIFY(tags.empty()); 0150 QCOMPARE(content, testHtml); 0151 } 0152 }; 0153 0154 QTEST_MAIN(PostTest) 0155 #include "posttest.moc"