File indexing completed on 2025-01-19 04:46:59
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 "pimeventsplugintest.h" 0009 #include "../pimeventsplugin.h" 0010 #include "fakepimdatasource.h" 0011 #include "testdataparser.h" 0012 #include "testutils.h" 0013 0014 #include <QSignalSpy> 0015 #include <QTest> 0016 0017 Q_DECLARE_METATYPE(DateEventDataHash) 0018 Q_DECLARE_METATYPE(CalendarEvents::EventData) 0019 0020 void PimEventsPluginTest::initTestCase() 0021 { 0022 qputenv("TZ", "Europe/Berlin"); 0023 qRegisterMetaType<DateEventDataHash>("QMultiHash<QDate, CalendarEvents::EventData>"); 0024 qRegisterMetaType<CalendarEvents::EventData>("CalendarEvents::EventData"); 0025 } 0026 0027 bool PimEventsPluginTest::compareEventDataHashes(const DateEventDataHash &actual, const DateEventDataHash &expected) 0028 { 0029 COMPARE(actual.size(), expected.size()); 0030 for (const QDate &resultKey : actual.uniqueKeys()) { 0031 VERIFY(expected.contains(resultKey)); 0032 auto resultValues = actual.values(resultKey); 0033 auto expectedValues = expected.values(resultKey); 0034 COMPARE(resultValues.size(), expectedValues.size()); 0035 std::sort(resultValues.begin(), resultValues.end(), std::less<CalendarEvents::EventData>()); 0036 std::sort(expectedValues.begin(), expectedValues.end(), std::less<CalendarEvents::EventData>()); 0037 COMPARE(resultValues, expectedValues); 0038 } 0039 return true; 0040 } 0041 0042 DateEventDataHash PimEventsPluginTest::populateCalendar(FakePimDataSource *source, bool uniqueEventData) 0043 { 0044 const QStringList allData = TestDataParser::allTestData(); 0045 DateEventDataHash expectedData; 0046 for (const QString &data : allData) { 0047 TestDataParser parser(data, true); 0048 if (parser.rangeEnd() < QDate(2016, 5, 1) || parser.rangeStart() > QDate(2016, 5, 31)) { 0049 continue; 0050 } 0051 const KCalendarCore::Event::Ptr event = parser.incidence().dynamicCast<KCalendarCore::Event>(); 0052 if (event) { 0053 source->setAkonadiIdForIncidence(event, parser.akonadiId()); 0054 source->calendar()->addEvent(event); 0055 for (const CalendarEvents::EventData &dt : parser.eventData()) { 0056 if (uniqueEventData) { 0057 expectedData.insert(dt.startDateTime().date(), dt); 0058 } else { 0059 QDate d = dt.startDateTime().date(); 0060 while (d <= dt.endDateTime().date()) { 0061 expectedData.insert(d, dt); 0062 d = d.addDays(1); 0063 } 0064 } 0065 } 0066 } 0067 } 0068 0069 return expectedData; 0070 } 0071 0072 QList<CalendarEvents::EventData> PimEventsPluginTest::findEventData(const KCalendarCore::Event::Ptr &event, const DateEventDataHash &allData) 0073 { 0074 QList<CalendarEvents::EventData> data; 0075 for (auto it = allData.cbegin(), end = allData.cend(); it != end; ++it) { 0076 // This is a very naive check 0077 if (it->title() == event->summary() && it->description() == event->description() && it->isAllDay() == event->allDay()) { 0078 data.push_back((*it)); 0079 } 0080 } 0081 0082 return data; 0083 } 0084 0085 void PimEventsPluginTest::testLoadEventsForDataRange() 0086 { 0087 FakePimDataSource source; 0088 const DateEventDataHash expectedData = populateCalendar(&source, false); 0089 0090 PimEventsPlugin plugin(&source); 0091 QSignalSpy dataReadySpy(&plugin, &PimEventsPlugin::dataReady); 0092 QVERIFY(dataReadySpy.isValid()); 0093 0094 plugin.loadEventsForDateRange(QDate(2016, 5, 1), QDate(2016, 5, 31)); 0095 QCOMPARE(dataReadySpy.size(), 1); 0096 const auto results = dataReadySpy.takeFirst().constFirst().value<DateEventDataHash>(); 0097 QVERIFY(compareEventDataHashes(results, expectedData)); 0098 0099 plugin.loadEventsForDateRange(QDate(2016, 1, 1), QDate(2016, 1, 30)); 0100 QCOMPARE(dataReadySpy.size(), 0); 0101 } 0102 0103 void PimEventsPluginTest::testEventAdded() 0104 { 0105 const QStringList allData = TestDataParser::allTestData(); 0106 0107 FakePimDataSource source; 0108 0109 PimEventsPlugin plugin(&source); 0110 QSignalSpy dataReadySpy(&plugin, &PimEventsPlugin::dataReady); 0111 QVERIFY(dataReadySpy.isValid()); 0112 0113 plugin.loadEventsForDateRange(QDate(2016, 5, 1), QDate(2016, 5, 31)); 0114 QCOMPARE(dataReadySpy.size(), 0); 0115 0116 for (const QString &data : allData) { 0117 TestDataParser parser(data, true); 0118 if (parser.rangeEnd() < QDate(2016, 5, 1) || parser.rangeStart() > QDate(2016, 5, 31)) { 0119 continue; 0120 } 0121 const KCalendarCore::Event::Ptr event = parser.incidence().dynamicCast<KCalendarCore::Event>(); 0122 if (event) { 0123 source.setAkonadiIdForIncidence(event, parser.akonadiId()); 0124 source.calendar()->addEvent(event); 0125 DateEventDataHash expectedData; 0126 for (const CalendarEvents::EventData &dt : parser.eventData()) { 0127 QDate d = dt.startDateTime().date(); 0128 while (d <= dt.endDateTime().date()) { 0129 expectedData.insert(d, dt); 0130 d = d.addDays(1); 0131 } 0132 } 0133 0134 QCOMPARE(dataReadySpy.size(), 1); 0135 const auto results = dataReadySpy.takeFirst().first().value<DateEventDataHash>(); 0136 QVERIFY(compareEventDataHashes(results, expectedData)); 0137 } 0138 } 0139 } 0140 0141 void PimEventsPluginTest::testEventModified() 0142 { 0143 FakePimDataSource source; 0144 0145 PimEventsPlugin plugin(&source); 0146 QSignalSpy eventModifiedSpy(&plugin, &PimEventsPlugin::eventModified); 0147 QVERIFY(eventModifiedSpy.isValid()); 0148 0149 // Populate model 0150 const auto allData = populateCalendar(&source, true); 0151 0152 // We don't care about the result of this, we just need to have mStart and 0153 // mEnd set 0154 plugin.loadEventsForDateRange(QDate(2016, 5, 1), QDate(2016, 5, 31)); 0155 0156 // Non-recurring event 0157 { 0158 QVERIFY(eventModifiedSpy.isEmpty()); 0159 KCalendarCore::Event::Ptr event = source.calendar()->event(QStringLiteral("4d7fdd2c-2d3a-4ecf-8964-00eb92225209")); 0160 QVERIFY(event); 0161 const auto expectedData = findEventData(event, allData); 0162 QCOMPARE(expectedData.size(), 1); 0163 event->setSummary(QStringLiteral("TEST")); 0164 0165 QVERIFY(source.calendar()->addEvent(event)); 0166 0167 QCOMPARE(eventModifiedSpy.size(), 1); 0168 const auto result = eventModifiedSpy.takeFirst().constFirst().value<CalendarEvents::EventData>(); 0169 // TODO: Test for other property changes too? 0170 QCOMPARE(result.title(), event->summary()); 0171 QCOMPARE(result.uid(), expectedData[0].uid()); 0172 } 0173 0174 // Recurring event 0175 { 0176 QVERIFY(eventModifiedSpy.isEmpty()); 0177 KCalendarCore::Event::Ptr event = source.calendar()->event(QStringLiteral("69971015-fe9c-4800-a20e-d46bafa24e41")); 0178 QVERIFY(event); 0179 auto expectedData = findEventData(event, allData); 0180 event->setSummary(QStringLiteral("TEST2")); 0181 QVERIFY(source.calendar()->addEvent(event)); 0182 0183 QCOMPARE(eventModifiedSpy.size(), expectedData.size()); 0184 while (!eventModifiedSpy.isEmpty()) { 0185 const auto args = eventModifiedSpy.takeFirst(); 0186 const auto &resultData = args[0].value<CalendarEvents::EventData>(); 0187 const auto expected = std::find_if(expectedData.begin(), expectedData.end(), [resultData](const CalendarEvents::EventData &e) { 0188 return e.uid() == resultData.uid(); 0189 }); 0190 QVERIFY(expected != expectedData.end()); 0191 expectedData.erase(expected); 0192 QCOMPARE(resultData.title(), QString::fromLatin1("TEST2")); 0193 } 0194 QVERIFY(expectedData.isEmpty()); 0195 } 0196 } 0197 0198 void PimEventsPluginTest::testEventRemoved() 0199 { 0200 FakePimDataSource source; 0201 0202 PimEventsPlugin plugin(&source); 0203 QSignalSpy eventRemovedSpy(&plugin, &PimEventsPlugin::eventRemoved); 0204 QVERIFY(eventRemovedSpy.isValid()); 0205 0206 const auto allData = populateCalendar(&source, true); 0207 0208 // We don't care about the result of this, we just need to have mStart and 0209 // mEnd set 0210 plugin.loadEventsForDateRange(QDate(2016, 5, 1), QDate(2016, 5, 31)); 0211 0212 // Non-recurring event 0213 { 0214 QVERIFY(eventRemovedSpy.isEmpty()); 0215 const KCalendarCore::Event::Ptr event = source.calendar()->event(QStringLiteral("4d7fdd2c-2d3a-4ecf-8964-00eb92225209")); 0216 QVERIFY(event); 0217 const auto expectedData = findEventData(event, allData); 0218 QCOMPARE(expectedData.size(), 1); 0219 0220 QVERIFY(source.calendar()->deleteEvent(event)); 0221 0222 QCOMPARE(eventRemovedSpy.size(), 1); 0223 const auto result = eventRemovedSpy.takeFirst().first().toString(); 0224 QCOMPARE(result, expectedData[0].uid()); 0225 } 0226 0227 // Recurring event 0228 { 0229 QVERIFY(eventRemovedSpy.isEmpty()); 0230 KCalendarCore::Event::Ptr event = source.calendar()->event(QStringLiteral("69971015-fe9c-4800-a20e-d46bafa24e41")); 0231 QVERIFY(event); 0232 auto expectedData = findEventData(event, allData); 0233 0234 QVERIFY(source.calendar()->deleteEvent(event)); 0235 0236 QCOMPARE(eventRemovedSpy.size(), expectedData.size()); 0237 while (!eventRemovedSpy.isEmpty()) { 0238 const QString resultUid = eventRemovedSpy.takeFirst().first().toString(); 0239 const auto expected = std::find_if(expectedData.begin(), expectedData.end(), [resultUid](const CalendarEvents::EventData &e) { 0240 return e.uid() == resultUid; 0241 }); 0242 QVERIFY(expected != expectedData.end()); 0243 expectedData.erase(expected); 0244 } 0245 QVERIFY(expectedData.isEmpty()); 0246 } 0247 } 0248 0249 QTEST_MAIN(PimEventsPluginTest) 0250 0251 #include "moc_pimeventsplugintest.cpp"