aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_calendarstore.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-24 17:50:47 +0200
committerDanilo M. <danix@danix.xyz>2026-09-24 17:50:47 +0200
commitff40d2a6dffdf234ade8bc4a5faa7624e58d5379 (patch)
treecf7b2469957db7d6d602cd4532263750eecdb9c4 /tests/test_calendarstore.cpp
parent7494ce76f1eefc2a9a2112d2f2ffec4709d90e08 (diff)
downloadqtmaildir-ff40d2a6dffdf234ade8bc4a5faa7624e58d5379.tar.gz
qtmaildir-ff40d2a6dffdf234ade8bc4a5faa7624e58d5379.zip
fix: drop orphaned overrides when a series stops, plus review minors
Diffstat (limited to 'tests/test_calendarstore.cpp')
-rw-r--r--tests/test_calendarstore.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/tests/test_calendarstore.cpp b/tests/test_calendarstore.cpp
index 524304e..8aa526e 100644
--- a/tests/test_calendarstore.cpp
+++ b/tests/test_calendarstore.cpp
@@ -152,10 +152,12 @@ private slots:
void aNewEventIsCompleteAndEmbedsItsZone();
void sameMeaningIgnoresFormatting();
void sameMeaningMatchesOverridesRegardlessOfOrder();
+ void sameMeaningTreatsExdatesAsASet();
void sameMeaningRejectsDifferentUids();
void editingOneOccurrenceWritesAnOverride();
void editingTheSameOccurrenceAgainReplacesItsOverride();
+ void stoppingASeriesDropsItsOverrides();
void deletingOneOccurrenceAddsAnExdateAndDropsItsOverride();
void deletingOneOccurrenceKeepsExistingExdates();
@@ -595,6 +597,25 @@ void TestCalendarStore::sameMeaningMatchesOverridesRegardlessOfOrder()
QVERIFY(!CalendarStore::sameMeaning(a, ics(master + second + changed)));
}
+void TestCalendarStore::sameMeaningTreatsExdatesAsASet()
+{
+ // EXDATE properties are a set; a server may reorder them on the round
+ // trip, and a list comparison would then warn about a version it kept.
+ const QByteArray a = ics(vevent(QStringLiteral(
+ "UID:ex@example.org\r\nDTSTART:20260922T080000Z\r\n"
+ "EXDATE:20260923T080000Z\r\nEXDATE:20260924T080000Z\r\n")));
+ const QByteArray b = ics(vevent(QStringLiteral(
+ "UID:ex@example.org\r\nDTSTART:20260922T080000Z\r\n"
+ "EXDATE:20260924T080000Z\r\nEXDATE:20260923T080000Z\r\n")));
+ QVERIFY(CalendarStore::sameMeaning(a, b));
+
+ // Only the order is ignored, not the contents.
+ const QByteArray changed = ics(vevent(QStringLiteral(
+ "UID:ex@example.org\r\nDTSTART:20260922T080000Z\r\n"
+ "EXDATE:20260923T080000Z\r\nEXDATE:20260925T080000Z\r\n")));
+ QVERIFY(!CalendarStore::sameMeaning(a, changed));
+}
+
void TestCalendarStore::sameMeaningRejectsDifferentUids()
{
// Identical fields, different events: the UID is the identity.
@@ -647,6 +668,34 @@ void TestCalendarStore::editingTheSameOccurrenceAgainReplacesItsOverride()
QCOMPARE(e.overrides[0].start, rome(22, 17));
}
+void TestCalendarStore::stoppingASeriesDropsItsOverrides()
+{
+ // A series with one overridden occurrence, then the repeat is stopped
+ // (Scope::All with RepeatRule() = Freq::None). The override is not a real
+ // occurrence any more: occurrences() never reads it for a non-repeating
+ // event, so leaving it in the file is invalid iCalendar that other clients
+ // may render as a phantom, and it would spring back if a repeat were
+ // re-enabled. EXDATEs are left inert.
+ const CalEvent series = parse(vevent(kDailySeries));
+ EventEdit edit = editOf(series);
+ edit.summary = QStringLiteral("Just this one");
+ edit.start = rome(22, 15);
+ edit.end = rome(22, 16);
+ const QByteArray withOverride = CalendarStore::applyEdit(
+ series.rawText, edit, CalendarStore::Scope::ThisOccurrence, rome(22, 10));
+ QCOMPARE(reparse(withOverride).overrides.size(), 1);
+
+ EventEdit stop = editOf(reparse(withOverride));
+ stop.repeat = RepeatRule(); // does not repeat
+ const QByteArray after = CalendarStore::applyEdit(
+ withOverride, stop, CalendarStore::Scope::All, {});
+
+ const CalEvent e = reparse(after);
+ QVERIFY(e.overrides.isEmpty());
+ QVERIFY2(!after.contains("RECURRENCE-ID"), after.constData());
+ QVERIFY2(!after.contains("RRULE"), after.constData());
+}
+
void TestCalendarStore::deletingOneOccurrenceAddsAnExdateAndDropsItsOverride()
{
const CalEvent series = parse(vevent(kDailySeries));