aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test-pearl-favorites.el123
-rw-r--r--tests/test-pearl-saved-query-sync.el28
2 files changed, 151 insertions, 0 deletions
diff --git a/tests/test-pearl-favorites.el b/tests/test-pearl-favorites.el
index b47cde6..70507d7 100644
--- a/tests/test-pearl-favorites.el
+++ b/tests/test-pearl-favorites.el
@@ -213,6 +213,129 @@ For an issue node, IDENTIFIER fills the issue's user-facing key."
"No favorites and no saved queries yields no candidates."
(should (null (pearl--pick-source-candidates nil nil))))
+;;; pick-source candidate builder -- synced saved queries (view-sync Phase 4)
+
+(ert-deftest test-pearl-pick-source-candidates-synced-saved-query-team-scope ()
+ "A team-scoped synced entry renders as `[saved \\u2192 <TeamName>] <Name>'."
+ (let* ((teams '(((id . "team-eng-id") (key . "ENG") (name . "Engineering"))))
+ (saved '(("My team view" :filter (:open t)
+ :linear-view-id "view-uuid"
+ :linear-view-team-id "team-eng-id"
+ :linear-view-shared t)))
+ (cands (pearl--pick-source-candidates nil saved teams)))
+ (should (assoc "[saved → Engineering] My team view" cands))))
+
+(ert-deftest test-pearl-pick-source-candidates-synced-saved-query-personal-scope ()
+ "A personal synced entry renders as `[saved \\u2192 Personal] <Name>'."
+ (let* ((saved '(("Mine" :filter (:open t)
+ :linear-view-id "view-uuid"
+ :linear-view-team-id nil
+ :linear-view-shared :json-false)))
+ (cands (pearl--pick-source-candidates nil saved nil)))
+ (should (assoc "[saved → Personal] Mine" cands))))
+
+(ert-deftest test-pearl-pick-source-candidates-synced-saved-query-unknown-team-renders-q ()
+ "A synced entry whose team-id isn't in TEAMS renders `[saved \\u2192 ?] <Name>'."
+ (let* ((teams '(((id . "other-id") (key . "OTH") (name . "Other"))))
+ (saved '(("Stale" :filter (:open t)
+ :linear-view-id "view-uuid"
+ :linear-view-team-id "gone-team-id")))
+ (cands (pearl--pick-source-candidates nil saved teams)))
+ (should (assoc "[saved → ?] Stale" cands))))
+
+(ert-deftest test-pearl-pick-source-candidates-synced-saved-query-no-teams-arg-renders-q ()
+ "When TEAMS is nil and an entry has a non-nil team-id, scope is `?'."
+ (let* ((saved '(("S" :filter (:open t)
+ :linear-view-id "view-uuid"
+ :linear-view-team-id "team-x"))))
+ (should (assoc "[saved → ?] S"
+ (pearl--pick-source-candidates nil saved nil)))))
+
+(ert-deftest test-pearl-pick-source-candidates-synced-saved-query-dispatches-as-view ()
+ "A synced entry's source plist has :type view with :id = :linear-view-id."
+ (let* ((saved '(("S" :filter (:open t)
+ :linear-view-id "view-uuid-X"
+ :linear-view-team-id nil)))
+ (cands (pearl--pick-source-candidates nil saved nil))
+ (source (cdr (assoc "[saved → Personal] S" cands))))
+ (should (eq 'view (plist-get source :type)))
+ (should (equal "view-uuid-X" (plist-get source :id)))
+ (should (equal "S" (plist-get source :name)))))
+
+(ert-deftest test-pearl-pick-source-candidates-synced-source-includes-url-when-stored ()
+ "A synced entry carrying `:linear-view-url' surfaces it in the source plist
+so `pearl-open-current-view-in-linear' can dispatch to the browser."
+ (let* ((saved '(("S" :filter (:open t)
+ :linear-view-id "view-uuid-X"
+ :linear-view-team-id nil
+ :linear-view-url "https://linear.app/ws/view/abc")))
+ (cands (pearl--pick-source-candidates nil saved nil))
+ (source (cdr (assoc "[saved → Personal] S" cands))))
+ (should (equal "https://linear.app/ws/view/abc"
+ (plist-get source :url)))))
+
+(ert-deftest test-pearl-pick-source-candidates-synced-source-no-url-when-not-stored ()
+ "An entry synced before `:linear-view-url' tracking landed has no URL in the
+source plist; the open-in-Linear command errors cleanly until the user re-syncs."
+ (let* ((saved '(("S" :filter (:open t)
+ :linear-view-id "view-uuid-X"
+ :linear-view-team-id nil)))
+ (cands (pearl--pick-source-candidates nil saved nil))
+ (source (cdr (assoc "[saved → Personal] S" cands))))
+ (should-not (plist-get source :url))))
+
+(ert-deftest test-pearl-pick-source-candidates-local-only-saved-query-keeps-saved-label ()
+ "A saved query without :linear-view-id still renders as `[saved] <Name>' and dispatches as filter."
+ (let* ((saved '(("Local" :filter (:open t))))
+ (cands (pearl--pick-source-candidates nil saved '()))
+ (source (cdr (assoc "[saved] Local" cands))))
+ (should source)
+ (should (eq 'filter (plist-get source :type)))
+ (should (equal '(:open t) (plist-get source :filter)))))
+
+(ert-deftest test-pearl-pick-source-candidates-mixed-local-and-synced ()
+ "A picker mixing local-only and synced entries renders both label styles."
+ (let* ((teams '(((id . "team-eng-id") (key . "ENG") (name . "Engineering"))))
+ (saved '(("Local thing" :filter (:open t))
+ ("Synced thing" :filter (:open t)
+ :linear-view-id "view-uuid"
+ :linear-view-team-id "team-eng-id")))
+ (cands (pearl--pick-source-candidates nil saved teams))
+ (labels (mapcar #'car cands)))
+ (should (member "[saved] Local thing" labels))
+ (should (member "[saved → Engineering] Synced thing" labels))))
+
+;;; pearl--saved-query-scope-label
+
+(ert-deftest test-pearl-saved-query-scope-label-local-only-returns-nil ()
+ "An entry without :linear-view-id has no scope and returns nil."
+ (should (null (pearl--saved-query-scope-label '(:filter (:open t)) nil))))
+
+(ert-deftest test-pearl-saved-query-scope-label-personal-when-no-team-id ()
+ "A synced entry with nil team-id renders as \"Personal\"."
+ (should (equal "Personal"
+ (pearl--saved-query-scope-label
+ '(:filter (:open t) :linear-view-id "v" :linear-view-team-id nil)
+ nil))))
+
+(ert-deftest test-pearl-saved-query-scope-label-resolves-team-name-from-teams ()
+ "A synced entry with a team-id resolves to that team's name."
+ (let ((teams '(((id . "team-eng-id") (key . "ENG") (name . "Engineering")))))
+ (should (equal "Engineering"
+ (pearl--saved-query-scope-label
+ '(:filter (:open t)
+ :linear-view-id "v" :linear-view-team-id "team-eng-id")
+ teams)))))
+
+(ert-deftest test-pearl-saved-query-scope-label-unknown-team-id-renders-q ()
+ "An entry whose team-id doesn't appear in TEAMS renders \"?\"."
+ (let ((teams '(((id . "other-id") (name . "Other")))))
+ (should (equal "?"
+ (pearl--saved-query-scope-label
+ '(:filter (:open t)
+ :linear-view-id "v" :linear-view-team-id "gone")
+ teams)))))
+
;;; open-favorite-url
(ert-deftest test-pearl-open-favorite-url-with-url-browses ()
diff --git a/tests/test-pearl-saved-query-sync.el b/tests/test-pearl-saved-query-sync.el
index ebf4622..830f738 100644
--- a/tests/test-pearl-saved-query-sync.el
+++ b/tests/test-pearl-saved-query-sync.el
@@ -239,6 +239,34 @@
(pearl--save-query-mark-synced "Q" nil nil "view-uuid")
:type 'user-error)))
+(ert-deftest test-pearl-save-query-mark-synced-stores-view-url-when-given ()
+ "The optional VIEW-URL arg lands in the entry as :linear-view-url."
+ (let ((pearl-saved-queries
+ (copy-tree '(("Q" :filter (:open t))))))
+ (cl-letf (((symbol-function 'customize-save-variable) (lambda (_ _) nil)))
+ (pearl--save-query-mark-synced
+ "Q" nil nil "view-uuid" "https://linear.app/ws/view/abc"))
+ (let ((spec (cdr (assoc "Q" pearl-saved-queries))))
+ (should (equal "https://linear.app/ws/view/abc"
+ (plist-get spec :linear-view-url))))))
+
+(ert-deftest test-pearl-save-query-mark-synced-keeps-prior-url-when-omitted ()
+ "Omitting VIEW-URL on a re-sync preserves any previously stored URL.
+Re-sync paths whose API response doesn't carry a URL shouldn't erase a
+URL the create path already wrote."
+ (let ((pearl-saved-queries
+ (copy-tree '(("Q" :filter (:open t)
+ :linear-view-id "old-id"
+ :linear-view-team-id nil
+ :linear-view-shared :json-false
+ :linear-view-url "https://linear.app/ws/view/old")))))
+ (cl-letf (((symbol-function 'customize-save-variable) (lambda (_ _) nil)))
+ ;; No VIEW-URL passed -- the prior URL should survive.
+ (pearl--save-query-mark-synced "Q" nil nil "new-id"))
+ (let ((spec (cdr (assoc "Q" pearl-saved-queries))))
+ (should (equal "https://linear.app/ws/view/old"
+ (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