File indexing completed on 2024-04-28 16:13:18

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"