Warning, file /utilities/telly-skout/autotests/tvspielfilmfetchertest.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // SPDX-FileCopyrightText: 2022 Plata Hill <plata.hill@kdemail.net>
0002 // SPDX-License-Identifier: LGPL-2.1-or-later
0003 
0004 #include "../src/tvspielfilmfetcher.h"
0005 
0006 #include <QFile>
0007 #include <QHash>
0008 #include <QNetworkAccessManager>
0009 #include <QNetworkReply>
0010 #include <QSignalSpy>
0011 #include <QStandardPaths>
0012 #include <QString>
0013 #include <QTest>
0014 
0015 namespace
0016 {
0017 class MockQNetworkReply : public QNetworkReply
0018 {
0019     Q_OBJECT
0020 public:
0021     explicit MockQNetworkReply(const QString &dataFileName, QObject *parent = nullptr)
0022         : QNetworkReply(parent)
0023     {
0024         setError(NetworkError::NoError, QString());
0025         setFinished(true);
0026 
0027         m_data.setFileName(QFINDTESTDATA(dataFileName));
0028         m_data.open(QIODevice::ReadOnly);
0029     }
0030 
0031     qint64 readData(char *data, qint64 maxlen) override
0032     {
0033         return m_data.read(data, maxlen);
0034     }
0035 
0036     void abort() override
0037     {
0038     }
0039 
0040 private:
0041     QFile m_data;
0042 };
0043 
0044 class MockQNetworkAccessManager : public QNetworkAccessManager
0045 {
0046     Q_OBJECT
0047 public:
0048     explicit MockQNetworkAccessManager(QObject *parent = nullptr)
0049         : QNetworkAccessManager(parent)
0050     {
0051     }
0052 
0053     QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData = nullptr) override
0054     {
0055         Q_UNUSED(op);
0056         Q_UNUSED(outgoingData);
0057         if (m_replies.contains(request.url().toString())) {
0058             QNetworkReply *reply = m_replies[request.url().toString()];
0059             reply->open(QIODevice::ReadOnly);
0060             return reply;
0061         } else {
0062             qWarning() << request.url() << m_replies;
0063         }
0064         return nullptr;
0065     }
0066 
0067     void registerReply(const QString &url, QNetworkReply *reply)
0068     {
0069         m_replies[url] = reply;
0070     }
0071 
0072 private:
0073     QHash<QString, QNetworkReply *> m_replies;
0074 };
0075 }
0076 
0077 class TvSpielfilmFetcherTest : public QObject
0078 {
0079     Q_OBJECT
0080 private Q_SLOTS:
0081     void initTestCase()
0082     {
0083         // TV Spielfilm: Europe/Berlin (UTC+1), DB: UTC
0084         // check that start/stop times are displayed correctly in Europe/Athens (UTC+2 = EET-2)
0085         qputenv("TZ", "EET-2");
0086         QStandardPaths::setTestModeEnabled(true);
0087     }
0088 
0089     void testFetchGroups()
0090     {
0091         MockQNetworkAccessManager nam;
0092         TvSpielfilmFetcher fetcher(&nam);
0093         QVector<GroupData> data;
0094         bool callbackCalled = false;
0095         bool errorCallbackCalled = false;
0096         fetcher.fetchGroups(
0097             [&data, &callbackCalled](const QVector<GroupData> &groups) {
0098                 data = groups;
0099                 callbackCalled = true;
0100             },
0101             [&errorCallbackCalled](Error) {
0102                 errorCallbackCalled = true;
0103             });
0104         QCOMPARE(callbackCalled, true);
0105         QCOMPARE(errorCallbackCalled, false);
0106         QCOMPARE(data.size(), 1);
0107         const GroupData &group = data.at(0);
0108         QCOMPARE(group.m_id.value(), "tvspielfilm.germany");
0109         QCOMPARE(group.m_name, "Germany");
0110         QCOMPARE(group.m_url, "https://www.tvspielfilm.de/tv-programm/sendungen");
0111     }
0112 
0113     void testFetchGroup()
0114     {
0115         QNetworkReply *reply = new MockQNetworkReply("data/tvspielfilmfetcher/channels.html");
0116         MockQNetworkAccessManager nam;
0117         nam.registerReply("https://www.tvspielfilm.de/tv-programm/sendungen", reply);
0118         TvSpielfilmFetcher fetcher(&nam);
0119         const GroupData group{GroupId("tvspielfilm.germany"), "Germany", "https://www.tvspielfilm.de/tv-programm/sendungen"};
0120         QList<ChannelData> data;
0121         bool callbackCalled = false;
0122         bool errorCallbackCalled = false;
0123         fetcher.fetchGroup(
0124             group.m_url,
0125             group.m_id,
0126             [&data, &callbackCalled](const QList<ChannelData> &channels) {
0127                 data = channels;
0128                 callbackCalled = true;
0129             },
0130             [&errorCallbackCalled](Error) {
0131                 errorCallbackCalled = true;
0132             });
0133         Q_EMIT reply->finished();
0134         QCOMPARE(callbackCalled, true);
0135         QCOMPARE(errorCallbackCalled, false);
0136         QCOMPARE(data.size(), 212);
0137     }
0138 
0139     void testFetchProgram()
0140     {
0141         const ChannelId channelId("SWR");
0142 
0143         QNetworkReply *replyYesterday = new MockQNetworkReply("data/tvspielfilmfetcher/empty.html");
0144         QNetworkReply *replyTodayPage1 = new MockQNetworkReply("data/tvspielfilmfetcher/swr-page1.html");
0145         QNetworkReply *replyTodayPage2 = new MockQNetworkReply("data/tvspielfilmfetcher/swr-page2.html");
0146         QNetworkReply *replyTomorrow = new MockQNetworkReply("data/tvspielfilmfetcher/empty.html");
0147         MockQNetworkAccessManager nam;
0148 
0149         const QString yesterday = QDate::currentDate().addDays(-1).toString("yyyy-MM-dd");
0150         const QString today = QDate::currentDate().toString("yyyy-MM-dd");
0151         const QString tomorrow = QDate::currentDate().addDays(1).toString("yyyy-MM-dd");
0152 
0153         const QString url = "https://www.tvspielfilm.de/tv-programm/sendungen/?time=day&channel=" + channelId.value();
0154         nam.registerReply(url + "&date=" + yesterday + "&page=1", replyYesterday);
0155         nam.registerReply(url + "&date=" + today + "&page=1", replyTodayPage1);
0156         nam.registerReply(url + "&date=" + today + "&page=2", replyTodayPage2); // link for 2022-12-28 page 2 hard coded in swr-page1.html
0157         nam.registerReply(url + "&date=" + tomorrow + "&page=1", replyTomorrow);
0158 
0159         TvSpielfilmFetcher fetcher(&nam);
0160         QVector<ProgramData> data;
0161         bool callbackCalled = false;
0162         bool errorCallbackCalled = false;
0163         fetcher.fetchProgram(
0164             channelId,
0165             [&data, &callbackCalled](const QVector<ProgramData> &programs) {
0166                 data = programs;
0167                 callbackCalled = true;
0168             },
0169             [&errorCallbackCalled](Error) {
0170                 errorCallbackCalled = true;
0171             });
0172         Q_EMIT replyTomorrow->finished();
0173         Q_EMIT replyTodayPage1->finished();
0174         Q_EMIT replyTodayPage2->finished();
0175         Q_EMIT replyYesterday->finished();
0176         QCOMPARE(callbackCalled, true);
0177         QCOMPARE(errorCallbackCalled, false);
0178         QCOMPARE(data.size(), 3);
0179 
0180         QCOMPARE(data.at(0).m_id, ProgramId("SWR_1672182000"));
0181         QCOMPARE(data.at(0).m_url, "https://www.tvspielfilm.de/tv-programm/sendung/description1.html");
0182         QCOMPARE(data.at(0).m_channelId, channelId);
0183         QCOMPARE(data.at(0).m_startTime, QDateTime::fromString("2022-12-28T01:00:00", Qt::ISODate));
0184         QCOMPARE(data.at(0).m_stopTime, QDateTime::fromString("2022-12-28T07:00:00", Qt::ISODate));
0185         QCOMPARE(data.at(0).m_title, "Title 1");
0186         QCOMPARE(data.at(0).m_subtitle, "");
0187         QCOMPARE(data.at(0).m_description, "");
0188         QCOMPARE(data.at(0).m_descriptionFetched, false);
0189         QCOMPARE(data.at(0).m_categories.at(0), "Category 1");
0190 
0191         QCOMPARE(data.at(1).m_id, ProgramId("SWR_1672203600"));
0192         QCOMPARE(data.at(1).m_url, "https://www.tvspielfilm.de/tv-programm/sendung/description2.html");
0193         QCOMPARE(data.at(1).m_channelId, channelId);
0194         QCOMPARE(data.at(1).m_startTime, QDateTime::fromString("2022-12-28T07:00:00", Qt::ISODate));
0195         QCOMPARE(data.at(1).m_stopTime, QDateTime::fromString("2022-12-28T10:00:00", Qt::ISODate));
0196         QCOMPARE(data.at(1).m_title, "Title 2");
0197         QCOMPARE(data.at(1).m_subtitle, "");
0198         QCOMPARE(data.at(1).m_description, "");
0199         QCOMPARE(data.at(1).m_descriptionFetched, false);
0200         QCOMPARE(data.at(1).m_categories.at(0), "Category 2");
0201 
0202         QCOMPARE(data.at(2).m_id, ProgramId("SWR_1672214400"));
0203         QCOMPARE(data.at(2).m_url, "https://www.tvspielfilm.de/tv-programm/sendung/description3.html");
0204         QCOMPARE(data.at(2).m_channelId, channelId);
0205         QCOMPARE(data.at(2).m_startTime, QDateTime::fromString("2022-12-28T10:00:00", Qt::ISODate));
0206         QCOMPARE(data.at(2).m_stopTime, QDateTime::fromString("2022-12-28T13:00:00", Qt::ISODate));
0207         QCOMPARE(data.at(2).m_title, "Title 3");
0208         QCOMPARE(data.at(2).m_subtitle, "");
0209         QCOMPARE(data.at(2).m_description, "");
0210         QCOMPARE(data.at(2).m_descriptionFetched, false);
0211         QCOMPARE(data.at(2).m_categories.at(0), "Category 3");
0212     }
0213 
0214     void testFetchProgramDescription()
0215     {
0216         const ChannelId channelId("SWR");
0217         ProgramId programId;
0218 
0219         QNetworkReply *reply = new MockQNetworkReply("data/tvspielfilmfetcher/description.html");
0220         MockQNetworkAccessManager nam;
0221         nam.registerReply("https://www.tvspielfilm.de/tv-programm/sendung/description1.html", reply);
0222         TvSpielfilmFetcher fetcher(&nam);
0223         QString data;
0224         bool callbackCalled = false;
0225         bool errorCallbackCalled = false;
0226         fetcher.fetchProgramDescription(
0227             channelId,
0228             ProgramId("channel1_1672182000"),
0229             "https://www.tvspielfilm.de/tv-programm/sendung/description1.html",
0230             [&data, &callbackCalled](const QString &description) {
0231                 data = description;
0232                 callbackCalled = true;
0233             },
0234             [&errorCallbackCalled](Error) {
0235                 errorCallbackCalled = true;
0236             });
0237         Q_EMIT reply->finished();
0238         QCOMPARE(callbackCalled, true);
0239         QCOMPARE(errorCallbackCalled, false);
0240         QCOMPARE(data, "Description");
0241     }
0242 };
0243 
0244 QTEST_GUILESS_MAIN(TvSpielfilmFetcherTest)
0245 
0246 #include "tvspielfilmfetchertest.moc"