File indexing completed on 2024-04-28 11:33:59
0001 /* 0002 This file is part of the kcalcore library. 0003 0004 SPDX-FileCopyrightText: 2006-2007 Allen Winter <winter@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "testmemorycalendar.h" 0010 #include "filestorage.h" 0011 #include "memorycalendar.h" 0012 0013 #include <QDebug> 0014 0015 #include <QTest> 0016 #include <QTimeZone> 0017 QTEST_MAIN(MemoryCalendarTest) 0018 0019 using namespace KCalendarCore; 0020 0021 void MemoryCalendarTest::testClose() 0022 { 0023 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0024 0025 Event::Ptr event1(new Event); 0026 cal->addIncidence(event1); 0027 0028 const QString nbuid = QString::fromLatin1("test-notebook"); 0029 QVERIFY(cal->addNotebook(nbuid, true)); 0030 0031 Event::Ptr event2(new Event); 0032 cal->addIncidence(event2); 0033 cal->setNotebook(event2, nbuid); 0034 0035 QCOMPARE(cal->incidences().count(), 2); 0036 QVERIFY(cal->instance(event1->instanceIdentifier())); 0037 QVERIFY(cal->instance(event2->instanceIdentifier())); 0038 QVERIFY(cal->event(event1->uid())); 0039 QVERIFY(cal->event(event2->uid())); 0040 QCOMPARE(cal->incidences(nbuid).count(), 1); 0041 0042 cal->close(); 0043 0044 QVERIFY(!cal->event(event1->uid())); 0045 QVERIFY(!cal->event(event2->uid())); 0046 QVERIFY(cal->incidences().isEmpty()); 0047 QVERIFY(cal->incidences(nbuid).isEmpty()); 0048 } 0049 0050 void MemoryCalendarTest::testValidity() 0051 { 0052 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0053 cal->setProductId(QStringLiteral("fredware calendar")); 0054 QVERIFY(cal->productId() == QLatin1String("fredware calendar")); 0055 QVERIFY(cal->timeZoneId() == QByteArrayLiteral("UTC")); 0056 QVERIFY(cal->timeZone() == QTimeZone::utc()); 0057 cal->close(); 0058 } 0059 0060 void MemoryCalendarTest::testInvalidTimeZone() 0061 { 0062 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone())); 0063 // On invalid time zone, fallback to system time zone. 0064 QVERIFY(cal->timeZone() == QTimeZone::systemTimeZone()); 0065 } 0066 0067 void MemoryCalendarTest::testEvents() 0068 { 0069 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0070 cal->setProductId(QStringLiteral("fredware calendar")); 0071 QDate dt = QDate::currentDate(); 0072 0073 Event::Ptr event1 = Event::Ptr(new Event()); 0074 event1->setUid(QStringLiteral("1")); 0075 event1->setDtStart(QDateTime(dt, {})); 0076 event1->setDtEnd(QDateTime(dt, {}).addDays(1)); 0077 event1->setAllDay(true); 0078 event1->setSummary(QStringLiteral("Event1 Summary")); 0079 event1->setDescription(QStringLiteral("This is a description of the first event")); 0080 event1->setLocation(QStringLiteral("the place")); 0081 0082 Event::Ptr event2 = Event::Ptr(new Event()); 0083 event2->setUid(QStringLiteral("2")); 0084 event2->setDtStart(QDateTime(dt, {}).addDays(1)); 0085 event2->setDtEnd(QDateTime(dt, {}).addDays(2)); 0086 event2->setAllDay(true); 0087 event2->setSummary(QStringLiteral("Event2 Summary")); 0088 event2->setDescription(QStringLiteral("This is a description of the second event")); 0089 event2->setLocation(QStringLiteral("the other place")); 0090 0091 QVERIFY(cal->addEvent(event1)); 0092 QVERIFY(cal->addEvent(event2)); 0093 0094 FileStorage store(cal, QStringLiteral("foo.ics")); 0095 QVERIFY(store.save()); 0096 cal->close(); 0097 QFile::remove(QStringLiteral("foo.ics")); 0098 } 0099 0100 void MemoryCalendarTest::testIncidences() 0101 { 0102 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0103 cal->setProductId(QStringLiteral("fredware calendar")); 0104 QDate dt = QDate::currentDate(); 0105 0106 Event::Ptr event1 = Event::Ptr(new Event()); 0107 event1->setUid(QStringLiteral("1")); 0108 event1->setDtStart(QDateTime(dt, {})); 0109 event1->setDtEnd(QDateTime(dt, {}).addDays(1)); 0110 event1->setAllDay(true); 0111 event1->setSummary(QStringLiteral("Event1 Summary")); 0112 event1->setDescription(QStringLiteral("This is a description of the first event")); 0113 event1->setLocation(QStringLiteral("the place")); 0114 0115 Event::Ptr event2 = Event::Ptr(new Event()); 0116 event2->setUid(QStringLiteral("2")); 0117 event2->setDtStart(QDateTime(dt, {}).addDays(1)); 0118 event2->setDtEnd(QDateTime(dt, {}).addDays(2)); 0119 event2->setAllDay(true); 0120 event2->setSummary(QStringLiteral("Event2 Summary")); 0121 event2->setDescription(QStringLiteral("This is a description of the second event")); 0122 event2->setLocation(QStringLiteral("the other place")); 0123 0124 QVERIFY(cal->addEvent(event1)); 0125 QVERIFY(cal->addEvent(event2)); 0126 0127 Todo::Ptr todo1 = Todo::Ptr(new Todo()); 0128 todo1->setUid(QStringLiteral("3")); 0129 todo1->setDtStart(QDateTime(dt, {}).addDays(1)); 0130 todo1->setDtDue(QDateTime(dt, {}).addDays(2)); 0131 todo1->setAllDay(true); 0132 todo1->setSummary(QStringLiteral("Todo1 Summary")); 0133 todo1->setDescription(QStringLiteral("This is a description of a todo")); 0134 todo1->setLocation(QStringLiteral("this place")); 0135 0136 Todo::Ptr todo2 = Todo::Ptr(new Todo()); 0137 todo2->setUid(QStringLiteral("4")); 0138 todo2->setDtStart(QDateTime(dt, {}).addDays(1)); 0139 todo2->setAllDay(true); 0140 todo2->setSummary(QStringLiteral("<qt><h1>Todo2 Summary</h1></qt>"), true); 0141 todo2->setDescription(QStringLiteral("This is a description of a todo")); 0142 todo2->setLocation(QStringLiteral("<html><a href=\"http://www.fred.com\">this place</a></html>"), true); 0143 0144 QVERIFY(cal->addTodo(todo1)); 0145 QVERIFY(cal->addTodo(todo2)); 0146 0147 FileStorage store(cal, QStringLiteral("foo.ics")); 0148 QVERIFY(store.save()); 0149 cal->close(); 0150 0151 QVERIFY(store.load()); 0152 Todo::Ptr todo = cal->incidence(QStringLiteral("4")).staticCast<Todo>(); 0153 QVERIFY(todo->uid() == QLatin1Char('4')); 0154 QVERIFY(todo->summaryIsRich()); 0155 QVERIFY(todo->locationIsRich()); 0156 cal->close(); 0157 QFile::remove(QStringLiteral("foo.ics")); 0158 } 0159 0160 void MemoryCalendarTest::testRelationsCrash() 0161 { 0162 // Before, there was a crash that occurred only when reloading a calendar in which 0163 // the incidences had special relations. 0164 // This test tests that scenario, and will crash if it fails. 0165 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0166 FileStorage store1(cal, QLatin1String(ICALTESTDATADIR) + QLatin1String("test_relations.ics")); 0167 QVERIFY(store1.load()); 0168 const Todo::List oldTodos = cal->todos(); 0169 qDebug() << "Loaded " << oldTodos.count() << " todos into oldTodos."; 0170 0171 FileStorage store2(cal, QLatin1String(ICALTESTDATADIR) + QLatin1String("test_relations.ics")); 0172 QVERIFY(store2.load()); 0173 const Todo::List newTodos = cal->todos(); 0174 qDebug() << "Loaded " << newTodos.count() << " into newTodos."; 0175 0176 // We can saftely access the old deleted todos here, since they are not really deleted 0177 // and are still kept in a map of deleted items somewhere. 0178 // 0179 // Here we make sure that non of the old items have connections to the new items, and 0180 // the other way around. 0181 0182 // This doesn't makes sense so i commented it. when you load a calendar the second time 0183 // it reuses what it can, so oldTodo == newTodo 0184 0185 /* foreach (const Todo::Ptr &oldTodo, oldTodos ) { 0186 foreach (const Todo::Ptr &newTodo, newTodos ) { 0187 QVERIFY( oldTodo != newTodo ); 0188 0189 // Make sure that none of the new todos point to an old, deleted todo 0190 QVERIFY( newTodo->relatedTo() != oldTodo ); 0191 QVERIFY( !newTodo->relations().contains( oldTodo ) ); 0192 0193 // Make sure that none of the old todos point to a new todo 0194 QVERIFY( oldTodo->relatedTo() != newTodo ); 0195 QVERIFY( !oldTodo->relations().contains( newTodo ) ); 0196 } 0197 } 0198 */ 0199 cal->close(); 0200 } 0201 0202 void MemoryCalendarTest::testRecurrenceExceptions() 0203 { 0204 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0205 cal->setProductId(QStringLiteral("fredware calendar")); 0206 QDate dt = QDate::currentDate(); 0207 QDateTime start(dt, {}); 0208 0209 Event::Ptr event1 = Event::Ptr(new Event()); 0210 event1->setUid(QStringLiteral("1")); 0211 event1->setDtStart(start); 0212 event1->setDtEnd(start.addDays(1)); 0213 event1->setSummary(QStringLiteral("Event1 Summary")); 0214 event1->recurrence()->setDaily(1); 0215 event1->recurrence()->setDuration(3); 0216 QVERIFY(cal->addEvent(event1)); 0217 0218 const QDateTime recurrenceId = event1->dtStart().addDays(1); 0219 Event::Ptr exception1 = cal->createException(event1, recurrenceId).staticCast<Event>(); 0220 QCOMPARE(exception1->recurrenceId(), recurrenceId); 0221 QCOMPARE(exception1->uid(), event1->uid()); 0222 exception1->setSummary(QStringLiteral("exception")); 0223 0224 QVERIFY(exception1); 0225 QVERIFY(cal->addEvent(exception1)); 0226 0227 QCOMPARE(cal->event(event1->uid()), event1); 0228 QCOMPARE(cal->event(event1->uid(), recurrenceId), exception1); 0229 0230 const Event::List incidences = cal->rawEvents(start.date(), start.addDays(3).date(), start.timeZone()); 0231 // Contains incidence and exception 0232 QCOMPARE(incidences.size(), 2); 0233 0234 // Returns only exceptions for an event 0235 const Event::List exceptions = cal->eventInstances(event1); 0236 QCOMPARE(exceptions.size(), 1); 0237 QCOMPARE(exceptions.first()->uid(), event1->uid()); 0238 QCOMPARE(exceptions.first()->summary(), exception1->summary()); 0239 } 0240 0241 void MemoryCalendarTest::testChangeRecurId() 0242 { 0243 // When we change the recurring id, internal hashtables should be updated. 0244 0245 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0246 QDateTime start(QDate::currentDate(), {}); 0247 0248 // Add main event 0249 Event::Ptr event1 = Event::Ptr(new Event()); 0250 const QString uid = QStringLiteral("1"); 0251 event1->setUid(uid); 0252 event1->setDtStart(start); 0253 event1->setDtEnd(start.addDays(1)); 0254 event1->setAllDay(true); 0255 event1->setSummary(QStringLiteral("Event1 Summary")); 0256 event1->recurrence()->setDaily(1); 0257 event1->recurrence()->setDuration(3); 0258 QVERIFY(cal->addEvent(event1)); 0259 0260 // Add exception event: 0261 const QDateTime recurrenceId = event1->dtStart().addDays(1); 0262 Event::Ptr exception1 = cal->createException(event1, recurrenceId).staticCast<Event>(); 0263 QCOMPARE(exception1->recurrenceId(), recurrenceId); 0264 QCOMPARE(exception1->uid(), event1->uid()); 0265 exception1->setSummary(QStringLiteral("exception")); 0266 QVERIFY(exception1); 0267 QVERIFY(cal->addEvent(exception1)); 0268 0269 const QString oldIdentifier = exception1->instanceIdentifier(); 0270 Incidence::Ptr foo = cal->instance(oldIdentifier); 0271 QVERIFY(foo && foo->hasRecurrenceId()); 0272 // Now change the recurring id! 0273 exception1->setRecurrenceId(start.addDays(2)); 0274 const QString newIdentifier = exception1->instanceIdentifier(); 0275 QVERIFY(oldIdentifier != newIdentifier); 0276 0277 foo = cal->instance(oldIdentifier); 0278 QVERIFY(!foo); 0279 0280 foo = cal->instance(newIdentifier); 0281 QVERIFY(foo); 0282 0283 // Test hashing 0284 Incidence::List incidences = cal->incidences(); 0285 QVERIFY(incidences.count() == 2); 0286 0287 QDateTime newRecId = start.addDays(2); 0288 Incidence::Ptr main = cal->incidence(uid); 0289 Incidence::Ptr exception = cal->incidence(uid, newRecId); 0290 Incidence::Ptr noException = cal->incidence(uid, recurrenceId); 0291 QVERIFY(!noException); 0292 QVERIFY(main); 0293 QVERIFY(exception); 0294 QVERIFY(exception->recurrenceId() == newRecId); 0295 QVERIFY(exception->summary() == QLatin1String("exception")); 0296 QVERIFY(main->summary() == event1->summary()); 0297 } 0298 0299 void MemoryCalendarTest::testRawEventsForDate() 0300 { 0301 // We're checking that events at a date in a given time zone 0302 // are properly returned for the day after / before if 0303 // the calendar is for another time zone. 0304 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0305 0306 Event::Ptr event = Event::Ptr(new Event()); 0307 event->setDtStart(QDateTime(QDate(2019, 10, 29), QTime(1, 30), QTimeZone("Asia/Ho_Chi_Minh"))); 0308 0309 QVERIFY(cal->addEvent(event)); 0310 0311 QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 28)).count(), 1); 0312 QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 29), QTimeZone("Asia/Ho_Chi_Minh")).count(), 1); 0313 0314 cal->setTimeZoneId("Asia/Ho_Chi_Minh"); 0315 QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 29)).count(), 1); 0316 QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 28), QTimeZone::utc()).count(), 1); 0317 0318 event->setDtStart(QDateTime(QDate(2019, 10, 30), QTime(23, 00), QTimeZone::utc())); 0319 QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 31)).count(), 1); 0320 QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 30), QTimeZone::utc()).count(), 1); 0321 0322 QVERIFY(cal->deleteIncidence(event)); 0323 QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 31)).count(), 0); 0324 0325 // Multi-days events are treated differently. 0326 event->setDtEnd(QDateTime(QDate(2019, 10, 31), QTime(23, 00), QTimeZone::utc())); 0327 QVERIFY(cal->addEvent(event)); 0328 QCOMPARE(cal->rawEventsForDate(QDate(2019, 10, 31)).count(), 1); 0329 QCOMPARE(cal->rawEventsForDate(QDate(2019, 11, 1)).count(), 1); 0330 0331 cal->close(); 0332 } 0333 0334 void MemoryCalendarTest::testVisibility() 0335 { 0336 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0337 const QString notebook = QLatin1String("Notebook"); 0338 0339 QVERIFY(cal->addNotebook(notebook, true)); 0340 QVERIFY(cal->isVisible(notebook)); 0341 0342 Event::Ptr event = Event::Ptr(new Event()); 0343 QVERIFY(cal->addIncidence(event)); 0344 QVERIFY(cal->setNotebook(event, notebook)); 0345 0346 QVERIFY(cal->isVisible(event)); 0347 0348 QVERIFY(cal->updateNotebook(notebook, false)); 0349 QVERIFY(!cal->isVisible(notebook)); 0350 QVERIFY(!cal->isVisible(event)); 0351 } 0352 0353 class TestCalendarObserver: public Calendar::CalendarObserver 0354 { 0355 public: 0356 TestCalendarObserver(const Calendar::Ptr &cal) 0357 : mCalendar(cal) 0358 { 0359 cal->registerObserver(this); 0360 } 0361 ~TestCalendarObserver() 0362 { 0363 mCalendar->unregisterObserver(this); 0364 } 0365 void calendarIncidenceChanged(const Incidence::Ptr &incidence) override 0366 { 0367 mUpdated.append(incidence); 0368 } 0369 bool hasIncidenceChanged(const Incidence::Ptr &incidence) const 0370 { 0371 return std::find_if(mUpdated.constBegin(), mUpdated.constEnd(), 0372 [incidence] (const Incidence::Ptr &it) { 0373 return (it->uid() == incidence->uid() 0374 && it->recurrenceId() == incidence->recurrenceId()); 0375 }) != mUpdated.constEnd(); 0376 } 0377 Incidence::List mUpdated; 0378 private: 0379 Calendar::Ptr mCalendar; 0380 }; 0381 0382 void MemoryCalendarTest::testNotebookChange() 0383 { 0384 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0385 TestCalendarObserver observer(cal); 0386 const QString notebook1 = QLatin1String("Notebook1"); 0387 const QString notebook2 = QLatin1String("Notebook2"); 0388 0389 QVERIFY(cal->addNotebook(notebook1, true)); 0390 QVERIFY(cal->addNotebook(notebook2, true)); 0391 0392 Event::Ptr event = Event::Ptr(new Event()); 0393 event->setDtStart(QDateTime(QDate(2022, 3, 23), QTime(10, 12), Qt::UTC)); 0394 event->recurrence()->setDaily(1); 0395 Incidence::Ptr exception = Calendar::createException(event, event->dtStart().addDays(3)); 0396 QVERIFY(exception); 0397 exception->setDtStart(exception->recurrenceId().addSecs(1800)); 0398 QVERIFY(cal->addIncidence(event)); 0399 QVERIFY(cal->addIncidence(exception)); 0400 QVERIFY(cal->notebook(event).isEmpty()); 0401 QVERIFY(cal->notebook(exception).isEmpty()); 0402 0403 QVERIFY(observer.mUpdated.isEmpty()); 0404 QVERIFY(cal->setNotebook(event, notebook1)); 0405 QCOMPARE(cal->notebook(event), notebook1); 0406 QCOMPARE(cal->notebook(exception), notebook1); 0407 QVERIFY(observer.hasIncidenceChanged(event)); 0408 QVERIFY(observer.hasIncidenceChanged(exception)); 0409 0410 observer.mUpdated.clear(); 0411 QVERIFY(cal->setNotebook(event, notebook2)); 0412 QCOMPARE(cal->notebook(event), notebook2); 0413 QCOMPARE(cal->notebook(exception), notebook2); 0414 QVERIFY(observer.hasIncidenceChanged(event)); 0415 QVERIFY(observer.hasIncidenceChanged(exception)); 0416 } 0417 0418 void MemoryCalendarTest::testRawEvents() 0419 { 0420 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0421 0422 Event::Ptr event = Event::Ptr(new Event()); 0423 // This event span in 20201011T2330Z - 20201012T2330Z 0424 event->setDtStart(QDateTime(QDate(2020, 10, 12), QTime(1, 30), QTimeZone("Europe/Paris"))); 0425 event->setDtEnd(QDateTime(QDate(2020, 10, 13), QTime(1, 30), QTimeZone("Europe/Paris"))); 0426 0427 QVERIFY(cal->addEvent(event)); 0428 0429 // Not full-event inclusive by default, UTC timezone. 0430 QCOMPARE(cal->rawEvents(QDate(2020, 10, 1), QDate(2020, 10, 10)).count(), 0); 0431 QCOMPARE(cal->rawEvents(QDate(2020, 10, 11), QDate(2020, 10, 11)).count(), 1); 0432 QCOMPARE(cal->rawEvents(QDate(2020, 10, 12), QDate(2020, 10, 12)).count(), 1); 0433 QCOMPARE(cal->rawEvents(QDate(2020, 10, 13), QDate(2020, 10, 31)).count(), 0); 0434 QCOMPARE(cal->rawEvents(QDate(), QDate(2020, 10, 10)).count(), 0); 0435 QCOMPARE(cal->rawEvents(QDate(), QDate(2020, 10, 11)).count(), 1); 0436 QCOMPARE(cal->rawEvents(QDate(2020, 10, 13), QDate()).count(), 0); 0437 QCOMPARE(cal->rawEvents(QDate(2020, 10, 12), QDate()).count(), 1); 0438 0439 // Changing the time zone we are considering the dates in. 0440 QCOMPARE(cal->rawEvents(QDate(2020, 10, 1), QDate(2020, 10, 11), QTimeZone("Europe/Paris")).count(), 0); 0441 QCOMPARE(cal->rawEvents(QDate(2020, 10, 12), QDate(2020, 10, 12), QTimeZone("Europe/Paris")).count(), 1); 0442 QCOMPARE(cal->rawEvents(QDate(2020, 10, 13), QDate(2020, 10, 13), QTimeZone("Europe/Paris")).count(), 1); 0443 QCOMPARE(cal->rawEvents(QDate(2020, 10, 14), QDate(2020, 10, 31), QTimeZone("Europe/Paris")).count(), 0); 0444 QCOMPARE(cal->rawEvents(QDate(), QDate(2020, 10, 11), QTimeZone("Europe/Paris")).count(), 0); 0445 QCOMPARE(cal->rawEvents(QDate(), QDate(2020, 10, 12), QTimeZone("Europe/Paris")).count(), 1); 0446 QCOMPARE(cal->rawEvents(QDate(2020, 10, 14), QDate(), QTimeZone("Europe/Paris")).count(), 0); 0447 QCOMPARE(cal->rawEvents(QDate(2020, 10, 13), QDate(), QTimeZone("Europe/Paris")).count(), 1); 0448 0449 // Full event must be in the span. 0450 QCOMPARE(cal->rawEvents(QDate(2020, 10, 1), QDate(2020, 10, 10), QTimeZone(), true).count(), 0); 0451 QCOMPARE(cal->rawEvents(QDate(2020, 10, 11), QDate(2020, 10, 11), QTimeZone(), true).count(), 0); 0452 QCOMPARE(cal->rawEvents(QDate(2020, 10, 12), QDate(2020, 10, 12), QTimeZone(), true).count(), 0); 0453 QCOMPARE(cal->rawEvents(QDate(2020, 10, 11), QDate(2020, 10, 12), QTimeZone(), true).count(), 1); 0454 QCOMPARE(cal->rawEvents(QDate(2020, 10, 13), QDate(2020, 10, 31), QTimeZone(), true).count(), 0); 0455 QCOMPARE(cal->rawEvents(QDate(), QDate(2020, 10, 10), QTimeZone(), true).count(), 0); 0456 QCOMPARE(cal->rawEvents(QDate(), QDate(2020, 10, 11), QTimeZone(), true).count(), 0); 0457 QCOMPARE(cal->rawEvents(QDate(), QDate(2020, 10, 12), QTimeZone(), true).count(), 1); 0458 QCOMPARE(cal->rawEvents(QDate(2020, 10, 13), QDate(), QTimeZone(), true).count(), 0); 0459 QCOMPARE(cal->rawEvents(QDate(2020, 10, 12), QDate(), QTimeZone(), true).count(), 0); 0460 QCOMPARE(cal->rawEvents(QDate(2020, 10, 11), QDate(), QTimeZone(), true).count(), 1); 0461 0462 cal->close(); 0463 } 0464 0465 void MemoryCalendarTest::testDeleteIncidence() 0466 { 0467 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0468 0469 Event::Ptr event = Event::Ptr(new Event()); 0470 event->setDtStart(QDateTime(QDate(2021, 1, 4), QTime(10, 13), QTimeZone("Europe/Paris"))); 0471 0472 QVERIFY(cal->addEvent(event)); 0473 QVERIFY(cal->instance(event->instanceIdentifier())); 0474 0475 QVERIFY(cal->deleteIncidence(event)); 0476 QVERIFY(cal->instance(event->instanceIdentifier()).isNull()); 0477 0478 event->recurrence()->setDaily(1); 0479 event->recurrence()->setDuration(3); 0480 QVERIFY(cal->addEvent(event)); 0481 QVERIFY(cal->instance(event->instanceIdentifier())); 0482 0483 Event::Ptr exception = Event::Ptr(event->clone()); 0484 exception->recurrence()->clear(); 0485 exception->setRecurrenceId(event->dtStart().addDays(1)); 0486 exception->setDtStart(event->dtStart().addDays(1).addSecs(3600)); 0487 QVERIFY(cal->addEvent(exception)); 0488 QVERIFY(cal->instance(exception->instanceIdentifier())); 0489 0490 Event::Ptr exception2 = Event::Ptr(event->clone()); 0491 exception2->recurrence()->clear(); 0492 exception2->setRecurrenceId(event->dtStart().addDays(2)); 0493 exception2->setDtStart(event->dtStart().addDays(2).addSecs(-3600)); 0494 QVERIFY(cal->addEvent(exception2)); 0495 QVERIFY(cal->instance(exception2->instanceIdentifier())); 0496 0497 QVERIFY(cal->deleteIncidence(exception)); 0498 QVERIFY(cal->incidence(event->uid(), exception->recurrenceId()).isNull()); 0499 QVERIFY(!cal->deleteIncidence(exception)); 0500 QVERIFY(cal->incidence(event->uid(), exception2->recurrenceId())); 0501 QVERIFY(cal->incidence(event->uid())); 0502 0503 QVERIFY(cal->deleteIncidence(event)); 0504 QVERIFY(cal->incidence(event->uid(), exception2->recurrenceId()).isNull()); 0505 QVERIFY(cal->incidence(event->uid()).isNull()); 0506 } 0507 0508 void MemoryCalendarTest::testUpdateIncidence() 0509 { 0510 MemoryCalendar::Ptr cal(new MemoryCalendar(QTimeZone::utc())); 0511 0512 const QDateTime dt(QDate(2021, 02, 25), QTime(14, 0), Qt::UTC); 0513 Event::Ptr event(new Event()); 0514 event->setCreated(dt); 0515 event->setLastModified(dt); 0516 event->setDtStart(dt); 0517 event->setDtEnd(dt.addSecs(3600)); 0518 0519 // Adding event to cal, makes cal an observer of event. 0520 QVERIFY(cal->addIncidence(event)); 0521 QCOMPARE(cal->rawEventsForDate(dt.date(), dt.timeZone()).count(), 1); 0522 0523 QVERIFY(cal->updateLastModifiedOnChange()); 0524 0525 const QDateTime now = QDateTime::currentDateTimeUtc(); 0526 0527 // Any single modification is updating the lastModified field. 0528 event->setSummary(QString::fromLatin1("test")); 0529 QVERIFY(event->lastModified().secsTo(now) < 5); 0530 0531 // Reset lastModified field. 0532 event->setLastModified(dt); 0533 QCOMPARE(event->lastModified(), dt); 0534 0535 // Any modification within a startUpdates()/endUpdates() should not touch 0536 // lastModified field, before the changes are completed. 0537 event->startUpdates(); 0538 QVERIFY(cal->rawEventsForDate(dt.date(), dt.timeZone()).isEmpty()); 0539 event->setSummary(QString::fromLatin1("test again")); 0540 QCOMPARE(event->lastModified(), dt); 0541 event->endUpdates(); 0542 QVERIFY(event->lastModified().secsTo(now) < 5); 0543 QCOMPARE(cal->rawEventsForDate(dt.date(), dt.timeZone()).count(), 1); 0544 0545 // Reset lastModified field. 0546 event->setLastModified(dt); 0547 QCOMPARE(event->lastModified(), dt); 0548 0549 // Don't update lastModified on change. 0550 cal->setUpdateLastModifiedOnChange(false); 0551 event->setSummary(QString::fromLatin1("last test")); 0552 QCOMPARE(event->lastModified(), dt); 0553 } 0554 0555 #include "moc_testmemorycalendar.cpp"