diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-24 04:29:57 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-24 04:29:57 -0500 |
| commit | b26b74cb447966c0283a46afba908866777bd6ae (patch) | |
| tree | fa9112ae3ed13be6f23d44ee4cebd512c1e9cc95 /tests/test-quick-video-capture--url-state.el | |
| parent | 35e4d70116c8a2a5b82eaf4b8c58889dc02cbe46 (diff) | |
| download | dotemacs-b26b74cb447966c0283a46afba908866777bd6ae.tar.gz dotemacs-b26b74cb447966c0283a46afba908866777bd6ae.zip | |
refactor(video-capture): scope capture URL to a dynamic binding
quick-video-capture passed the org-protocol URL through a global cj/video-download-current-url: the protocol handler setq the global, the capture handler read and cleared it. If a capture was aborted or errored between those steps, the stale URL survived into the next manual capture.
Renamed it to cj/--video-download-url and let-bind it around the org-capture call in the protocol handler instead of setq-ing a global. The binding lives only for the dynamic extent of the capture, so the handler still sees the URL while the capture runs, and an abort or error unwinds the binding automatically — no stale state, no manual clear. The handler still prompts when invoked manually with no URL bound. Tests cover the bound-URL download, the manual prompt, the empty-URL error, that the URL is visible during the capture, and that an aborted capture leaves nothing behind.
Diffstat (limited to 'tests/test-quick-video-capture--url-state.el')
| -rw-r--r-- | tests/test-quick-video-capture--url-state.el | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/tests/test-quick-video-capture--url-state.el b/tests/test-quick-video-capture--url-state.el new file mode 100644 index 00000000..6a0cd583 --- /dev/null +++ b/tests/test-quick-video-capture--url-state.el @@ -0,0 +1,75 @@ +;;; test-quick-video-capture--url-state.el --- Tests for video-capture URL state -*- lexical-binding: t; -*- + +;;; Commentary: +;; Unit tests for the URL handoff between the org-protocol entry point and the +;; capture handler in quick-video-capture.el. The URL is passed via a +;; dynamically-bound variable scoped to the org-capture call, so an aborted or +;; erroring capture cannot leave a stale URL behind for the next manual capture. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'quick-video-capture) + +;;; cj/video-download-capture-handler + +(ert-deftest test-qvc-handler-downloads-bound-url () + "Normal: the handler downloads the dynamically-bound URL and saves nothing." + (let (downloaded) + (cl-letf (((symbol-function 'require) (lambda (&rest _) nil)) + ((symbol-function 'cj/yt-dl-it) (lambda (u) (setq downloaded u)))) + (let ((cj/--video-download-url "https://example.com/v")) + (should (equal "" (cj/video-download-capture-handler)))) + (should (equal "https://example.com/v" downloaded))))) + +(ert-deftest test-qvc-handler-prompts-when-no-bound-url () + "Boundary: with no bound URL the handler prompts the user." + (let (downloaded) + (cl-letf (((symbol-function 'require) (lambda (&rest _) nil)) + ((symbol-function 'cj/yt-dl-it) (lambda (u) (setq downloaded u))) + ((symbol-function 'read-string) (lambda (&rest _) "https://typed/v"))) + (let ((cj/--video-download-url nil)) + (cj/video-download-capture-handler)) + (should (equal "https://typed/v" downloaded))))) + +(ert-deftest test-qvc-handler-empty-url-errors () + "Error: an empty URL signals rather than downloading nothing." + (cl-letf (((symbol-function 'require) (lambda (&rest _) nil)) + ((symbol-function 'read-string) (lambda (&rest _) ""))) + (let ((cj/--video-download-url "")) + (should-error (cj/video-download-capture-handler))))) + +;;; cj/org-protocol-video-download — no global leak + +(ert-deftest test-qvc-protocol-binds-url-during-capture () + "Normal: the protocol handler makes the URL visible to the capture call." + (let (seen-during) + (cl-letf (((symbol-function 'cj/ensure-video-download-initialized) #'ignore) + ((symbol-function 'org-capture) + (lambda (&rest _) (setq seen-during cj/--video-download-url)))) + (cj/org-protocol-video-download '(:url "https://example.com/p"))) + (should (equal "https://example.com/p" seen-during)))) + +(ert-deftest test-qvc-protocol-leaves-no-stale-url () + "Boundary: after the protocol capture returns, no URL remains bound." + (cl-letf (((symbol-function 'cj/ensure-video-download-initialized) #'ignore) + ((symbol-function 'org-capture) #'ignore)) + (cj/org-protocol-video-download '(:url "https://example.com/p"))) + (should (null cj/--video-download-url))) + +(ert-deftest test-qvc-protocol-aborted-capture-clears-url () + "Error: a capture that errors/aborts mid-flow still leaves no stale URL. +This is the regression the dynamic binding prevents: the old global +setq survived an interrupted capture into the next manual one." + (cl-letf (((symbol-function 'cj/ensure-video-download-initialized) #'ignore) + ((symbol-function 'org-capture) + (lambda (&rest _) (error "simulated capture abort")))) + (ignore-errors + (cj/org-protocol-video-download '(:url "https://example.com/p")))) + (should (null cj/--video-download-url))) + +(provide 'test-quick-video-capture--url-state) +;;; test-quick-video-capture--url-state.el ends here |
