diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-pearl-favorites.el | 123 | ||||
| -rw-r--r-- | tests/test-pearl-saved-query-sync.el | 28 |
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 |
