summaryrefslogtreecommitdiff
path: root/tests/test-chime-notify.el
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-chime-notify.el')
-rw-r--r--tests/test-chime-notify.el244
1 files changed, 244 insertions, 0 deletions
diff --git a/tests/test-chime-notify.el b/tests/test-chime-notify.el
new file mode 100644
index 0000000..451508d
--- /dev/null
+++ b/tests/test-chime-notify.el
@@ -0,0 +1,244 @@
+;;; test-chime-notify.el --- Tests for chime--notify -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2024 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:
+
+;; Unit tests for chime--notify function.
+;; Tests cover normal cases, boundary cases, and error cases.
+
+;;; Code:
+
+;; Initialize package system for batch mode
+(when noninteractive
+ (package-initialize))
+
+(require 'ert)
+
+;; Load dependencies required by chime
+(require 'dash)
+(require 'alert)
+(require 'async)
+(require 'org-agenda)
+
+;; Load chime from parent directory
+(load (expand-file-name "../chime.el") nil t)
+
+;; Load test utilities
+(require 'testutil-general (expand-file-name "testutil-general.el"))
+
+;;; Setup and Teardown
+
+(defun test-chime-notify-setup ()
+ "Setup function run before each test."
+ (chime-create-test-base-dir)
+ ;; Reset notification settings
+ (setq chime-notification-title "Agenda")
+ (setq chime-notification-icon nil)
+ (setq chime-alert-severity 'medium)
+ (setq chime-extra-alert-plist nil)
+ (setq chime-play-sound t)
+ ;; Use a simple test path for sound file
+ (setq chime-sound-file "/tmp/test-chime.wav"))
+
+(defun test-chime-notify-teardown ()
+ "Teardown function run after each test."
+ (chime-delete-test-base-dir))
+
+;;; Normal Cases
+
+(ert-deftest test-chime-notify-plays-sound-when-enabled-and-file-exists ()
+ "Test that sound is played when enabled and file exists."
+ (test-chime-notify-setup)
+ (unwind-protect
+ (let ((sound-played nil)
+ (alert-called nil)
+ (alert-message nil))
+ (cl-letf* ((chime-play-sound t)
+ (chime-sound-file (expand-file-name "test-sound.wav" chime-test-base-dir))
+ ;; Mock file-exists-p to return t
+ ((symbol-function 'file-exists-p) (lambda (file) t))
+ ;; Mock play-sound-file to track if called
+ ((symbol-function 'play-sound-file)
+ (lambda (file)
+ (setq sound-played t)))
+ ;; Mock alert to track if called
+ ((symbol-function 'alert)
+ (lambda (msg &rest args)
+ (setq alert-called t)
+ (setq alert-message msg))))
+ (chime--notify "Team Meeting at 02:10 PM")
+ ;; Should play sound
+ (should sound-played)
+ ;; Should show alert
+ (should alert-called)
+ (should (equal alert-message "Team Meeting at 02:10 PM"))))
+ (test-chime-notify-teardown)))
+
+(ert-deftest test-chime-notify-uses-beep-when-no-sound-file-specified ()
+ "Test that beep is used when chime-sound-file is nil."
+ (test-chime-notify-setup)
+ (unwind-protect
+ (let ((beep-called nil)
+ (alert-called nil))
+ (cl-letf* ((chime-play-sound t)
+ (chime-sound-file nil)
+ ;; Mock beep to track if called
+ ((symbol-function 'beep)
+ (lambda () (setq beep-called t)))
+ ;; Mock alert
+ ((symbol-function 'alert)
+ (lambda (msg &rest args) (setq alert-called t))))
+ (chime--notify "Standup in 5 minutes")
+ ;; Should call beep
+ (should beep-called)
+ ;; Should show alert
+ (should alert-called)))
+ (test-chime-notify-teardown)))
+
+(ert-deftest test-chime-notify-no-sound-when-disabled ()
+ "Test that no sound is played when chime-play-sound is nil."
+ (test-chime-notify-setup)
+ (unwind-protect
+ (let ((sound-played nil)
+ (beep-called nil)
+ (alert-called nil))
+ (cl-letf* ((chime-play-sound nil)
+ ((symbol-function 'play-sound-file)
+ (lambda (file) (setq sound-played t)))
+ ((symbol-function 'beep)
+ (lambda () (setq beep-called t)))
+ ((symbol-function 'alert)
+ (lambda (msg &rest args) (setq alert-called t))))
+ (chime--notify "Daily Standup")
+ ;; Should NOT play sound or beep
+ (should-not sound-played)
+ (should-not beep-called)
+ ;; Should still show alert
+ (should alert-called)))
+ (test-chime-notify-teardown)))
+
+(ert-deftest test-chime-notify-passes-correct-parameters-to-alert ()
+ "Test that alert is called with correct parameters."
+ (test-chime-notify-setup)
+ (unwind-protect
+ (let ((alert-params nil))
+ (cl-letf* ((chime-play-sound nil)
+ (chime-notification-title "Custom Title")
+ (chime-notification-icon "/path/to/icon.png")
+ (chime-alert-severity 'high)
+ (chime-extra-alert-plist '(:persistent t))
+ ;; Mock alert to capture parameters
+ ((symbol-function 'alert)
+ (lambda (msg &rest args) (setq alert-params args))))
+ (chime--notify "Test Event")
+ ;; Verify alert was called with correct parameters
+ (should (equal (plist-get alert-params :title) "Custom Title"))
+ (should (equal (plist-get alert-params :icon) "/path/to/icon.png"))
+ (should (equal (plist-get alert-params :severity) 'high))
+ (should (equal (plist-get alert-params :category) 'chime))
+ ;; Extra plist should be merged in
+ (should (equal (plist-get alert-params :persistent) t))))
+ (test-chime-notify-teardown)))
+
+;;; Boundary Cases
+
+(ert-deftest test-chime-notify-empty-message-still-notifies ()
+ "Test that empty message still triggers notification."
+ (test-chime-notify-setup)
+ (unwind-protect
+ (let ((alert-called nil)
+ (alert-message nil))
+ (cl-letf* ((chime-play-sound nil)
+ ((symbol-function 'alert)
+ (lambda (msg &rest args)
+ (setq alert-called t)
+ (setq alert-message msg))))
+ (chime--notify "")
+ ;; Should still call alert, even with empty message
+ (should alert-called)
+ (should (equal alert-message ""))))
+ (test-chime-notify-teardown)))
+
+(ert-deftest test-chime-notify-no-sound-file-when-file-doesnt-exist ()
+ "Test that no sound is played when file doesn't exist."
+ (test-chime-notify-setup)
+ (unwind-protect
+ (let ((sound-played nil)
+ (alert-called nil))
+ (cl-letf* ((chime-play-sound t)
+ (chime-sound-file "/nonexistent/path/sound.wav")
+ ;; Mock file-exists-p to return nil
+ ((symbol-function 'file-exists-p) (lambda (file) nil))
+ ((symbol-function 'play-sound-file)
+ (lambda (file) (setq sound-played t)))
+ ((symbol-function 'alert)
+ (lambda (msg &rest args) (setq alert-called t))))
+ (chime--notify "Test Event")
+ ;; Should NOT play sound
+ (should-not sound-played)
+ ;; Should still show alert
+ (should alert-called)))
+ (test-chime-notify-teardown)))
+
+;;; Error Cases
+
+(ert-deftest test-chime-notify-handles-sound-playback-error-gracefully ()
+ "Test that errors in sound playback don't prevent notification."
+ (test-chime-notify-setup)
+ (unwind-protect
+ (let ((alert-called nil))
+ (cl-letf* ((chime-play-sound t)
+ (chime-sound-file "/some/file.wav")
+ ;; Mock file-exists-p to return t
+ ((symbol-function 'file-exists-p) (lambda (file) t))
+ ;; Mock play-sound-file to throw error
+ ((symbol-function 'play-sound-file)
+ (lambda (file) (error "Sound playback failed")))
+ ((symbol-function 'alert)
+ (lambda (msg &rest args) (setq alert-called t))))
+ ;; Should not throw error
+ (should-not (condition-case nil
+ (progn (chime--notify "Test Event") nil)
+ (error t)))
+ ;; Should still show alert despite sound error
+ (should alert-called)))
+ (test-chime-notify-teardown)))
+
+(ert-deftest test-chime-notify-handles-beep-error-gracefully ()
+ "Test that errors in beep don't prevent notification."
+ (test-chime-notify-setup)
+ (unwind-protect
+ (let ((alert-called nil))
+ (cl-letf* ((chime-play-sound t)
+ (chime-sound-file nil)
+ ;; Mock beep to throw error
+ ((symbol-function 'beep)
+ (lambda () (error "Beep failed")))
+ ((symbol-function 'alert)
+ (lambda (msg &rest args) (setq alert-called t))))
+ ;; Should not throw error
+ (should-not (condition-case nil
+ (progn (chime--notify "Test Event") nil)
+ (error t)))
+ ;; Should still show alert despite beep error
+ (should alert-called)))
+ (test-chime-notify-teardown)))
+
+(provide 'test-chime-notify)
+;;; test-chime-notify.el ends here