File indexing completed on 2024-10-06 12:56:09
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 "helperreply.h" 0007 #include "mockaccount.h" 0008 #include "timeline/maintimelinemodel.h" 0009 #include "timeline/poll.h" 0010 #include "timeline/tagstimelinemodel.h" 0011 #include "timeline/threadmodel.h" 0012 #include <KLocalizedString> 0013 #include <QAbstractItemModelTester> 0014 #include <QSignalSpy> 0015 0016 class TimelineTest : public QObject 0017 { 0018 Q_OBJECT 0019 0020 private Q_SLOTS: 0021 void initTestCase() 0022 { 0023 account = new MockAccount(); 0024 AccountManager::instance().addAccount(account); 0025 AccountManager::instance().selectAccount(account); 0026 } 0027 0028 void cleanupTestCase() 0029 { 0030 AccountManager::instance().removeAccount(account); 0031 } 0032 0033 void testMainDisplayName() 0034 { 0035 KLocalizedString::setApplicationDomain("tokodon"); 0036 KLocalizedString::setLanguages(QStringList{"C"}); 0037 account->setUsername("test"); 0038 0039 QJsonObject fakeIdentity; 0040 fakeIdentity["id"] = QStringLiteral("1"); 0041 fakeIdentity["display_name"] = QStringLiteral("test"); 0042 0043 account->setFakeIdentity(fakeIdentity); 0044 0045 MainTimelineModel timelineModel; 0046 timelineModel.setName("public"); 0047 QCOMPARE(timelineModel.displayName(), "Local Timeline"); 0048 timelineModel.setName("federated"); 0049 QCOMPARE(timelineModel.displayName(), "Global Timeline"); 0050 timelineModel.setName("home"); 0051 QCOMPARE(timelineModel.displayName(), "Home"); 0052 0053 auto account2 = new MockAccount(); 0054 AccountManager::instance().addAccount(account2); 0055 0056 QCOMPARE(timelineModel.displayName(), "Home (test)"); 0057 0058 account->clearFakeIdentity(); 0059 } 0060 0061 void testStreamUpdate() 0062 { 0063 QFile statusExampleApi; 0064 statusExampleApi.setFileName(QLatin1String(DATA_DIR) + QLatin1Char('/') + "status.json"); 0065 statusExampleApi.open(QIODevice::ReadOnly); 0066 0067 MainTimelineModel timelineModel; 0068 timelineModel.setName("home"); 0069 QCOMPARE(timelineModel.rowCount({}), 0); 0070 0071 account->streamingEvent(AbstractAccount::StreamingEventType::UpdateEvent, statusExampleApi.readAll()); 0072 QCOMPARE(timelineModel.rowCount({}), 1); 0073 } 0074 0075 void testFillTimelineMain() 0076 { 0077 account->registerGet(account->apiUrl(QStringLiteral("/api/v1/timelines/home")), new TestReply("statuses.json", account)); 0078 auto fetchMoreUrl = account->apiUrl(QStringLiteral("/api/v1/timelines/home")); 0079 fetchMoreUrl.setQuery(QUrlQuery{ 0080 {"max_id", "103270115826038975"}, 0081 }); 0082 account->registerGet(fetchMoreUrl, new TestReply("statuses.json", account)); 0083 0084 MainTimelineModel timelineModel; 0085 timelineModel.setName("home"); 0086 0087 QCOMPARE(timelineModel.rowCount({}), 2); 0088 QVERIFY(timelineModel.canFetchMore({})); 0089 timelineModel.fetchMore({}); 0090 QCOMPARE(timelineModel.rowCount({}), 4); 0091 } 0092 0093 void testTagModel() 0094 { 0095 account->registerGet(account->apiUrl(QStringLiteral("/api/v1/timelines/tag/home")), new TestReply("statuses.json", account)); 0096 auto fetchMoreUrl = account->apiUrl(QStringLiteral("/api/v1/timelines/tag/home")); 0097 fetchMoreUrl.setQuery(QUrlQuery{ 0098 {"max_id", "103270115826038975"}, 0099 }); 0100 account->registerGet(fetchMoreUrl, new TestReply("statuses.json", account)); 0101 0102 TagsTimelineModel tagModel; 0103 tagModel.setHashtag("home"); 0104 0105 QCOMPARE(tagModel.rowCount({}), 2); 0106 QVERIFY(tagModel.canFetchMore({})); 0107 tagModel.fetchMore({}); 0108 QCOMPARE(tagModel.rowCount({}), 4); 0109 } 0110 0111 void testThreadModel() 0112 { 0113 account->registerGet(account->apiUrl(QStringLiteral("/api/v1/statuses/103270115826048975")), new TestReply("status.json", account)); 0114 account->registerGet(account->apiUrl(QStringLiteral("/api/v1/statuses/103270115826048975/context")), new TestReply("context.json", account)); 0115 0116 ThreadModel threadModel; 0117 threadModel.setPostId(QStringLiteral("103270115826048975")); 0118 QCOMPARE(threadModel.rowCount({}), 3); 0119 QCOMPARE(threadModel.data(threadModel.index(1, 0), AbstractTimelineModel::SelectedRole).toBool(), true); 0120 QCOMPARE(threadModel.displayName(), "Thread"); 0121 QCOMPARE(threadModel.postId(), "103270115826048975"); 0122 QCOMPARE(threadModel.canFetchMore({}), false); 0123 } 0124 0125 void testModelPoll() 0126 { 0127 MainTimelineModel timelineModel; 0128 timelineModel.setName("home"); 0129 0130 QFile statusExampleApi; 0131 statusExampleApi.setFileName(QLatin1String(DATA_DIR) + QLatin1Char('/') + "status-poll.json"); 0132 statusExampleApi.open(QIODevice::ReadOnly); 0133 account->streamingEvent(AbstractAccount::StreamingEventType::UpdateEvent, statusExampleApi.readAll()); 0134 QCOMPARE(timelineModel.rowCount({}), 1); 0135 0136 QCOMPARE(timelineModel.data(timelineModel.index(0, 0), AbstractTimelineModel::IdRole).value<QString>(), "103270115826048975"); 0137 QCOMPARE(timelineModel.data(timelineModel.index(0, 0), AbstractTimelineModel::MentionsRole).value<QStringList>(), QStringList{}); 0138 QCOMPARE(timelineModel.data(timelineModel.index(0, 0), AbstractTimelineModel::ContentRole).value<QString>(), "<p>LOREM</p>"); 0139 QCOMPARE(timelineModel.data(timelineModel.index(0, 0), AbstractTimelineModel::AuthorIdentityRole).value<Identity *>()->id(), QStringLiteral("1")); 0140 QCOMPARE(timelineModel.data(timelineModel.index(0, 0), AbstractTimelineModel::AuthorIdentityRole).value<Identity *>()->displayNameHtml(), 0141 QStringLiteral("Eugen <img height=\"16\" align=\"middle\" width=\"16\" src=\"https://kde.org\">")); 0142 QCOMPARE(timelineModel.data(timelineModel.index(0, 0), AbstractTimelineModel::IsBoostedRole).value<bool>(), false); 0143 0144 const auto poll = timelineModel.data(timelineModel.index(0, 0), AbstractTimelineModel::PollRole).value<Poll>(); 0145 QCOMPARE(poll.id(), "34830"); 0146 QCOMPARE(poll.expiresAt().date().year(), 2019); 0147 QCOMPARE(poll.expired(), true); 0148 QCOMPARE(poll.multiple(), false); 0149 QCOMPARE(poll.votesCount(), 10); 0150 QCOMPARE(poll.votersCount(), -1); 0151 QCOMPARE(poll.voted(), true); 0152 QCOMPARE(poll.ownVotes().count(), 1); 0153 QCOMPARE(poll.ownVotes()[0], 1); 0154 QCOMPARE(poll.options().count(), 2); 0155 QCOMPARE(poll.options()[0]["title"], QStringLiteral("accept")); 0156 QCOMPARE(poll.options()[0]["votesCount"], 6); 0157 QCOMPARE(poll.options()[1]["title"], QStringLiteral("deny <img height=\"16\" align=\"middle\" width=\"16\" src=\"https://kde.org\">")); 0158 QCOMPARE(poll.options()[1]["votesCount"], 4); 0159 0160 account->registerPost(QString("/api/v1/polls/34830/votes"), new TestReply("poll.json", account)); 0161 0162 QSignalSpy spy(&timelineModel, &QAbstractItemModel::dataChanged); 0163 QVERIFY(spy.isValid()); 0164 timelineModel.actionVote(timelineModel.index(0, 0), {0}); 0165 spy.wait(1000); 0166 QCOMPARE(spy.count(), 1); 0167 const auto arguments = spy.takeFirst(); 0168 QCOMPARE(arguments[0].value<QModelIndex>().row(), 0); 0169 QCOMPARE(arguments[1].value<QModelIndex>().row(), 0); 0170 QCOMPARE(arguments[2].value<QVector<int>>().count(), 1); 0171 QCOMPARE(arguments[2].value<QVector<int>>()[0], AbstractTimelineModel::PollRole); 0172 } 0173 0174 private: 0175 MockAccount *account; 0176 }; 0177 0178 QTEST_MAIN(TimelineTest) 0179 #include "timelinetest.moc"