summaryrefslogtreecommitdiff
path: root/tests/test-video-audio-recording-validate-system-audio.el
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-video-audio-recording-validate-system-audio.el')
-rw-r--r--tests/test-video-audio-recording-validate-system-audio.el162
1 files changed, 162 insertions, 0 deletions
diff --git a/tests/test-video-audio-recording-validate-system-audio.el b/tests/test-video-audio-recording-validate-system-audio.el
new file mode 100644
index 00000000..ef730ab3
--- /dev/null
+++ b/tests/test-video-audio-recording-validate-system-audio.el
@@ -0,0 +1,162 @@
+;;; test-video-audio-recording-validate-system-audio.el --- Tests for cj/recording--validate-system-audio -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Unit tests for cj/recording--validate-system-audio function.
+;; Tests the pre-recording validation that catches stale/drifted system
+;; audio devices before they cause silent recordings.
+
+;;; Code:
+
+(require 'ert)
+
+;; Stub dependencies before loading the module
+(defvar cj/custom-keymap (make-sparse-keymap)
+ "Stub keymap for testing.")
+
+(require 'video-audio-recording)
+
+;;; Setup and Teardown
+
+(defun test-validate-setup ()
+ "Reset device variables before each test."
+ (setq cj/recording-system-device nil))
+
+(defun test-validate-teardown ()
+ "Clean up device variables after each test."
+ (setq cj/recording-system-device nil))
+
+;;; Normal Cases
+
+(ert-deftest test-validate-system-audio-normal-device-matches-default-no-change ()
+ "Test that no change occurs when device matches current default and audio is active."
+ (test-validate-setup)
+ (unwind-protect
+ (let ((cj/recording-system-device "alsa_output.usb-Jabra-00.analog-stereo.monitor"))
+ (cl-letf (((symbol-function 'shell-command-to-string)
+ (lambda (cmd)
+ (cond
+ ((string-match-p "sources short" cmd)
+ "65\talsa_output.usb-Jabra-00.analog-stereo.monitor\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n")
+ ((string-match-p "sinks short" cmd)
+ "65\talsa_output.usb-Jabra-00.analog-stereo\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n")
+ ((string-match-p "sink-inputs" cmd) "Sink Input #1\n\tSink: 65\n")
+ ((string-match-p "get-default-sink" cmd) "alsa_output.usb-Jabra-00.analog-stereo")
+ (t "")))))
+ (cj/recording--validate-system-audio)
+ (should (equal "alsa_output.usb-Jabra-00.analog-stereo.monitor"
+ cj/recording-system-device))))
+ (test-validate-teardown)))
+
+(ert-deftest test-validate-system-audio-normal-stale-device-auto-updates ()
+ "Test that a stale (non-existent) device is auto-updated to current default."
+ (test-validate-setup)
+ (unwind-protect
+ (let ((cj/recording-system-device "old_disappeared_device.monitor")
+ (messages nil))
+ (cl-letf (((symbol-function 'shell-command-to-string)
+ (lambda (cmd)
+ (cond
+ ((string-match-p "sources short" cmd)
+ ;; Old device NOT in list
+ "65\talsa_output.usb-Jabra-00.analog-stereo.monitor\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n")
+ ((string-match-p "sinks short" cmd)
+ "65\talsa_output.usb-Jabra-00.analog-stereo\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n")
+ ((string-match-p "sink-inputs" cmd) "Sink Input #1\n\tSink: 65\n")
+ ((string-match-p "get-default-sink" cmd) "alsa_output.usb-Jabra-00.analog-stereo")
+ (t ""))))
+ ((symbol-function 'message)
+ (lambda (fmt &rest args)
+ (push (apply #'format fmt args) messages))))
+ (cj/recording--validate-system-audio)
+ (should (equal "alsa_output.usb-Jabra-00.analog-stereo.monitor"
+ cj/recording-system-device))
+ (should (cl-some (lambda (m) (string-match-p "no longer exists" m)) messages))))
+ (test-validate-teardown)))
+
+(ert-deftest test-validate-system-audio-normal-drifted-default-auto-updates ()
+ "Test that device is updated when default sink has drifted."
+ (test-validate-setup)
+ (unwind-protect
+ (let ((cj/recording-system-device "alsa_output.pci-0000.hdmi-stereo.monitor")
+ (messages nil))
+ (cl-letf (((symbol-function 'shell-command-to-string)
+ (lambda (cmd)
+ (cond
+ ((string-match-p "sources short" cmd)
+ ;; Old device still exists
+ (concat "65\talsa_output.pci-0000.hdmi-stereo.monitor\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n"
+ "69\talsa_output.usb-Jabra-00.analog-stereo.monitor\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n"))
+ ((string-match-p "sinks short" cmd)
+ "69\talsa_output.usb-Jabra-00.analog-stereo\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n")
+ ((string-match-p "sink-inputs" cmd) "Sink Input #1\n\tSink: 69\n")
+ ;; But default has changed to Jabra
+ ((string-match-p "get-default-sink" cmd) "alsa_output.usb-Jabra-00.analog-stereo")
+ (t ""))))
+ ((symbol-function 'message)
+ (lambda (fmt &rest args)
+ (push (apply #'format fmt args) messages))))
+ (cj/recording--validate-system-audio)
+ (should (equal "alsa_output.usb-Jabra-00.analog-stereo.monitor"
+ cj/recording-system-device))
+ (should (cl-some (lambda (m) (string-match-p "default output changed" m)) messages))))
+ (test-validate-teardown)))
+
+(ert-deftest test-validate-system-audio-normal-no-audio-warns ()
+ "Test that no active audio triggers a y-or-n-p warning."
+ (test-validate-setup)
+ (unwind-protect
+ (let ((cj/recording-system-device "alsa_output.usb-Jabra-00.analog-stereo.monitor")
+ (prompted nil))
+ (cl-letf (((symbol-function 'shell-command-to-string)
+ (lambda (cmd)
+ (cond
+ ((string-match-p "sources short" cmd)
+ "65\talsa_output.usb-Jabra-00.analog-stereo.monitor\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n")
+ ((string-match-p "sinks short" cmd)
+ "65\talsa_output.usb-Jabra-00.analog-stereo\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n")
+ ;; No sink inputs — nothing playing
+ ((string-match-p "sink-inputs" cmd) "")
+ ((string-match-p "get-default-sink" cmd) "alsa_output.usb-Jabra-00.analog-stereo")
+ (t ""))))
+ ((symbol-function 'y-or-n-p)
+ (lambda (prompt)
+ (setq prompted prompt)
+ t))) ; User says yes, continue
+ (cj/recording--validate-system-audio)
+ (should prompted)
+ (should (string-match-p "No audio is playing" prompted))))
+ (test-validate-teardown)))
+
+(ert-deftest test-validate-system-audio-normal-no-audio-user-cancels ()
+ "Test that user declining the warning cancels recording."
+ (test-validate-setup)
+ (unwind-protect
+ (let ((cj/recording-system-device "alsa_output.usb-Jabra-00.analog-stereo.monitor"))
+ (cl-letf (((symbol-function 'shell-command-to-string)
+ (lambda (cmd)
+ (cond
+ ((string-match-p "sources short" cmd)
+ "65\talsa_output.usb-Jabra-00.analog-stereo.monitor\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n")
+ ((string-match-p "sinks short" cmd)
+ "65\talsa_output.usb-Jabra-00.analog-stereo\tPipeWire\ts32le 2ch 48000Hz\tSUSPENDED\n")
+ ((string-match-p "sink-inputs" cmd) "")
+ ((string-match-p "get-default-sink" cmd) "alsa_output.usb-Jabra-00.analog-stereo")
+ (t ""))))
+ ((symbol-function 'y-or-n-p)
+ (lambda (_prompt) nil))) ; User says no
+ (should-error (cj/recording--validate-system-audio) :type 'user-error)))
+ (test-validate-teardown)))
+
+;;; Boundary Cases
+
+(ert-deftest test-validate-system-audio-boundary-nil-device-skips-validation ()
+ "Test that nil system device skips all validation."
+ (let ((cj/recording-system-device nil)
+ (shell-called nil))
+ (cl-letf (((symbol-function 'shell-command-to-string)
+ (lambda (_cmd) (setq shell-called t) "")))
+ (cj/recording--validate-system-audio)
+ (should-not shell-called))))
+
+(provide 'test-video-audio-recording-validate-system-audio)
+;;; test-video-audio-recording-validate-system-audio.el ends here