aboutsummaryrefslogtreecommitdiff
path: root/tests/test-auth-config--plstore-read-fixed.el
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-auth-config--plstore-read-fixed.el')
-rw-r--r--tests/test-auth-config--plstore-read-fixed.el101
1 files changed, 101 insertions, 0 deletions
diff --git a/tests/test-auth-config--plstore-read-fixed.el b/tests/test-auth-config--plstore-read-fixed.el
new file mode 100644
index 000000000..4b14a4a0c
--- /dev/null
+++ b/tests/test-auth-config--plstore-read-fixed.el
@@ -0,0 +1,101 @@
+;;; test-auth-config--plstore-read-fixed.el --- Tests for the oauth2-auto cache fix -*- lexical-binding: t -*-
+
+;;; Commentary:
+;; Tests for `cj/oauth2-auto--plstore-read-fixed' in auth-config.el — the
+;; advice that re-enables oauth2-auto's plstore cache. oauth2-auto is not
+;; installed here, so its symbols and the plstore I/O are stubbed at the
+;; boundary; the function's own logic (cache-first read, puthash, the
+;; unwind-protect close) runs for real. `require' is stubbed to no-op only
+;; for oauth2-auto (other requires delegate through), satisfying the
+;; function's `(require 'oauth2-auto)' without loading or provide-ing the
+;; package (a provide would fire auth-config's advice-add side effect).
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+(require 'plstore)
+(require 'auth-config)
+
+;; Declared special so the function (which reads these as free package
+;; globals) sees the dynamic let-bindings the tests establish.
+(defvar oauth2-auto--plstore-cache nil)
+(defvar oauth2-auto-plstore nil)
+
+(defvar test-auth--open-count 0 "Times plstore-open was called in a test.")
+(defvar test-auth--closed nil "Whether plstore-close ran in a test.")
+(defvar test-auth--get-fn nil "Stub behavior for plstore-get: (lambda (ps id) ...).")
+
+(defmacro test-auth--with-env (&rest body)
+ "Run BODY with a faked oauth2-auto + plstore environment.
+Resets the open counter and closed flag and gives a fresh cache each time."
+ (declare (indent 0))
+ `(let* ((oauth2-auto--plstore-cache (make-hash-table :test 'equal))
+ (oauth2-auto-plstore "/tmp/oauth2-test.plist")
+ (test-auth--open-count 0)
+ (test-auth--closed nil)
+ (orig-require (symbol-function 'require)))
+ (cl-letf (((symbol-function 'require)
+ (lambda (feat &rest args)
+ (if (eq feat 'oauth2-auto)
+ 'oauth2-auto
+ (apply orig-require feat args))))
+ ((symbol-function 'oauth2-auto--compute-id)
+ (lambda (_u _p) "ID"))
+ ((symbol-function 'plstore-open)
+ (lambda (_f) (cl-incf test-auth--open-count) 'PS))
+ ((symbol-function 'plstore-get)
+ (lambda (ps id) (funcall test-auth--get-fn ps id)))
+ ((symbol-function 'plstore-close)
+ (lambda (_p) (setq test-auth--closed t))))
+ ,@body)))
+
+;;; Normal Cases
+
+(ert-deftest test-auth-config-plstore-read-fixed-cache-hit ()
+ "Normal: a cache hit returns the cached value without opening the plstore."
+ (let ((test-auth--get-fn (lambda (_ps _id) (error "should not read"))))
+ (test-auth--with-env
+ (puthash "ID" "CACHED" oauth2-auto--plstore-cache)
+ (should (equal (cj/oauth2-auto--plstore-read-fixed "u" "p") "CACHED"))
+ (should (= test-auth--open-count 0)))))
+
+(ert-deftest test-auth-config-plstore-read-fixed-cache-miss-reads-and-caches ()
+ "Normal: a miss reads from the plstore, caches the value, and closes."
+ (let ((test-auth--get-fn (lambda (_ps id) (cons id "TOK"))))
+ (test-auth--with-env
+ (should (equal (cj/oauth2-auto--plstore-read-fixed "u" "p") "TOK"))
+ (should (equal (gethash "ID" oauth2-auto--plstore-cache) "TOK"))
+ (should (= test-auth--open-count 1))
+ (should test-auth--closed))))
+
+;;; Boundary Cases
+
+(ert-deftest test-auth-config-plstore-read-fixed-value-cached-after-first-read ()
+ "Boundary: a non-nil value is cached, so a second call does not re-open."
+ (let ((test-auth--get-fn (lambda (_ps id) (cons id "TOK"))))
+ (test-auth--with-env
+ (cj/oauth2-auto--plstore-read-fixed "u" "p")
+ (cj/oauth2-auto--plstore-read-fixed "u" "p")
+ (should (= test-auth--open-count 1)))))
+
+(ert-deftest test-auth-config-plstore-read-fixed-nil-value-rereads ()
+ "Boundary: a nil value caches nil, so every call re-opens the plstore.
+This documents current behavior — `gethash' on a nil entry is a miss."
+ (let ((test-auth--get-fn (lambda (_ps _id) (cons "ID" nil))))
+ (test-auth--with-env
+ (should-not (cj/oauth2-auto--plstore-read-fixed "u" "p"))
+ (should-not (cj/oauth2-auto--plstore-read-fixed "u" "p"))
+ (should (= test-auth--open-count 2)))))
+
+;;; Error Cases
+
+(ert-deftest test-auth-config-plstore-read-fixed-closes-on-error ()
+ "Error: a read failure still closes the plstore via unwind-protect."
+ (let ((test-auth--get-fn (lambda (&rest _) (error "boom"))))
+ (test-auth--with-env
+ (should-error (cj/oauth2-auto--plstore-read-fixed "u" "p"))
+ (should test-auth--closed))))
+
+(provide 'test-auth-config--plstore-read-fixed)
+;;; test-auth-config--plstore-read-fixed.el ends here