test-org-protocol.el 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. ;;; test-org-protocol.el --- tests for org-protocol.el -*- lexical-binding: t; -*-
  2. ;; Copyright (c) Sacha Chua
  3. ;; Authors: Sacha Chua
  4. ;; This file is not part of GNU Emacs.
  5. ;; This program is free software; you can redistribute it and/or modify
  6. ;; it under the terms of the GNU General Public License as published by
  7. ;; the Free Software Foundation, either version 3 of the License, or
  8. ;; (at your option) any later version.
  9. ;; This program is distributed in the hope that it will be useful,
  10. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ;; GNU General Public License for more details.
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. ;;; Code:
  16. (require 'cl-lib)
  17. (unless (featurep 'org-protocol)
  18. (signal 'missing-test-dependency "Support for org-protocol"))
  19. (ert-deftest test-org-protocol/org-protocol-parse-parameters ()
  20. "Test `org-protocol-parse-parameters' specifications."
  21. ;; Ignore lists
  22. (let ((data (org-protocol-parse-parameters '(:url "abc" :title "def") nil)))
  23. (should (string= (plist-get data :url) "abc"))
  24. (should (string= (plist-get data :title) "def")))
  25. ;; Parse new-style links
  26. (let ((data (org-protocol-parse-parameters "url=abc&title=def" t)))
  27. (should (string= (plist-get data :url) "abc"))
  28. (should (string= (plist-get data :title) "def")))
  29. ;; Parse new-style complex links
  30. (let* ((url (concat "template=p&"
  31. "url=https%3A%2F%2Forgmode.org%2Forg.html%23capture-protocol&"
  32. "title=The%20Org%20Manual&"
  33. "body=9.4.2%20capture%20protocol"))
  34. (data (org-protocol-parse-parameters url t)))
  35. (should (string= (plist-get data :template) "p"))
  36. (should (string= (plist-get data :url) "https://orgmode.org/org.html#capture-protocol"))
  37. (should (string= (plist-get data :title) "The Org Manual"))
  38. (should (string= (plist-get data :body) "9.4.2 capture protocol")))
  39. ;; Parse old-style links
  40. (let ((data (org-protocol-parse-parameters "abc/def" nil '(:url :title))))
  41. (should (string= (plist-get data :url) "abc"))
  42. (should (string= (plist-get data :title) "def")))
  43. ;; Parse old-style links even without keys
  44. (let ((data (org-protocol-parse-parameters "b/abc/def" nil)))
  45. (should (equal data '("b" "abc" "def"))))
  46. ;; Parse old-style links with key/val pairs
  47. (let ((data (org-protocol-parse-parameters "b/abc/extrakey/extraval" nil '(:param1 :param2))))
  48. (should (string= (plist-get data :param1) "b"))
  49. (should (string= (plist-get data :param2) "abc"))
  50. (should (string= (plist-get data :extrakey) "extraval"))))
  51. (ert-deftest test-org-protocol/org-protocol-store-link ()
  52. "Test `org-protocol-store-link' specifications."
  53. ;; Old link style
  54. (let ((uri "/some/directory/org-protocol:/store-link:/URL/TITLE"))
  55. (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
  56. (should (equal (car org-stored-links) '("URL" "TITLE"))))
  57. ;; URL encoded
  58. (let ((uri (format "/some/directory/org-protocol:/store-link:/%s/TITLE"
  59. (url-hexify-string "http://example.com"))))
  60. (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
  61. (should (equal (car org-stored-links) '("http://example.com" "TITLE"))))
  62. ;; Handle multiple slashes, old link style
  63. (let ((uri "/some/directory/org-protocol://store-link://URL2//TITLE2"))
  64. (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
  65. (should (equal (car org-stored-links) '("URL2" "TITLE2"))))
  66. ;; New link style
  67. (let ((uri "/some/directory/org-protocol://store-link?url=URL3&title=TITLE3"))
  68. (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
  69. (should (equal (car org-stored-links) '("URL3" "TITLE3")))))
  70. (ert-deftest test-org-protocol/org-protocol-store-link-file ()
  71. "store-link: `org-protocol-sanitize-uri' could distort URL."
  72. :expected-result :failed
  73. (let ((uri "/org-protocol:/store-link:/file%3A%2F%2F%2Fetc%2Fmailcap/Triple%20Slash"))
  74. (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
  75. (should (equal (car org-stored-links) '("file:///etc/mailcap" "Triple Slash"))))
  76. (let ((uri "/org-protocol:/store-link?url=file%3A%2F%2F%2Fetc%2Fmailcap&title=Triple%20Slash"))
  77. (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
  78. (should (equal (car org-stored-links) '("file:///etc/mailcap" "Triple Slash")))))
  79. (ert-deftest test-org-protocol/org-protocol-capture ()
  80. "Test `org-protocol-capture' specifications."
  81. (let* ((org-protocol-default-template-key "t")
  82. (temp-file-name (make-temp-file "org-protocol-test"))
  83. (org-capture-templates
  84. `(("t" "Test" entry (file ,temp-file-name) "** TODO\n\n%i\n\n%a\n" :kill-buffer t)
  85. ("x" "With params" entry (file ,temp-file-name) "** SOMEDAY\n\n%i\n\n%a\n" :kill-buffer t)
  86. ("X" "Just the template" entry (file ,temp-file-name) "** Hello World\n\n%i\n\nGoodbye World\n" :kill-buffer t)))
  87. (test-urls
  88. '(
  89. ;; Old style:
  90. ;; - multiple slashes
  91. ("/some/directory/org-protocol:/capture:/URL/TITLE"
  92. . "** TODO\n\n\n\n[[URL][TITLE]]\n")
  93. ;; - body specification
  94. ("/some/directory/org-protocol:/capture:/URL/TITLE/BODY"
  95. . "** TODO\n\nBODY\n\n[[URL][TITLE]]\n")
  96. ;; - template
  97. ("/some/directory/org-protocol:/capture:/x/URL/TITLE/BODY"
  98. . "** SOMEDAY\n\nBODY\n\n[[URL][TITLE]]\n")
  99. ;; - query parameters, not sure how to include them in template
  100. ("/some/directory/org-protocol:/capture:/x/URL/TITLE/BODY/from/example"
  101. . "** SOMEDAY\n\nBODY\n\n[[URL][TITLE]]\n")
  102. ;; New style:
  103. ;; - multiple slashes
  104. ("/some/directory/org-protocol:/capture?url=NEWURL&title=TITLE"
  105. . "** TODO\n\n\n\n[[NEWURL][TITLE]]\n")
  106. ;; - body specification
  107. ("/some/directory/org-protocol:/capture?url=NEWURL&title=TITLE&body=BODY"
  108. . "** TODO\n\nBODY\n\n[[NEWURL][TITLE]]\n")
  109. ;; - template
  110. ("/some/directory/org-protocol:/capture?template=x&url=NEWURL&title=TITLE&body=BODY"
  111. . "** SOMEDAY\n\nBODY\n\n[[NEWURL][TITLE]]\n")
  112. ;; - no url specified
  113. ("/some/directory/org-protocol:/capture?template=x&title=TITLE&body=BODY"
  114. . "** SOMEDAY\n\nBODY\n\nTITLE\n")
  115. ;; - no title specified
  116. ("/some/directory/org-protocol:/capture?template=x&url=NEWURL&body=BODY"
  117. . "** SOMEDAY\n\nBODY\n\n[[NEWURL][NEWURL]]\n")
  118. ;; - just the template
  119. ("/some/directory/org-protocol:/capture?template=X"
  120. . "** Hello World\n\n\n\nGoodbye World\n")
  121. ;; - query parameters, not sure how to include them in template
  122. ("/some/directory/org-protocol:/capture?template=x&url=URL&title=TITLE&body=BODY&from=example"
  123. . "** SOMEDAY\n\nBODY\n\n[[URL][TITLE]]\n")
  124. )))
  125. ;; Old link style
  126. (mapc
  127. (lambda (test-case)
  128. (let ((uri (car test-case)))
  129. (org-protocol-check-filename-for-protocol uri (list uri) nil)
  130. (should (string= (buffer-string) (cdr test-case)))
  131. (org-capture-kill)))
  132. test-urls)
  133. (delete-file temp-file-name)))
  134. (ert-deftest test-org-protocol/org-protocol-capture-file ()
  135. "capture: `org-protocol-sanitize-uri' could distort URL."
  136. :expected-result :failed
  137. (let* ((org-protocol-default-template-key "t")
  138. (temp-file-name (make-temp-file "org-protocol-test"))
  139. (org-capture-templates
  140. `(("t" "Test" plain (file ,temp-file-name) "%a\n%i\n" :kill-buffer t))))
  141. (let ((uri "/org-protocol:/capture:/t/file%3A%2F%2F%2Fetc%2Fmailcap/Triple%20Slash/Body"))
  142. (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
  143. (should (string= (buffer-string) "[[file:///etc/mailcap][Triple Slash]]\nBody")))
  144. (let ((uri "/org-protocol:/capture?template=t&url=file%3A%2F%2F%2Fetc%2Fmailcap&title=Triple%20Slash&body=Body"))
  145. (should (null (org-protocol-check-filename-for-protocol uri (list uri) nil)))
  146. (should (string= (buffer-string) "[[file:///etc/mailcap][Triple Slash]]\nBody")))))
  147. (ert-deftest test-org-protocol/org-protocol-open-source ()
  148. "Test org-protocol://open-source links."
  149. (let* ((temp-file-name1 (make-temp-file "org-protocol-test1"))
  150. (temp-file-name2 (make-temp-file "org-protocol-test2"))
  151. (org-protocol-project-alist
  152. `((test1
  153. :base-url "http://example.com/"
  154. :online-suffix ".html"
  155. :working-directory ,(file-name-directory temp-file-name1))
  156. (test2
  157. :base-url "http://another.example.com/"
  158. :online-suffix ".js"
  159. :working-directory ,(file-name-directory temp-file-name2))
  160. (test3
  161. :base-url "https://blog-example.com/"
  162. :working-directory ,(file-name-directory temp-file-name2)
  163. :online-suffix ".html"
  164. :working-suffix ".md"
  165. :rewrites (("\\(https://blog-example.com/[0-9]+/[0-9]+/[0-9]+/\\)" . ".md")))))
  166. (test-cases
  167. (list
  168. ;; Old-style URLs
  169. (cons
  170. (concat "/some/directory/org-protocol:/open-source:/"
  171. (url-hexify-string
  172. (concat "http://example.com/" (file-name-nondirectory temp-file-name1) ".html")))
  173. temp-file-name1)
  174. (cons
  175. (concat "/some/directory/org-protocol:/open-source:/"
  176. (url-hexify-string
  177. (concat "http://another.example.com/" (file-name-nondirectory temp-file-name2) ".js")))
  178. temp-file-name2)
  179. ;; New-style URLs
  180. (cons
  181. (concat "/some/directory/org-protocol:/open-source?url="
  182. (url-hexify-string
  183. (concat "http://example.com/" (file-name-nondirectory temp-file-name1) ".html")))
  184. temp-file-name1)
  185. (cons
  186. (concat "/some/directory/org-protocol:/open-source?url="
  187. (url-hexify-string
  188. (concat "http://another.example.com/" (file-name-nondirectory temp-file-name2) ".js")))
  189. temp-file-name2))))
  190. (mapc (lambda (test-case)
  191. (should (string=
  192. (org-protocol-check-filename-for-protocol
  193. (car test-case)
  194. (list (car test-case)) nil)
  195. (cdr test-case))))
  196. test-cases)
  197. (delete-file temp-file-name1)
  198. (delete-file temp-file-name2)))
  199. (defun test-org-protocol/org-protocol-greedy-handler (fname)
  200. ;; fname should be a list of parsed items
  201. (should (listp fname))
  202. nil)
  203. (ert-deftest test-org-protocol/org-protocol-with-greedy-handler ()
  204. "Check that greedy handlers are called with all the filenames."
  205. (let ((org-protocol-protocol-alist
  206. '(("protocol-a" :protocol "greedy" :function test-org-protocol/org-protocol-greedy-handler :kill-client t :greedy t))))
  207. ;; Neither of these should signal errors
  208. (let ((uri "/some/dir/org-protocol://greedy?a=b&c=d")
  209. (uri2 "/some/dir/org-protocol://greedy?e=f&g=h"))
  210. (org-protocol-check-filename-for-protocol uri (list uri uri2) nil))))
  211. ;; TODO: Verify greedy protocol handling
  212. ;;; test-org-protocol.el ends here