File indexing completed on 2024-04-21 03:52:41

0001 /*
0002  * SPDX-FileCopyrightText: 2012 Christian Mollekopf <mollekopf@kolabsys.com>
0003  *
0004  * SPDX-License-Identifier: LGPL-3.0-or-later
0005  */
0006 
0007 #include "testoccurrenceiterator.h"
0008 #include "calfilter.h"
0009 #include "memorycalendar.h"
0010 #include "occurrenceiterator.h"
0011 
0012 #include <QDebug>
0013 #include <QTest>
0014 #include <QTimeZone>
0015 
0016 QTEST_MAIN(TestOccurrenceIterator)
0017 
0018 void TestOccurrenceIterator::testIterationWithExceptions()
0019 {
0020     KCalendarCore::MemoryCalendar calendar(QTimeZone::utc());
0021 
0022     QDateTime start(QDate(2013, 03, 10), QTime(10, 0, 0), QTimeZone::UTC);
0023     QDateTime end(QDate(2013, 03, 10), QTime(11, 0, 0), QTimeZone::UTC);
0024 
0025     QDateTime recurrenceId(QDate(2013, 03, 11), QTime(10, 0, 0), QTimeZone::UTC);
0026     QDateTime exceptionStart(QDate(2013, 03, 11), QTime(12, 0, 0), QTimeZone::UTC);
0027     QDateTime exceptionEnd(QDate(2013, 03, 11), QTime(13, 0, 0), QTimeZone::UTC);
0028 
0029     QDateTime actualEnd(QDate(2013, 03, 12), QTime(11, 0, 0), QTimeZone::UTC);
0030 
0031     KCalendarCore::Event::Ptr event1(new KCalendarCore::Event());
0032     event1->setUid(QStringLiteral("event1"));
0033     event1->setSummary(QStringLiteral("event1"));
0034     event1->setDtStart(start);
0035     event1->setDtEnd(end);
0036     event1->recurrence()->setDaily(1);
0037     calendar.addEvent(event1);
0038 
0039     KCalendarCore::Event::Ptr exception(new KCalendarCore::Event());
0040     exception->setUid(event1->uid());
0041     exception->setSummary(QStringLiteral("exception"));
0042     exception->setRecurrenceId(recurrenceId);
0043     exception->setDtStart(exceptionStart);
0044     exception->setDtEnd(exceptionEnd);
0045     calendar.addEvent(exception);
0046 
0047     int occurrence = 0;
0048     KCalendarCore::OccurrenceIterator rIt(calendar, start, actualEnd);
0049     while (rIt.hasNext()) {
0050         rIt.next();
0051         occurrence++;
0052         if (occurrence == 1) {
0053             QCOMPARE(rIt.occurrenceStartDate(), start);
0054             QCOMPARE(rIt.incidence()->summary(), event1->summary());
0055         }
0056         if (occurrence == 2) {
0057             QCOMPARE(rIt.occurrenceStartDate(), exceptionStart);
0058             QCOMPARE(rIt.incidence()->summary(), exception->summary());
0059         }
0060         if (occurrence == 3) {
0061             QCOMPARE(rIt.occurrenceStartDate(), start.addDays(2));
0062             QCOMPARE(rIt.incidence()->summary(), event1->summary());
0063         }
0064     }
0065     QCOMPARE(occurrence, 3);
0066 }
0067 
0068 void TestOccurrenceIterator::testEventsAndTodos()
0069 {
0070     KCalendarCore::MemoryCalendar calendar(QTimeZone::utc());
0071 
0072     QDateTime start(QDate(2013, 03, 10), QTime(10, 0, 0), QTimeZone::UTC);
0073     QDateTime actualEnd(QDate(2013, 03, 13), QTime(11, 0, 0), QTimeZone::UTC);
0074 
0075     KCalendarCore::Event::Ptr event(new KCalendarCore::Event());
0076     event->setUid(QStringLiteral("event"));
0077     event->setDtStart(start);
0078     event->recurrence()->setDaily(1);
0079     event->recurrence()->setDuration(2);
0080     calendar.addEvent(event);
0081 
0082     KCalendarCore::Todo::Ptr todo(new KCalendarCore::Todo());
0083     todo->setUid(QStringLiteral("todo"));
0084     todo->setDtStart(start);
0085     todo->recurrence()->setDaily(1);
0086     todo->recurrence()->setDuration(2);
0087     calendar.addTodo(todo);
0088 
0089     KCalendarCore::OccurrenceIterator rIt(calendar, start, actualEnd);
0090     QList<QDateTime> expectedTodoOccurrences;
0091     expectedTodoOccurrences << start << start.addDays(1);
0092     QList<QDateTime> expectedEventOccurrences;
0093     expectedEventOccurrences << start << start.addDays(1);
0094     while (rIt.hasNext()) {
0095         rIt.next();
0096         qDebug() << rIt.occurrenceStartDate().toString();
0097         if (rIt.incidence()->type() == KCalendarCore::Incidence::TypeTodo) {
0098             QCOMPARE(expectedTodoOccurrences.removeAll(rIt.occurrenceStartDate()), 1);
0099         } else {
0100             QCOMPARE(expectedEventOccurrences.removeAll(rIt.occurrenceStartDate()), 1);
0101         }
0102     }
0103     QCOMPARE(expectedTodoOccurrences.size(), 0);
0104     QCOMPARE(expectedEventOccurrences.size(), 0);
0105 }
0106 
0107 void TestOccurrenceIterator::testFilterCompletedTodos()
0108 {
0109     KCalendarCore::MemoryCalendar calendar(QTimeZone::utc());
0110     calendar.filter()->setCriteria(KCalendarCore::CalFilter::HideCompletedTodos);
0111 
0112     QDateTime start(QDate(2013, 03, 10), QTime(10, 0, 0), QTimeZone::UTC);
0113     QDateTime actualEnd(QDate(2013, 03, 13), QTime(11, 0, 0), QTimeZone::UTC);
0114 
0115     KCalendarCore::Todo::Ptr todo(new KCalendarCore::Todo());
0116     todo->setUid(QStringLiteral("todo"));
0117     todo->setDtDue(start);
0118     todo->setDtStart(start);
0119     todo->recurrence()->setDaily(1);
0120     todo->recurrence()->setDuration(2);
0121     // Yes, recurring todos are weird... setting this says that all occurrences
0122     // until this one have been completed, and thus should be skipped.
0123     // that's what kontact did, so it's what we test now.
0124     todo->setDtRecurrence(start.addDays(2));
0125     calendar.addTodo(todo);
0126 
0127     KCalendarCore::OccurrenceIterator rIt(calendar, start, actualEnd);
0128     QVERIFY(!rIt.hasNext());
0129 }
0130 
0131 void TestOccurrenceIterator::testAllDayEvents()
0132 {
0133     KCalendarCore::MemoryCalendar calendar(QTimeZone::utc());
0134 
0135     QDateTime start(QDate(2013, 03, 10), QTime(), QTimeZone::UTC);
0136     QDateTime actualEnd(QDate(2013, 03, 13), QTime(11, 0, 0), QTimeZone::UTC);
0137 
0138     KCalendarCore::Event::Ptr event(new KCalendarCore::Event());
0139     event->setUid(QStringLiteral("event"));
0140     event->setDtStart(start);
0141     event->setAllDay(true);
0142     event->recurrence()->setDaily(1);
0143     event->recurrence()->setDuration(2);
0144     calendar.addEvent(event);
0145 
0146     KCalendarCore::OccurrenceIterator rIt(calendar, start, actualEnd);
0147     QList<QDateTime> expectedEventOccurrences;
0148     expectedEventOccurrences << start << start.addDays(1);
0149     while (rIt.hasNext()) {
0150         rIt.next();
0151         qDebug() << rIt.occurrenceStartDate().toString();
0152         QCOMPARE(expectedEventOccurrences.removeAll(rIt.occurrenceStartDate()), 1);
0153     }
0154     QCOMPARE(expectedEventOccurrences.size(), 0);
0155 }
0156 
0157 void TestOccurrenceIterator::testWithExceptionThisAndFuture()
0158 {
0159     KCalendarCore::MemoryCalendar calendar(QTimeZone::utc());
0160 
0161     QDateTime start(QDate(2013, 03, 10), QTime(10, 0, 0), QTimeZone::UTC);
0162     QDateTime end(QDate(2013, 03, 10), QTime(11, 0, 0), QTimeZone::UTC);
0163 
0164     QDateTime recurrenceId1(QDate(2013, 03, 11), QTime(10, 0, 0), QTimeZone::UTC);
0165     QDateTime exceptionStart1(QDate(2013, 03, 11), QTime(12, 0, 0), QTimeZone::UTC);
0166     QDateTime exceptionEnd1(QDate(2013, 03, 11), QTime(13, 0, 0), QTimeZone::UTC);
0167 
0168     QDateTime recurrenceId2(QDate(2013, 03, 13), QTime(10, 0, 0), QTimeZone::UTC);
0169     QDateTime exceptionStart2(QDate(2013, 03, 13), QTime(14, 0, 0), QTimeZone::UTC);
0170     QDateTime exceptionEnd2(QDate(2013, 03, 13), QTime(15, 0, 0), QTimeZone::UTC);
0171 
0172     QDateTime actualEnd(QDate(2013, 03, 14), QTime(11, 0, 0), QTimeZone::UTC);
0173 
0174     KCalendarCore::Event::Ptr event1(new KCalendarCore::Event());
0175     event1->setUid(QStringLiteral("event1"));
0176     event1->setSummary(QStringLiteral("event1"));
0177     event1->setDtStart(start);
0178     event1->setDtEnd(end);
0179     event1->recurrence()->setDaily(1);
0180     calendar.addEvent(event1);
0181 
0182     KCalendarCore::Event::Ptr exception1(new KCalendarCore::Event());
0183     exception1->setUid(event1->uid());
0184     exception1->setSummary(QStringLiteral("exception1"));
0185     exception1->setRecurrenceId(recurrenceId1);
0186     exception1->setThisAndFuture(true);
0187     exception1->setDtStart(exceptionStart1);
0188     exception1->setDtEnd(exceptionEnd1);
0189     calendar.addEvent(exception1);
0190 
0191     KCalendarCore::Event::Ptr exception2(new KCalendarCore::Event());
0192     exception2->setUid(event1->uid());
0193     exception2->setSummary(QStringLiteral("exception2"));
0194     exception2->setRecurrenceId(recurrenceId2);
0195     exception2->setDtStart(exceptionStart2);
0196     exception2->setDtEnd(exceptionEnd2);
0197     calendar.addEvent(exception2);
0198 
0199     int occurrence = 0;
0200     KCalendarCore::OccurrenceIterator rIt(calendar, start, actualEnd);
0201     while (rIt.hasNext()) {
0202         rIt.next();
0203         occurrence++;
0204         QCOMPARE(rIt.recurrenceId(), start.addDays(occurrence - 1));
0205         if (occurrence == 1) {
0206             QCOMPARE(rIt.occurrenceStartDate(), start);
0207             QCOMPARE(rIt.incidence()->summary(), event1->summary());
0208         }
0209         if (occurrence == 2) {
0210             QCOMPARE(rIt.occurrenceStartDate(), exceptionStart1);
0211             QCOMPARE(rIt.incidence()->summary(), exception1->summary());
0212         }
0213         if (occurrence == 3) {
0214             QCOMPARE(rIt.occurrenceStartDate(), exceptionStart1.addDays(1));
0215             QCOMPARE(rIt.incidence()->summary(), exception1->summary());
0216         }
0217         if (occurrence == 4) {
0218             QCOMPARE(rIt.occurrenceStartDate(), exceptionStart2);
0219             QCOMPARE(rIt.incidence()->summary(), exception2->summary());
0220         }
0221         if (occurrence == 5) {
0222             QCOMPARE(rIt.occurrenceStartDate(), exceptionStart1.addDays(3));
0223             QCOMPARE(rIt.incidence()->summary(), exception1->summary());
0224         }
0225     }
0226     QCOMPARE(occurrence, 5);
0227 }
0228 
0229 void TestOccurrenceIterator::testSubDailyRecurrences()
0230 {
0231     KCalendarCore::MemoryCalendar calendar(QTimeZone::utc());
0232 
0233     QDateTime start(QDate(2013, 03, 10), QTime(10, 0, 0), QTimeZone::UTC);
0234     QDateTime actualEnd(QDate(2013, 03, 10), QTime(13, 0, 0), QTimeZone::UTC);
0235 
0236     KCalendarCore::Event::Ptr event(new KCalendarCore::Event());
0237     event->setUid(QStringLiteral("event"));
0238     event->setDtStart(start);
0239     event->recurrence()->setHourly(1);
0240     event->recurrence()->setDuration(2);
0241     calendar.addEvent(event);
0242 
0243     KCalendarCore::OccurrenceIterator rIt(calendar, start, actualEnd);
0244     QList<QDateTime> expectedEventOccurrences;
0245     expectedEventOccurrences << start << start.addSecs(60 * 60);
0246     while (rIt.hasNext()) {
0247         rIt.next();
0248         qDebug() << rIt.occurrenceStartDate().toString();
0249         QCOMPARE(expectedEventOccurrences.removeAll(rIt.occurrenceStartDate()), 1);
0250     }
0251     QCOMPARE(expectedEventOccurrences.size(), 0);
0252 }
0253 
0254 void TestOccurrenceIterator::testJournals()
0255 {
0256     KCalendarCore::MemoryCalendar calendar(QTimeZone::utc());
0257 
0258     const QDateTime today = QDateTime::currentDateTimeUtc();
0259     const QDateTime yesterday = today.addDays(-1);
0260     const QDateTime tomorrow = today.addDays(1);
0261 
0262     KCalendarCore::Journal::Ptr journal(new KCalendarCore::Journal());
0263     journal->setUid(QStringLiteral("journal"));
0264     journal->setDtStart(today);
0265     calendar.addJournal(journal);
0266 
0267     KCalendarCore::OccurrenceIterator rIt(calendar, yesterday, tomorrow);
0268     QVERIFY(rIt.hasNext());
0269     rIt.next();
0270     QCOMPARE(rIt.occurrenceStartDate(), today);
0271     QVERIFY(!rIt.hasNext());
0272 
0273     KCalendarCore::OccurrenceIterator rIt2(calendar, tomorrow, tomorrow.addDays(1));
0274     QVERIFY(!rIt2.hasNext());
0275 }
0276 
0277 void TestOccurrenceIterator::testEndDate()
0278 {
0279     const QDateTime start(QDate(2021, 8, 30), QTime(10, 0, 0));
0280     const QDateTime end(QDate(2021, 8, 30), QTime(11, 0, 0));
0281 
0282     const QDateTime start2(QDate(2021, 8, 30), QTime(15, 0, 0));
0283     const QDateTime end2(QDate(2021, 8, 30), QTime(18, 0, 0));
0284 
0285     KCalendarCore::MemoryCalendar calendar(QTimeZone::utc());
0286 
0287     KCalendarCore::Event::Ptr event(new KCalendarCore::Event);
0288     event->setUid(QStringLiteral("event"));
0289     event->setSummary(QStringLiteral("event"));
0290     event->setDtStart(start);
0291     event->setDtEnd(end);
0292     event->recurrence()->setDaily(1);
0293     event->recurrence()->addRDateTimePeriod(KCalendarCore::Period(start2, end2));
0294     calendar.addEvent(event);
0295 
0296     KCalendarCore::Journal::Ptr journal(new KCalendarCore::Journal);
0297     journal->setUid(QStringLiteral("journal"));
0298     journal->setDtStart(start);
0299     calendar.addJournal(journal);
0300 
0301     KCalendarCore::OccurrenceIterator rIt(calendar, start, start.addDays(1));
0302     // The base event.
0303     QVERIFY(rIt.hasNext());
0304     rIt.next();
0305     QCOMPARE(rIt.occurrenceStartDate(), start);
0306     QCOMPARE(rIt.occurrenceEndDate(), end);
0307     // The additional occurrence with a longer duration.
0308     QVERIFY(rIt.hasNext());
0309     rIt.next();
0310     QCOMPARE(rIt.occurrenceStartDate(), start2);
0311     QCOMPARE(rIt.occurrenceEndDate(), end2);
0312     // The recurring occurrence with the base duration.
0313     QVERIFY(rIt.hasNext());
0314     rIt.next();
0315     QCOMPARE(rIt.occurrenceStartDate(), start.addDays(1));
0316     QCOMPARE(rIt.occurrenceEndDate(), end.addDays(1));
0317     // The journal.
0318     QVERIFY(rIt.hasNext());
0319     rIt.next();
0320     QCOMPARE(rIt.occurrenceStartDate(), start);
0321     QVERIFY(!rIt.occurrenceEndDate().isValid());
0322     QVERIFY(!rIt.hasNext());
0323 }
0324 
0325 #include "moc_testoccurrenceiterator.cpp"