aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/calendar-sync.el10
-rw-r--r--tests/test-calendar-sync--apply-single-exception.el37
2 files changed, 46 insertions, 1 deletions
diff --git a/modules/calendar-sync.el b/modules/calendar-sync.el
index 8d7552d3e..7ed14921f 100644
--- a/modules/calendar-sync.el
+++ b/modules/calendar-sync.el
@@ -540,7 +540,15 @@ Compares year, month, day, hour, minute."
(plist-put result :location (plist-get exception :location)))
;; Pass through new fields if exception overrides them
(when (plist-get exception :attendees)
- (plist-put result :attendees (plist-get exception :attendees)))
+ (plist-put result :attendees (plist-get exception :attendees))
+ ;; Re-derive the user's status from the overridden attendees so a
+ ;; singly-declined occurrence drops its inherited series "accepted"
+ ;; (otherwise `calendar-sync--filter-declined' can't drop it). Leave the
+ ;; inherited status when the override doesn't name the user.
+ (let ((status (calendar-sync--find-user-status
+ (plist-get exception :attendees) calendar-sync-user-emails)))
+ (when status
+ (plist-put result :status status))))
(when (plist-get exception :organizer)
(plist-put result :organizer (plist-get exception :organizer)))
(when (plist-get exception :url)
diff --git a/tests/test-calendar-sync--apply-single-exception.el b/tests/test-calendar-sync--apply-single-exception.el
index 3d2342708..f23104d98 100644
--- a/tests/test-calendar-sync--apply-single-exception.el
+++ b/tests/test-calendar-sync--apply-single-exception.el
@@ -105,5 +105,42 @@
(plist-get (calendar-sync--apply-single-exception occ exc)
:url)))))
+;;; Status re-derivation from overridden attendees (chime handoff 2026-06-24)
+
+(ert-deftest test-calendar-sync--apply-single-exception-declined-occurrence-rederives-status ()
+ "Normal: a declined single occurrence re-derives :status from the override attendees."
+ (let ((calendar-sync-user-emails '("craig@example.com"))
+ (occ (list :start '(2026 6 24 16 0) :status "accepted" :uid "abc"))
+ (exc (list :start '(2026 6 24 16 0)
+ :attendees (list (list :email "craig@example.com" :partstat "DECLINED")))))
+ (should (equal "declined"
+ (plist-get (calendar-sync--apply-single-exception occ exc) :status)))))
+
+(ert-deftest test-calendar-sync--apply-single-exception-no-attendee-override-keeps-status ()
+ "Boundary: an exception with no attendee block leaves the inherited :status intact."
+ (let ((calendar-sync-user-emails '("craig@example.com"))
+ (occ (list :start '(2026 6 24 16 0) :status "accepted" :uid "abc"))
+ (exc (list :start '(2026 6 24 16 0) :summary "Moved")))
+ (should (equal "accepted"
+ (plist-get (calendar-sync--apply-single-exception occ exc) :status)))))
+
+(ert-deftest test-calendar-sync--apply-single-exception-accepted-override-stays-accepted ()
+ "Normal: an accepted attendee override keeps :status accepted."
+ (let ((calendar-sync-user-emails '("craig@example.com"))
+ (occ (list :start '(2026 6 24 16 0) :status "accepted" :uid "abc"))
+ (exc (list :start '(2026 6 24 16 0)
+ :attendees (list (list :email "craig@example.com" :partstat "ACCEPTED")))))
+ (should (equal "accepted"
+ (plist-get (calendar-sync--apply-single-exception occ exc) :status)))))
+
+(ert-deftest test-calendar-sync--apply-single-exception-override-without-user-keeps-status ()
+ "Boundary: override attendees that don't include the user leave :status intact."
+ (let ((calendar-sync-user-emails '("craig@example.com"))
+ (occ (list :start '(2026 6 24 16 0) :status "accepted" :uid "abc"))
+ (exc (list :start '(2026 6 24 16 0)
+ :attendees (list (list :email "someone@else.com" :partstat "DECLINED")))))
+ (should (equal "accepted"
+ (plist-get (calendar-sync--apply-single-exception occ exc) :status)))))
+
(provide 'test-calendar-sync--apply-single-exception)
;;; test-calendar-sync--apply-single-exception.el ends here