aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pearl.el32
-rw-r--r--tests/test-pearl-saved-query-sync.el28
2 files changed, 44 insertions, 16 deletions
diff --git a/pearl.el b/pearl.el
index 61c4934..39b7878 100644
--- a/pearl.el
+++ b/pearl.el
@@ -3820,22 +3820,22 @@ isn't in `pearl-saved-queries'."
(let ((entry (assoc name pearl-saved-queries)))
(unless entry
(user-error "No saved query named %s" name))
- (let* ((spec (cdr entry))
- (filter (plist-get spec :filter))
- (sort (plist-get spec :sort))
- (order (plist-get spec :order))
- (existing-url (plist-get spec :linear-view-url))
- (effective-url (or view-url existing-url))
- (synced-at (format-time-string "%Y-%m-%dT%H:%M:%SZ" nil t))
- (new-spec (append (list :filter filter)
- (when sort (list :sort sort))
- (when order (list :order order))
- (list :linear-view-id view-id
- :linear-view-team-id team-id
- :linear-view-shared shared
- :linear-view-synced-at synced-at)
- (when effective-url
- (list :linear-view-url effective-url)))))
+ ;; Copy the existing spec and plist-put each sync key on top. Earlier
+ ;; versions rebuilt the spec from `:filter', `:sort', `:order' + the four
+ ;; sync keys, which silently dropped any other key on the entry -- a
+ ;; future `:description', a user-added annotation, or any new schema
+ ;; field would vanish on every re-sync. Copy-then-put preserves
+ ;; everything the user (or future pearl code) attached.
+ (let* ((synced-at (format-time-string "%Y-%m-%dT%H:%M:%SZ" nil t))
+ (new-spec (copy-sequence (cdr entry))))
+ (setq new-spec (plist-put new-spec :linear-view-id view-id))
+ (setq new-spec (plist-put new-spec :linear-view-team-id team-id))
+ (setq new-spec (plist-put new-spec :linear-view-shared shared))
+ (setq new-spec (plist-put new-spec :linear-view-synced-at synced-at))
+ ;; Only touch :linear-view-url when this call supplied one; a re-sync
+ ;; whose API response somehow lacks the URL must not erase the prior.
+ (when view-url
+ (setq new-spec (plist-put new-spec :linear-view-url view-url)))
(setq pearl-saved-queries
(cons (cons name new-spec)
(assoc-delete-all name (copy-sequence pearl-saved-queries))))
diff --git a/tests/test-pearl-saved-query-sync.el b/tests/test-pearl-saved-query-sync.el
index f9bab00..ceac5e6 100644
--- a/tests/test-pearl-saved-query-sync.el
+++ b/tests/test-pearl-saved-query-sync.el
@@ -267,6 +267,34 @@ URL the create path already wrote."
(should (equal "https://linear.app/ws/view/old"
(plist-get spec :linear-view-url))))))
+(ert-deftest test-pearl-save-query-mark-synced-preserves-unknown-plist-keys ()
+ "Unknown keys on a saved-query spec survive a mark-synced call.
+The earlier implementation rebuilt the spec from a fixed key set and
+silently dropped anything outside it. Copy-then-plist-put preserves
+arbitrary keys so a future schema field or user annotation isn't
+erased on every re-sync."
+ (let ((pearl-saved-queries
+ (copy-tree '(("Q" :filter (:open t)
+ :sort updated
+ :order desc
+ :description "private note about this query"
+ :user-tag "experimental")))))
+ (cl-letf (((symbol-function 'customize-save-variable) (lambda (_ _) nil)))
+ (pearl--save-query-mark-synced "Q" "team-uuid" t "view-uuid" "https://x"))
+ (let ((spec (cdr (assoc "Q" pearl-saved-queries))))
+ ;; Original keys survive.
+ (should (equal '(:open t) (plist-get spec :filter)))
+ (should (eq 'updated (plist-get spec :sort)))
+ (should (eq 'desc (plist-get spec :order)))
+ (should (equal "private note about this query"
+ (plist-get spec :description)))
+ (should (equal "experimental" (plist-get spec :user-tag)))
+ ;; New sync keys layered on top.
+ (should (equal "view-uuid" (plist-get spec :linear-view-id)))
+ (should (equal "team-uuid" (plist-get spec :linear-view-team-id)))
+ (should (eq t (plist-get spec :linear-view-shared)))
+ (should (equal "https://x" (plist-get spec :linear-view-url))))))
+
(ert-deftest test-pearl-save-query-mark-synced-overwrites-prior-sync-metadata ()
"Re-syncing an already-synced entry overwrites the four `:linear-view-*' keys."
(let ((pearl-saved-queries