aboutsummaryrefslogtreecommitdiff
path: root/tests/test-wttrin-set-location-from-geolocation.el
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-wttrin-set-location-from-geolocation.el')
-rw-r--r--tests/test-wttrin-set-location-from-geolocation.el122
1 files changed, 122 insertions, 0 deletions
diff --git a/tests/test-wttrin-set-location-from-geolocation.el b/tests/test-wttrin-set-location-from-geolocation.el
new file mode 100644
index 0000000..170d0fb
--- /dev/null
+++ b/tests/test-wttrin-set-location-from-geolocation.el
@@ -0,0 +1,122 @@
+;;; test-wttrin-set-location-from-geolocation.el --- Tests for wttrin-set-location-from-geolocation -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2026 Craig Jennings
+
+;;; Commentary:
+;; Unit tests for the interactive `wttrin-set-location-from-geolocation'
+;; command. Mocks `wttrin-geolocation-detect' (to invoke the callback
+;; synchronously with a chosen value) and `yes-or-no-p' (to simulate
+;; user consent). Does not hit the network and does not prompt.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+(require 'wttrin)
+(require 'wttrin-geolocation)
+
+;;; Setup and Teardown
+
+(defvar test-wttrin-set-location-from-geolocation--saved-favorite nil
+ "Snapshot of `wttrin-favorite-location' restored in teardown.")
+
+(defun test-wttrin-set-location-from-geolocation-setup ()
+ "Snapshot `wttrin-favorite-location' and clear it for the test."
+ (setq test-wttrin-set-location-from-geolocation--saved-favorite
+ wttrin-favorite-location)
+ (setq wttrin-favorite-location nil))
+
+(defun test-wttrin-set-location-from-geolocation-teardown ()
+ "Restore `wttrin-favorite-location' to its pre-test value."
+ (setq wttrin-favorite-location
+ test-wttrin-set-location-from-geolocation--saved-favorite))
+
+;;; Helpers
+
+(defmacro test-wttrin-set-location--with-detected (location confirm &rest body)
+ "Run BODY with `wttrin-geolocation-detect' returning LOCATION and `yes-or-no-p' returning CONFIRM."
+ (declare (indent 2))
+ `(cl-letf (((symbol-function 'wttrin-geolocation-detect)
+ (lambda (callback) (funcall callback ,location)))
+ ((symbol-function 'yes-or-no-p)
+ (lambda (&rest _) ,confirm)))
+ ,@body))
+
+;;; Normal Cases
+
+(ert-deftest test-wttrin-set-location-from-geolocation-normal-confirm-sets-variable ()
+ "Successful detection followed by user confirmation sets the favorite."
+ (test-wttrin-set-location-from-geolocation-setup)
+ (unwind-protect
+ (progn
+ (test-wttrin-set-location--with-detected "Berkeley, California" t
+ (wttrin-set-location-from-geolocation))
+ (should (string= "Berkeley, California" wttrin-favorite-location)))
+ (test-wttrin-set-location-from-geolocation-teardown)))
+
+(ert-deftest test-wttrin-set-location-from-geolocation-normal-decline-leaves-variable-unchanged ()
+ "Successful detection followed by user declining leaves the favorite untouched."
+ (test-wttrin-set-location-from-geolocation-setup)
+ (setq wttrin-favorite-location "Pre-existing, Place")
+ (unwind-protect
+ (progn
+ (test-wttrin-set-location--with-detected "Berkeley, California" nil
+ (wttrin-set-location-from-geolocation))
+ (should (string= "Pre-existing, Place" wttrin-favorite-location)))
+ (test-wttrin-set-location-from-geolocation-teardown)))
+
+;;; Boundary Cases
+
+(ert-deftest test-wttrin-set-location-from-geolocation-boundary-unicode-location ()
+ "A Unicode location string round-trips into the favorite variable."
+ (test-wttrin-set-location-from-geolocation-setup)
+ (unwind-protect
+ (progn
+ (test-wttrin-set-location--with-detected "München, Bayern" t
+ (wttrin-set-location-from-geolocation))
+ (should (string= "München, Bayern" wttrin-favorite-location)))
+ (test-wttrin-set-location-from-geolocation-teardown)))
+
+;;; Error Cases
+
+(ert-deftest test-wttrin-set-location-from-geolocation-error-nil-detection-leaves-variable-unchanged ()
+ "When detection returns nil, the favorite variable is not modified."
+ (test-wttrin-set-location-from-geolocation-setup)
+ (setq wttrin-favorite-location "Pre-existing, Place")
+ (unwind-protect
+ (progn
+ (test-wttrin-set-location--with-detected nil t
+ (wttrin-set-location-from-geolocation))
+ (should (string= "Pre-existing, Place" wttrin-favorite-location)))
+ (test-wttrin-set-location-from-geolocation-teardown)))
+
+(ert-deftest test-wttrin-set-location-from-geolocation-error-nil-detection-does-not-prompt ()
+ "When detection returns nil, the user is not prompted for confirmation."
+ (test-wttrin-set-location-from-geolocation-setup)
+ (unwind-protect
+ (let ((prompt-called nil))
+ (cl-letf (((symbol-function 'wttrin-geolocation-detect)
+ (lambda (callback) (funcall callback nil)))
+ ((symbol-function 'yes-or-no-p)
+ (lambda (&rest _) (setq prompt-called t) t)))
+ (wttrin-set-location-from-geolocation))
+ (should-not prompt-called))
+ (test-wttrin-set-location-from-geolocation-teardown)))
+
+(ert-deftest test-wttrin-set-location-from-geolocation-error-detection-failure-shows-message ()
+ "When detection returns nil, the user sees a diagnostic message."
+ (test-wttrin-set-location-from-geolocation-setup)
+ (unwind-protect
+ (let ((messages nil))
+ (cl-letf (((symbol-function 'wttrin-geolocation-detect)
+ (lambda (callback) (funcall callback nil)))
+ ((symbol-function 'message)
+ (lambda (fmt &rest args)
+ (push (apply #'format fmt args) messages))))
+ (wttrin-set-location-from-geolocation))
+ (should (cl-some (lambda (m) (string-match-p "[Cc]ould not detect" m))
+ messages)))
+ (test-wttrin-set-location-from-geolocation-teardown)))
+
+(provide 'test-wttrin-set-location-from-geolocation)
+;;; test-wttrin-set-location-from-geolocation.el ends here