aboutsummaryrefslogtreecommitdiff
path: root/tests/test-pearl-teams.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-24 13:44:34 -0500
committerCraig Jennings <c@cjennings.net>2026-05-24 13:44:34 -0500
commitb081d62276378b3168c92c06153fd59db0589535 (patch)
tree9be7f7d22e0c9b4a73432fe744c09bb456c671a9 /tests/test-pearl-teams.el
downloadpearl-b081d62276378b3168c92c06153fd59db0589535.tar.gz
pearl-b081d62276378b3168c92c06153fd59db0589535.zip
feat: pearl — manage Linear issues from org-mode
Pearl fetches Linear issues into an org file and syncs edits back. It covers list / custom views / saved queries, per-issue and bulk rendering with comments inline, conflict-aware sync of descriptions, titles, and comments, field commands for priority / state / assignee / labels, and a transient dispatch menu. The render folds to a scannable outline and nests issues under a sortable parent. Based on and inspired by Gael Blanchemain's linear-emacs.
Diffstat (limited to 'tests/test-pearl-teams.el')
-rw-r--r--tests/test-pearl-teams.el109
1 files changed, 109 insertions, 0 deletions
diff --git a/tests/test-pearl-teams.el b/tests/test-pearl-teams.el
new file mode 100644
index 0000000..dc7e41c
--- /dev/null
+++ b/tests/test-pearl-teams.el
@@ -0,0 +1,109 @@
+;;; test-pearl-teams.el --- Tests for pearl team/project lookups -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Craig Jennings
+
+;; Author: Craig Jennings <c@cjennings.net>
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Tests for team, project, member, and label lookups with `request' stubbed.
+;; These exercise the response-unwrapping (assoc nesting) and the
+;; name-to-id resolution used when syncing org headings back to Linear.
+
+;;; Code:
+
+(require 'test-bootstrap (expand-file-name "test-bootstrap.el"))
+(require 'testutil-request (expand-file-name "testutil-request.el"))
+
+;;; pearl-get-teams-async
+
+(ert-deftest test-pearl-get-teams-async-parses-nodes ()
+ "Teams are unwrapped from data.teams.nodes and passed to the callback."
+ (let ((got nil)
+ (pearl--cache-teams nil))
+ (testutil-linear-with-response
+ '((data (teams (nodes . (((id . "t1") (name . "Eng"))
+ ((id . "t2") (name . "Ops")))))))
+ (pearl-get-teams-async (lambda (teams) (setq got teams))))
+ (should (= 2 (length got)))
+ (should (string-equal "Eng" (cdr (assoc 'name (car got)))))))
+
+;;; pearl--get-team-id-by-name
+
+(ert-deftest test-pearl-get-team-id-by-name-found ()
+ "A team whose name matches resolves to its id."
+ (let ((pearl--cache-teams nil))
+ (testutil-linear-with-response
+ '((data (teams (nodes . (((id . "t1") (name . "Eng")))))))
+ (should (string-equal "t1" (pearl--get-team-id-by-name "Eng"))))))
+
+(ert-deftest test-pearl-get-team-id-by-name-not-found ()
+ "A name with no matching team resolves to nil."
+ (let ((pearl--cache-teams nil))
+ (testutil-linear-with-response
+ '((data (teams (nodes . (((id . "t1") (name . "Eng")))))))
+ (should (null (pearl--get-team-id-by-name "Marketing"))))))
+
+(ert-deftest test-pearl-team-id-lookup-caches-teams ()
+ "A second team-id lookup reuses the cached team list, no new request."
+ (let ((pearl-api-key "test-key")
+ (pearl--cache-teams nil)
+ (calls 0))
+ (cl-letf (((symbol-function 'request)
+ (lambda (_url &rest args)
+ (setq calls (1+ calls))
+ (funcall (plist-get args :success)
+ :data '((data (teams (nodes . (((id . "t1") (name . "Eng"))
+ ((id . "t2") (name . "Ops"))))))))) ))
+ (should (string-equal "t1" (pearl--get-team-id-by-name "Eng")))
+ (should (string-equal "t2" (pearl--get-team-id-by-name "Ops")))
+ (should (= 1 calls)))))
+
+;;; pearl-get-projects
+
+(ert-deftest test-pearl-get-projects-converts-vector-to-list ()
+ "Projects come back as a vector from json-read and are returned as a list."
+ (testutil-linear-with-response
+ '((data (team (projects (nodes . [((id . "p1") (name . "Platform"))])))))
+ (let ((projects (pearl-get-projects "team-1")))
+ (should (listp projects))
+ (should (= 1 (length projects)))
+ (should (string-equal "Platform" (cdr (assoc 'name (car projects))))))))
+
+;;; pearl-get-issue-types
+
+(ert-deftest test-pearl-get-issue-types-maps-name-to-id ()
+ "Issue-type labels are returned as a name -> id alist."
+ (testutil-linear-with-response
+ '((data (team (labels (nodes . (((id . "l1") (name . "bug"))
+ ((id . "l2") (name . "feature"))))))))
+ (let ((types (pearl-get-issue-types "team-1")))
+ (should (string-equal "l1" (cdr (assoc "bug" types))))
+ (should (string-equal "l2" (cdr (assoc "feature" types)))))))
+
+;;; pearl-get-team-members
+
+(ert-deftest test-pearl-get-team-members-prefers-display-name ()
+ "Members map their display name (falling back to name) to their id."
+ (testutil-linear-with-response
+ '((data (team (members (nodes . (((id . "m1") (name . "Ada Lovelace") (displayName . "Ada"))
+ ((id . "m2") (name . "Alan Turing"))))))))
+ (let ((members (pearl-get-team-members "team-1")))
+ (should (string-equal "m1" (cdr (assoc "Ada" members))))
+ (should (string-equal "m2" (cdr (assoc "Alan Turing" members)))))))
+
+(provide 'test-pearl-teams)
+;;; test-pearl-teams.el ends here