File indexing completed on 2025-01-19 04:46:58

0001 /*
0002  * SPDX-FileCopyrightText: 2016 Daniel Vrátil <dvratil@kde.org>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-or-later
0005  *
0006  */
0007 
0008 #include "eventdatavisitortest.h"
0009 #include "../eventdatavisitor.h"
0010 #include "fakepimdatasource.h"
0011 #include "testdataparser.h"
0012 #include "testutils.h"
0013 
0014 #include <QTest>
0015 
0016 #include <KCalendarCore/Event>
0017 #include <KCalendarCore/Todo>
0018 
0019 #include <CalendarEvents/CalendarEventsPlugin>
0020 
0021 Q_DECLARE_METATYPE(CalendarEvents::EventData)
0022 Q_DECLARE_METATYPE(KCalendarCore::Incidence::Ptr)
0023 
0024 template<typename Visitor>
0025 class TestableVisitor : public Visitor
0026 {
0027 public:
0028     TestableVisitor(PimDataSource *source, QDate start = QDate(), QDate end = QDate())
0029         : Visitor(source, start, end)
0030     {
0031     }
0032 
0033     [[nodiscard]] QString callGenerateUid(const KCalendarCore::Incidence::Ptr &incidence, const QDateTime &recurrenceId) const
0034     {
0035         return Visitor::generateUid(incidence, recurrenceId);
0036     }
0037 
0038     [[nodiscard]] bool callIsInRange(QDate start, QDate end) const
0039     {
0040         return Visitor::isInRange(start, end);
0041     }
0042 
0043     QList<CalendarEvents::EventData>
0044     callExplodeIncidenceOccurences(const CalendarEvents::EventData &baseEd, const KCalendarCore::Incidence::Ptr &incidence, bool &ok)
0045     {
0046         return Visitor::explodeIncidenceOccurences(baseEd, incidence, ok);
0047     }
0048 };
0049 
0050 using TestableEventDataVisitor = TestableVisitor<EventDataVisitor>;
0051 using TestableEventDataIdVisitor = TestableVisitor<EventDataIdVisitor>;
0052 
0053 using DateTimeRange = QPair<QDateTime, QDateTime>;
0054 
0055 void EventDataVisitorTest::initTestCase()
0056 {
0057     qputenv("TZ", "Europe/Berlin");
0058 }
0059 
0060 void EventDataVisitorTest::testGenerateUID_data()
0061 {
0062     QTest::addColumn<KCalendarCore::Incidence::Ptr>("incidence");
0063     QTest::addColumn<QDateTime>("recurrenceId");
0064     QTest::addColumn<qint64>("itemId");
0065     QTest::addColumn<QString>("expectedUID");
0066 
0067     auto incidence = KCalendarCore::Event::Ptr::create().staticCast<KCalendarCore::Incidence>();
0068     QTest::newRow("simple event") << incidence << QDateTime() << 1ll << QStringLiteral("Akonadi-1");
0069     QTest::newRow("recurring event") << incidence << QDateTime(QDate(2016, 5, 29), QTime(15, 47, 0), Qt::UTC) << 1ll
0070                                      << QStringLiteral("Akonadi-1-20160529T154700UTC");
0071 
0072     incidence = KCalendarCore::Todo::Ptr::create().staticCast<KCalendarCore::Incidence>();
0073     QTest::newRow("simple todo") << incidence << QDateTime() << 42ll << QStringLiteral("Akonadi-42");
0074     QTest::newRow("recurring todo") << incidence << QDateTime(QDate(2016, 5, 29), QTime(15, 49, 5), Qt::UTC) << 42ll
0075                                     << QStringLiteral("Akonadi-42-20160529T154905UTC");
0076 }
0077 
0078 void EventDataVisitorTest::testGenerateUID()
0079 {
0080     QFETCH(KCalendarCore::Incidence::Ptr, incidence);
0081     QFETCH(QDateTime, recurrenceId);
0082     QFETCH(qint64, itemId);
0083     QFETCH(QString, expectedUID);
0084 
0085     FakePimDataSource source;
0086     source.setAkonadiIdForIncidence(incidence, itemId);
0087     TestableEventDataVisitor visitor(&source);
0088 
0089     const QString result = visitor.callGenerateUid(incidence, recurrenceId);
0090     QCOMPARE(result, expectedUID);
0091 }
0092 
0093 void EventDataVisitorTest::testIsInRange_data()
0094 {
0095     QTest::addColumn<QDate>("rangeStart");
0096     QTest::addColumn<QDate>("rangeEnd");
0097     QTest::addColumn<QDate>("eventStart");
0098     QTest::addColumn<QDate>("eventEnd");
0099     QTest::addColumn<bool>("expectedResult");
0100 
0101     QTest::newRow("single day fully in-range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 3) << QDate(2016, 5, 3) << true;
0102     QTest::newRow("multiday fully in-range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 3) << QDate(2016, 5, 15) << true;
0103     QTest::newRow("multiday start overlap") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 4, 28) << QDate(2016, 5, 5) << true;
0104     QTest::newRow("multiday end overlap") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 28) << QDate(2016, 6, 5) << true;
0105     QTest::newRow("single day range edge start") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 1) << QDate(2016, 5, 1) << true;
0106     QTest::newRow("single day range edge end") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 31) << QDate(2016, 5, 31) << true;
0107     QTest::newRow("multiday range edge start") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 1) << QDate(2016, 5, 10) << true;
0108     QTest::newRow("multiday range edge end") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 5, 20) << QDate(2016, 5, 31) << true;
0109     QTest::newRow("single day before range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 4, 28) << QDate(2016, 4, 28) << false;
0110     QTest::newRow("single day after range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 6, 4) << QDate(2016, 6, 4) << false;
0111     QTest::newRow("multiday before range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 4, 12) << QDate(2016, 4, 20) << false;
0112     QTest::newRow("multiday after range") << QDate(2016, 5, 1) << QDate(2016, 5, 31) << QDate(2016, 6, 5) << QDate(2016, 6, 10) << false;
0113 }
0114 
0115 void EventDataVisitorTest::testIsInRange()
0116 {
0117     QFETCH(QDate, rangeStart);
0118     QFETCH(QDate, rangeEnd);
0119     QFETCH(QDate, eventStart);
0120     QFETCH(QDate, eventEnd);
0121     QFETCH(bool, expectedResult);
0122 
0123     FakePimDataSource source;
0124     TestableEventDataVisitor visitor(&source, rangeStart, rangeEnd);
0125     const bool result = visitor.callIsInRange(eventStart, eventEnd);
0126     QCOMPARE(result, expectedResult);
0127 }
0128 
0129 void EventDataVisitorTest::testExplodeIncidenceOccurences_data()
0130 {
0131     QTest::addColumn<QDate>("rangeStart");
0132     QTest::addColumn<QDate>("rangeEnd");
0133     QTest::addColumn<CalendarEvents::EventData>("baseEventData");
0134     QTest::addColumn<KCalendarCore::Incidence::Ptr>("incidence");
0135     QTest::addColumn<qint64>("akonadiItemId");
0136     QTest::addColumn<QList<CalendarEvents::EventData>>("expectedEventData");
0137 
0138     const auto allTestData = TestDataParser::allTestData();
0139     for (const auto &testData : allTestData) {
0140         TestDataParser parser(testData, true);
0141         // skip non-recurring testcases
0142         if (!parser.incidence()->recurs()) {
0143             continue;
0144         }
0145         QTest::newRow(qPrintable(testData)) << parser.rangeStart() << parser.rangeEnd() << parser.eventData().constFirst() << parser.incidence()
0146                                             << parser.akonadiId() << parser.eventData();
0147     }
0148 }
0149 
0150 void EventDataVisitorTest::testExplodeIncidenceOccurences()
0151 {
0152     QFETCH(QDate, rangeStart);
0153     QFETCH(QDate, rangeEnd);
0154     QFETCH(CalendarEvents::EventData, baseEventData);
0155     QFETCH(KCalendarCore::Incidence::Ptr, incidence);
0156     QFETCH(qint64, akonadiItemId);
0157     QFETCH(QList<CalendarEvents::EventData>, expectedEventData);
0158 
0159     FakePimDataSource source;
0160     source.setAkonadiIdForIncidence(incidence, akonadiItemId);
0161     TestableEventDataVisitor visitor(&source, rangeStart, rangeEnd);
0162     bool ok = false;
0163     const auto results = visitor.callExplodeIncidenceOccurences(baseEventData, incidence, ok);
0164     QVERIFY(ok);
0165 
0166     QCOMPARE(results.size(), expectedEventData.size());
0167     for (int i = 0; i < results.size(); ++i) {
0168         QVERIFY(TestUtils::compareEventData(results[i], expectedEventData[i]));
0169     }
0170 }
0171 
0172 void EventDataVisitorTest::testEventDataVisitor_data()
0173 {
0174     QTest::addColumn<QDate>("rangeStart");
0175     QTest::addColumn<QDate>("rangeEnd");
0176     QTest::addColumn<KCalendarCore::Incidence::Ptr>("incidence");
0177     QTest::addColumn<qint64>("akonadiItemId");
0178     QTest::addColumn<QList<CalendarEvents::EventData>>("expectedResults");
0179 
0180     const auto allTestData = TestDataParser::allTestData();
0181     for (const auto &testData : allTestData) {
0182         TestDataParser parser(testData);
0183 
0184         QTest::newRow(qPrintable(testData)) << parser.rangeStart() << parser.rangeEnd() << parser.incidence() << parser.akonadiId() << parser.eventData();
0185     }
0186 }
0187 
0188 void EventDataVisitorTest::testEventDataVisitor()
0189 {
0190     QFETCH(QDate, rangeStart);
0191     QFETCH(QDate, rangeEnd);
0192     QFETCH(KCalendarCore::Incidence::Ptr, incidence);
0193     QFETCH(qint64, akonadiItemId);
0194     QFETCH(QList<CalendarEvents::EventData>, expectedResults);
0195 
0196     FakePimDataSource source;
0197     source.setAkonadiIdForIncidence(incidence, akonadiItemId);
0198     TestableEventDataVisitor visitor(&source, rangeStart, rangeEnd);
0199     QVERIFY(visitor.act(incidence));
0200 
0201     const auto &results = visitor.results();
0202     QCOMPARE(results.size(), expectedResults.size());
0203 
0204     auto resultValues = results.values();
0205     std::sort(resultValues.begin(), resultValues.end(), std::less<CalendarEvents::EventData>());
0206     for (int i = 0; i < resultValues.size(); ++i) {
0207         const auto &result = resultValues[i];
0208         const auto &expectedResult = expectedResults[i];
0209 
0210         QVERIFY(TestUtils::compareEventData(result, expectedResult));
0211     }
0212 }
0213 
0214 void EventDataVisitorTest::testEventDataIdVisitor_data()
0215 {
0216     QTest::addColumn<QDate>("rangeStart");
0217     QTest::addColumn<QDate>("rangeEnd");
0218     QTest::addColumn<KCalendarCore::Incidence::Ptr>("incidence");
0219     QTest::addColumn<qint64>("akonadiItemId");
0220     QTest::addColumn<QStringList>("expectedUids");
0221 
0222     const auto allTestData = TestDataParser::allTestData();
0223     for (const auto &testData : allTestData) {
0224         TestDataParser parser(testData, true);
0225         QStringList uids;
0226         for (const auto &ed : parser.eventData()) {
0227             uids.push_back(ed.uid());
0228         }
0229         QTest::newRow(qPrintable(testData)) << parser.rangeStart() << parser.rangeEnd() << parser.incidence() << parser.akonadiId() << uids;
0230     }
0231 }
0232 
0233 void EventDataVisitorTest::testEventDataIdVisitor()
0234 {
0235     QFETCH(QDate, rangeStart);
0236     QFETCH(QDate, rangeEnd);
0237     QFETCH(KCalendarCore::Incidence::Ptr, incidence);
0238     QFETCH(qint64, akonadiItemId);
0239     QFETCH(QStringList, expectedUids);
0240 
0241     FakePimDataSource source;
0242     source.setAkonadiIdForIncidence(incidence, akonadiItemId);
0243     TestableEventDataIdVisitor visitor(&source, rangeStart, rangeEnd);
0244     QVERIFY(visitor.act(incidence));
0245 
0246     auto results = visitor.results();
0247 
0248     std::sort(results.begin(), results.end());
0249     std::sort(expectedUids.begin(), expectedUids.end());
0250     QCOMPARE(results, expectedUids);
0251 }
0252 
0253 QTEST_MAIN(EventDataVisitorTest)
0254 
0255 #include "moc_eventdatavisitortest.cpp"