File indexing completed on 2024-04-28 15:18:54

0001 /*
0002   This file is part of the kcalcore library.
0003 
0004   SPDX-FileCopyrightText: 2015 Sandro Knauß <knauss@kolabsys.com>
0005 
0006   SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 #include "testincidence.h"
0009 #include "event.h"
0010 #include "incidence.h"
0011 #include <cmath>
0012 #include <QTest>
0013 
0014 QTEST_MAIN(IncidenceTest)
0015 
0016 Q_DECLARE_METATYPE(KCalendarCore::Incidence::DateTimeRole)
0017 
0018 using namespace KCalendarCore;
0019 
0020 const auto TEST_TZ = "Europe/Paris";
0021 
0022 void IncidenceTest::initTestCase()
0023 {
0024     qputenv("TZ", TEST_TZ);
0025 }
0026 
0027 void IncidenceTest::testDtStartChange()
0028 {
0029     QDate dt = QDate::currentDate();
0030     QTime t = QTime::currentTime();
0031     Event inc;
0032     inc.setDtStart(QDateTime(dt, {}));
0033     inc.setAllDay(true);
0034     inc.recurrence()->setDaily(1);
0035     inc.resetDirtyFields();
0036 
0037     inc.setDtStart(QDateTime(dt, {}));
0038     QVERIFY(inc.dirtyFields().empty());
0039 
0040     inc.setDtStart(QDateTime(dt, t));
0041     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldDtStart << IncidenceBase::FieldRecurrence);
0042     QCOMPARE(inc.recurrence()->startDateTime().time(), t);
0043     inc.resetDirtyFields();
0044 
0045     inc.setDtStart(QDateTime(dt, {}).addDays(1));
0046     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldDtStart << IncidenceBase::FieldRecurrence);
0047     QCOMPARE(inc.recurrence()->startDateTime(), QDateTime(dt, {}).addDays(1));
0048     inc.resetDirtyFields();
0049 
0050     inc.setDtStart(QDateTime());
0051     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldDtStart << IncidenceBase::FieldRecurrence);
0052     QCOMPARE(inc.recurrence()->startDateTime(), QDateTime());
0053     inc.resetDirtyFields();
0054 
0055     inc.setDtStart(QDateTime(dt, {}).addDays(1));
0056     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldDtStart << IncidenceBase::FieldRecurrence);
0057     QCOMPARE(inc.recurrence()->startDateTime(), QDateTime(dt, {}).addDays(1));
0058 }
0059 
0060 void IncidenceTest::testDtStartEqual()
0061 {
0062     QDateTime dt {QDate::currentDate(), QTime::currentTime(), QTimeZone(TEST_TZ)};
0063     QVERIFY(dt.timeSpec() == Qt::TimeZone);
0064 
0065     Event i1;
0066     i1.setDtStart(dt);
0067     auto i2 = i1.clone();
0068     QVERIFY(i1 == *i2);
0069 
0070     // Create a "floating" datetime, which represents the same instant in real time
0071     // because we're still running in the test's time zone.
0072     dt.setTimeSpec(Qt::LocalTime);
0073 
0074     i1.setDtStart(dt);
0075     QVERIFY(i1 != *i2);
0076     i2->setDtStart(dt);
0077     QVERIFY(i1 == *i2);
0078 }
0079 
0080 void IncidenceTest::testSummaryChange()
0081 {
0082     Event inc;
0083     inc.setSummary(QStringLiteral("bla"), false);
0084     inc.resetDirtyFields();
0085 
0086     inc.setSummary(QStringLiteral("bla"), false);
0087     QVERIFY(inc.dirtyFields().empty());
0088 
0089     inc.setSummary(QStringLiteral("bla2"), false);
0090     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldSummary);
0091     inc.resetDirtyFields();
0092 
0093     inc.setSummary(QStringLiteral("bla2"), true);
0094     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldSummary);
0095 }
0096 
0097 void IncidenceTest::testLocationChange()
0098 {
0099     Event inc;
0100     inc.setLocation(QStringLiteral("here"), false);
0101     inc.resetDirtyFields();
0102 
0103     inc.setLocation(QStringLiteral("here"), false);
0104     QVERIFY(inc.dirtyFields().empty());
0105 
0106     inc.setLocation(QStringLiteral("there"), false);
0107     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldLocation);
0108     inc.resetDirtyFields();
0109 
0110     inc.setLocation(QStringLiteral("there"), true);
0111     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldLocation);
0112 }
0113 
0114 void IncidenceTest::testGeo()
0115 {
0116     Event inc;
0117 
0118     // Default state:  no GEO.
0119     QCOMPARE(inc.hasGeo(), false);
0120     QCOMPARE(inc.geoLatitude(), INVALID_LATLON);
0121     QCOMPARE(inc.geoLongitude(), INVALID_LATLON);
0122     QVERIFY(inc.dirtyFields().empty());
0123 
0124     // Set GEO, thoroughly.
0125     inc.setGeoLatitude(90.0);
0126     inc.setGeoLongitude(180.0);
0127 #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 89)
0128     inc.setHasGeo(true);
0129 #endif
0130     QCOMPARE(inc.hasGeo(), true);
0131     QCOMPARE(inc.geoLatitude(), 90.0);
0132     QCOMPARE(inc.geoLongitude(), 180.0);
0133     QCOMPARE(inc.dirtyFields(), (QSet{IncidenceBase::FieldGeoLatitude, IncidenceBase::FieldGeoLongitude}));
0134     inc.resetDirtyFields();
0135     inc.setGeoLatitude(-90.0);
0136     inc.setGeoLongitude(-180.0);
0137     QCOMPARE(inc.hasGeo(), true);
0138     QCOMPARE(inc.geoLatitude(), -90.0);
0139     QCOMPARE(inc.geoLongitude(), -180.0);
0140     QCOMPARE(inc.dirtyFields(), (QSet{IncidenceBase::FieldGeoLatitude, IncidenceBase::FieldGeoLongitude}));
0141 
0142     // Clear GEO, thoroughly.
0143     inc.resetDirtyFields();
0144     inc.setGeoLatitude(INVALID_LATLON);
0145     inc.setGeoLongitude(INVALID_LATLON);
0146 #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 89)
0147     inc.setHasGeo(false);
0148 #endif
0149     QCOMPARE(inc.hasGeo(), false);
0150     QCOMPARE(inc.geoLatitude(), INVALID_LATLON);
0151     QCOMPARE(inc.geoLongitude(), INVALID_LATLON);
0152     QCOMPARE(inc.dirtyFields(), (QSet{IncidenceBase::FieldGeoLatitude, IncidenceBase::FieldGeoLongitude}));
0153 
0154     // Error handling.
0155 #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 89)
0156     inc.setHasGeo(true);
0157 #endif
0158     inc.setGeoLatitude(90.0);
0159     inc.setGeoLongitude(180.0);
0160 #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 89)
0161     inc.setHasGeo(false);
0162     QCOMPARE(inc.geoLatitude(), INVALID_LATLON);
0163     QCOMPARE(inc.geoLongitude(), INVALID_LATLON);
0164     inc.setHasGeo(true);
0165     inc.setGeoLatitude(90.0);
0166     inc.setGeoLongitude(180.0);
0167 #endif
0168     inc.setGeoLatitude(INVALID_LATLON);
0169     QCOMPARE(inc.hasGeo(), false);
0170     QCOMPARE(inc.geoLatitude(), INVALID_LATLON);
0171     QCOMPARE(inc.geoLongitude(), INVALID_LATLON);
0172 #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 89)
0173     inc.setHasGeo(true);
0174 #endif
0175     inc.setGeoLatitude(90.0);
0176     inc.setGeoLongitude(180.0);
0177     inc.setGeoLongitude(INVALID_LATLON);
0178     QCOMPARE(inc.hasGeo(), false);
0179     QCOMPARE(inc.geoLatitude(), INVALID_LATLON);
0180     QCOMPARE(inc.geoLongitude(), INVALID_LATLON);
0181 #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 89)
0182     inc.setHasGeo(true);
0183 #endif
0184     inc.setGeoLatitude(90.0);
0185     inc.setGeoLongitude(180.0);
0186     inc.setGeoLatitude(NAN);
0187     QCOMPARE(inc.hasGeo(), false);
0188     QCOMPARE(inc.geoLatitude(), INVALID_LATLON);
0189     QCOMPARE(inc.geoLongitude(), INVALID_LATLON);
0190 #if KCALENDARCORE_BUILD_DEPRECATED_SINCE(5, 89)
0191     inc.setHasGeo(true);
0192 #endif
0193     inc.setGeoLatitude(90.0);
0194     inc.setGeoLongitude(180.0);
0195     inc.setGeoLongitude(NAN);
0196     QCOMPARE(inc.hasGeo(), false);
0197     QCOMPARE(inc.geoLatitude(), INVALID_LATLON);
0198     QCOMPARE(inc.geoLongitude(), INVALID_LATLON);
0199 }
0200 
0201 void IncidenceTest::testRecurrenceTypeChange()
0202 {
0203     QDate dt = QDate::currentDate();
0204     Event inc;
0205     inc.setDtStart(QDateTime(dt, {}));
0206     KCalendarCore::Recurrence *r = inc.recurrence();
0207     r->setDaily(1);
0208     inc.resetDirtyFields();
0209 
0210     r->setDaily(1);
0211     QVERIFY(inc.dirtyFields().empty());
0212 
0213     r->setDaily(2);
0214     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldRecurrence);
0215     inc.resetDirtyFields();
0216 
0217     r->setMonthly(2);
0218     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldRecurrence);
0219 }
0220 
0221 void IncidenceTest::testRecurrenceEndTimeChange()
0222 {
0223     QDate dt = QDate::currentDate();
0224     Event inc;
0225     inc.setDtStart(QDateTime(dt, {}));
0226     KCalendarCore::Recurrence *r = inc.recurrence();
0227     r->setDaily(1);
0228     r->setEndDateTime(QDateTime(dt, {}).addDays(1));
0229     inc.resetDirtyFields();
0230 
0231     r->setEndDateTime(QDateTime(dt, {}).addDays(1));
0232     QVERIFY(inc.dirtyFields().empty());
0233 
0234     r->setEndDateTime(QDateTime(dt, {}).addDays(2));
0235     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldRecurrence);
0236 }
0237 
0238 void IncidenceTest::testRecurrenceEndTimeDurationChange()
0239 {
0240     QDate dt = QDate::currentDate();
0241     Event inc;
0242     inc.setDtStart(QDateTime(dt, {}));
0243     KCalendarCore::Recurrence *r = inc.recurrence();
0244     r->setDaily(1);
0245     inc.resetDirtyFields();
0246     QCOMPARE(r->duration(), -1);
0247     QVERIFY(!r->endDateTime().isValid());
0248 
0249     r->setDuration(5);
0250     QVERIFY(r->endDateTime().isValid());
0251     inc.resetDirtyFields();
0252 
0253     // duration is set and set enddate to inValid
0254     r->setDuration(5);
0255     r->setEndDateTime(QDateTime());
0256     QVERIFY(inc.dirtyFields().empty());
0257 
0258     // now set valid enddate -> set duration to 0 by sideeffect
0259     r->setEndDateTime(QDateTime(dt, {}).addDays(1));
0260     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldRecurrence);
0261     QCOMPARE(r->duration(), 0);
0262     QCOMPARE(r->endDateTime(), QDateTime(dt, {}).addDays(1));
0263 
0264     // with valid endDate, now setDuration and aftward set invalid endDate
0265     r->setEndDateTime(QDateTime(dt, {}).addDays(1));
0266     r->setDuration(5);
0267     inc.resetDirtyFields();
0268 
0269     r->setEndDateTime(QDateTime());
0270     QVERIFY(inc.dirtyFields().empty());
0271     QCOMPARE(r->endDate(), dt.addDays(4));
0272     QCOMPARE(r->duration(), 5);
0273 }
0274 
0275 void IncidenceTest::testRecurrenceDurationChange()
0276 {
0277     QDate dt = QDate::currentDate();
0278     Event inc;
0279     inc.setDtStart(QDateTime(dt, {}));
0280     KCalendarCore::Recurrence *r = inc.recurrence();
0281     r->setDuration(1);
0282     inc.resetDirtyFields();
0283 
0284     r->setDuration(1);
0285     QVERIFY(inc.dirtyFields().empty());
0286 
0287     r->setDuration(2);
0288     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldRecurrence);
0289 }
0290 
0291 void IncidenceTest::testRecurrenceExDatesChange()
0292 {
0293     QDate dt = QDate::currentDate();
0294     Event inc;
0295     inc.setDtStart(QDateTime(dt, {}));
0296     KCalendarCore::Recurrence *r = inc.recurrence();
0297     r->setExDates(DateList() << dt.addDays(1) << dt.addDays(2));
0298     inc.resetDirtyFields();
0299 
0300     r->setExDates(DateList() << dt.addDays(2) << dt.addDays(1));
0301     QVERIFY(inc.dirtyFields().empty());
0302 
0303     r->setExDates(DateList() << dt.addDays(1));
0304     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldRecurrence);
0305 }
0306 
0307 void IncidenceTest::testRecurrenceMonthlyDate()
0308 {
0309     QDate dt = QDate::currentDate();
0310     Event inc;
0311     inc.setDtStart(QDateTime(dt, {}));
0312     KCalendarCore::Recurrence *r = inc.recurrence();
0313     r->setMonthly(1);
0314     r->setMonthlyDate(QList<int>() << 1 << 2 << 3);
0315     inc.resetDirtyFields();
0316 
0317     r->setMonthlyDate(QList<int>() << 3 << 1 << 2);
0318     QVERIFY(inc.dirtyFields().empty());
0319 
0320     r->setMonthlyDate(QList<int>() << 3 << 1);
0321     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldRecurrence);
0322 }
0323 
0324 void IncidenceTest::testRecurrenceMonthlyPos()
0325 {
0326     QDate dt = QDate::currentDate();
0327     RecurrenceRule::WDayPos pos1(1, 2);
0328     RecurrenceRule::WDayPos pos2(3, 4);
0329     RecurrenceRule::WDayPos pos3(1, 2);
0330     Event inc;
0331     inc.setDtStart(QDateTime(dt, {}));
0332     KCalendarCore::Recurrence *r = inc.recurrence();
0333     r->setYearly(1);
0334     r->setMonthlyPos(QList<RecurrenceRule::WDayPos>() << pos1 << pos2);
0335     inc.resetDirtyFields();
0336 
0337     // TODO: test sorting
0338     r->setMonthlyPos(QList<RecurrenceRule::WDayPos>() << pos1 << pos2);
0339     QVERIFY(inc.dirtyFields().empty());
0340 
0341     r->setMonthlyPos(QList<RecurrenceRule::WDayPos>() << pos3);
0342     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldRecurrence);
0343 }
0344 
0345 void IncidenceTest::testRecurrenceYearlyDay()
0346 {
0347     QDate dt = QDate::currentDate();
0348     Event inc;
0349     inc.setDtStart(QDateTime(dt, {}));
0350     KCalendarCore::Recurrence *r = inc.recurrence();
0351     r->setYearly(1);
0352     r->setYearlyDay(QList<int>() << 1 << 2 << 3);
0353     inc.resetDirtyFields();
0354 
0355     r->setYearlyDay(QList<int>() << 3 << 1 << 2);
0356     QVERIFY(inc.dirtyFields().empty());
0357 
0358     r->setYearlyDay(QList<int>() << 3 << 1);
0359     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldRecurrence);
0360 }
0361 
0362 void IncidenceTest::testRecurrenceYearlyMonth()
0363 {
0364     QDate dt = QDate::currentDate();
0365     Event inc;
0366     inc.setDtStart(QDateTime(dt, {}));
0367     KCalendarCore::Recurrence *r = inc.recurrence();
0368     r->setYearly(1);
0369     r->setYearlyMonth(QList<int>() << 1 << 2 << 3);
0370     inc.resetDirtyFields();
0371 
0372     r->setYearlyMonth(QList<int>() << 3 << 1 << 2);
0373     QVERIFY(inc.dirtyFields().empty());
0374 
0375     r->setYearlyMonth(QList<int>() << 3 << 1);
0376     QCOMPARE(inc.dirtyFields(), QSet<IncidenceBase::Field>() << IncidenceBase::FieldRecurrence);
0377 }
0378 
0379 #include "moc_testincidence.cpp"