diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-signal-config.el | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/tests/test-signal-config.el b/tests/test-signal-config.el new file mode 100644 index 00000000..40879342 --- /dev/null +++ b/tests/test-signal-config.el @@ -0,0 +1,141 @@ +;;; test-signal-config.el --- Tests for signal-config -*- lexical-binding: t -*- + +;;; Commentary: +;; ERT tests for the pure helper layer of `signal-config': contact-list +;; parsing for the contact picker, and the notify-when-not-viewing +;; predicate. These need neither signal-cli nor a linked account. + +;;; Code: + +(require 'ert) +(require 'json) +(require 'signal-config) + +;;; cj/signal--jstr + +(ert-deftest test-signal-config-jstr-string () + "Normal: a non-blank string passes through unchanged." + (should (equal (cj/signal--jstr "hi") "hi"))) + +(ert-deftest test-signal-config-jstr-rejects-nonstrings () + "Boundary/Error: nil, empty, whitespace, and non-string sentinels become nil." + (should-not (cj/signal--jstr nil)) + (should-not (cj/signal--jstr "")) + (should-not (cj/signal--jstr " ")) + (should-not (cj/signal--jstr :null)) + (should-not (cj/signal--jstr 42))) + +;;; cj/signal--contact-display-name +;; Field priority: nickName, then nickGiven+nickFamily, then top-level name, +;; then top-level given+family, then profile given+family, then username. + +(ert-deftest test-signal-config-display-name-prefers-name () + "Normal: the top-level combined name wins over the given/family parts." + (should (equal (cj/signal--contact-display-name + '((name . "Alice Anderson") (givenName . "Ali") (familyName . "A"))) + "Alice Anderson"))) + +(ert-deftest test-signal-config-display-name-nickname-wins () + "Normal: a nickName overrides the contact name." + (should (equal (cj/signal--contact-display-name + '((nickName . "Edster") (name . "Eve Edwards") + (givenName . "Eve") (familyName . "Edwards"))) + "Edster"))) + +(ert-deftest test-signal-config-display-name-nickname-parts () + "Boundary: nickGivenName+nickFamilyName combine when nickName is unset." + (should (equal (cj/signal--contact-display-name + '((nickGivenName . "DJ") (nickFamilyName . "Cool") (name . "Daniel"))) + "DJ Cool"))) + +(ert-deftest test-signal-config-display-name-toplevel-given-family () + "Boundary: with no name, top-level givenName+familyName combine." + (should (equal (cj/signal--contact-display-name + '((name) (givenName . "Bob") (familyName . "Brown"))) + "Bob Brown"))) + +(ert-deftest test-signal-config-display-name-profile-fallback () + "Boundary: with no name or top-level parts, profile given/family is the fallback." + (should (equal (cj/signal--contact-display-name + '((name) (givenName) (familyName) + (profile . ((givenName . "Carol") (familyName))))) + "Carol"))) + +(ert-deftest test-signal-config-display-name-username-fallback () + "Boundary: username is the last name source." + (should (equal (cj/signal--contact-display-name + '((name) (username . "dave.42"))) + "dave.42"))) + +(ert-deftest test-signal-config-display-name-none () + "Error: no usable name yields nil." + (should-not (cj/signal--contact-display-name + '((name) (givenName) (familyName) + (profile . ((givenName) (familyName)))))) + (should-not (cj/signal--contact-display-name '((number . "+15551112222"))))) + +;;; cj/signal--parse-contacts + +(defconst test-signal-config--contacts-json + "[ + {\"number\":\"+15551112222\",\"uuid\":\"uuid-a\",\"name\":\"Alice Anderson\",\"givenName\":\"Alice\",\"familyName\":\"Anderson\",\"nickName\":null,\"nickGivenName\":null,\"nickFamilyName\":null,\"username\":null,\"profile\":{\"givenName\":null,\"familyName\":null}}, + {\"number\":\"+15553334444\",\"uuid\":null,\"name\":null,\"givenName\":\"Bob\",\"familyName\":\"Brown\",\"nickName\":null,\"username\":null,\"profile\":{\"givenName\":null,\"familyName\":null}}, + {\"number\":\"+15555556666\",\"uuid\":\"uuid-c\",\"name\":null,\"givenName\":null,\"familyName\":null,\"nickName\":null,\"username\":null,\"profile\":{\"givenName\":\"Carol\",\"familyName\":null}}, + {\"number\":null,\"uuid\":\"uuid-d\",\"name\":null,\"givenName\":null,\"familyName\":null,\"username\":null,\"profile\":{\"givenName\":null,\"familyName\":null}}, + {\"number\":\"+15557778888\",\"uuid\":\"uuid-e\",\"name\":\"Eve Edwards\",\"givenName\":\"Eve\",\"familyName\":\"Edwards\",\"nickName\":\"Edster\",\"username\":null,\"profile\":{\"givenName\":null,\"familyName\":null}} +]" + "Synthetic fixture mirroring the signal-cli 0.14.4.1 `listContacts' shape: +top-level name/givenName/familyName and nickName fields, with a profile +sub-object whose name fields are usually null. Field layout was confirmed +against a live linked account on 2026-05-26; the values here are fake.") + +(ert-deftest test-signal-config-parse-contacts-normal () + "Normal: top-level name, top-level parts, profile fallback, uuid fallback, nickname." + (let* ((result (json-read-from-string test-signal-config--contacts-json)) + (pairs (cj/signal--parse-contacts result))) + (should (equal pairs + '(("Alice Anderson (+15551112222)" . "+15551112222") + ("Bob Brown (+15553334444)" . "+15553334444") + ("Carol (+15555556666)" . "+15555556666") + ("Edster (+15557778888)" . "+15557778888") + ("uuid-d" . "uuid-d")))))) + +(ert-deftest test-signal-config-parse-contacts-empty () + "Boundary: an empty result yields nil for both vector and nil input." + (should-not (cj/signal--parse-contacts [])) + (should-not (cj/signal--parse-contacts nil))) + +(ert-deftest test-signal-config-parse-contacts-accepts-list-and-vector () + "Boundary: vector and list result sequences parse identically." + (let ((entry '((number . "+15551112222") (name . "Al")))) + (should (equal (cj/signal--parse-contacts (vector entry)) + (cj/signal--parse-contacts (list entry)))))) + +(ert-deftest test-signal-config-parse-contacts-drops-recipientless () + "Error: a contact with neither number nor uuid is dropped." + (should-not (cj/signal--parse-contacts + (list '((name . "Ghost") (number) (uuid)))))) + +;;; cj/signal--suppress-notify-p + +(ert-deftest test-signal-config-suppress-when-viewing-focused () + "Normal: viewing the chat buffer with focus suppresses the notification." + (should (cj/signal--suppress-notify-p + "+15551112222" "*Signel: +15551112222*" t))) + +(ert-deftest test-signal-config-no-suppress-other-buffer () + "Boundary: a different selected buffer does not suppress." + (should-not (cj/signal--suppress-notify-p + "+15551112222" "*scratch*" t))) + +(ert-deftest test-signal-config-no-suppress-unfocused () + "Boundary: viewing the chat but with the frame unfocused still notifies." + (should-not (cj/signal--suppress-notify-p + "+15551112222" "*Signel: +15551112222*" nil))) + +(ert-deftest test-signal-config-no-suppress-nil-viewing () + "Error: a nil viewing-buffer name does not suppress." + (should-not (cj/signal--suppress-notify-p "+15551112222" nil t))) + +(provide 'test-signal-config) +;;; test-signal-config.el ends here |
