Allow 'browse-url-emacs' to fetch URL in the selected window
[emacs.git] / test / lisp / auth-source-tests.el
blobeb93f7488e4c1b8f62a3c76c3a15ef26b524939d
1 ;;; auth-source-tests.el --- Tests for auth-source.el -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2015-2018 Free Software Foundation, Inc.
5 ;; Author: Damien Cassou <damien@cassou.me>,
6 ;; Nicolas Petton <nicolas@petton.fr>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
23 ;;; Commentary:
27 ;;; Code:
29 (require 'ert)
30 (require 'cl-lib)
31 (require 'auth-source)
33 (defvar secrets-enabled t
34 "Enable the secrets backend to test its features.")
36 (defun auth-source-ensure-ignored-backend (source)
37 (auth-source-validate-backend source '((:source . "")
38 (:type . ignore))))
40 (defun auth-source-validate-backend (source validation-alist)
41 (let ((backend (auth-source-backend-parse source)))
42 (should (auth-source-backend-p backend))
43 (dolist (pair validation-alist)
44 (should (equal (eieio-oref backend (car pair)) (cdr pair))))))
46 (ert-deftest auth-source-backend-parse-macos-keychain ()
47 (auth-source-validate-backend '(:source (:macos-keychain-generic foobar))
48 '((:source . "foobar")
49 (:type . macos-keychain-generic)
50 (:search-function . auth-source-macos-keychain-search)
51 (:create-function . auth-source-macos-keychain-create))))
53 (ert-deftest auth-source-backend-parse-macos-keychain-generic-string ()
54 (auth-source-validate-backend "macos-keychain-generic:foobar"
55 '((:source . "foobar")
56 (:type . macos-keychain-generic)
57 (:search-function . auth-source-macos-keychain-search)
58 (:create-function . auth-source-macos-keychain-create))))
60 (ert-deftest auth-source-backend-parse-macos-keychain-internet-string ()
61 (auth-source-validate-backend "macos-keychain-internet:foobar"
62 '((:source . "foobar")
63 (:type . macos-keychain-internet)
64 (:search-function . auth-source-macos-keychain-search)
65 (:create-function . auth-source-macos-keychain-create))))
67 (ert-deftest auth-source-backend-parse-macos-keychain-internet-symbol ()
68 (auth-source-validate-backend 'macos-keychain-internet
69 '((:source . "default")
70 (:type . macos-keychain-internet)
71 (:search-function . auth-source-macos-keychain-search)
72 (:create-function . auth-source-macos-keychain-create))))
74 (ert-deftest auth-source-backend-parse-macos-keychain-generic-symbol ()
75 (auth-source-validate-backend 'macos-keychain-generic
76 '((:source . "default")
77 (:type . macos-keychain-generic)
78 (:search-function . auth-source-macos-keychain-search)
79 (:create-function . auth-source-macos-keychain-create))))
81 (ert-deftest auth-source-backend-parse-macos-keychain-internet-default-string ()
82 (auth-source-validate-backend 'macos-keychain-internet
83 '((:source . "default")
84 (:type . macos-keychain-internet)
85 (:search-function . auth-source-macos-keychain-search)
86 (:create-function . auth-source-macos-keychain-create))))
88 (ert-deftest auth-source-backend-parse-plstore ()
89 (auth-source-validate-backend '(:source "foo.plist")
90 '((:source . "foo.plist")
91 (:type . plstore)
92 (:search-function . auth-source-plstore-search)
93 (:create-function . auth-source-plstore-create))))
95 (ert-deftest auth-source-backend-parse-netrc ()
96 (auth-source-validate-backend '(:source "foo")
97 '((:source . "foo")
98 (:type . netrc)
99 (:search-function . auth-source-netrc-search)
100 (:create-function . auth-source-netrc-create))))
102 (ert-deftest auth-source-backend-parse-netrc-string ()
103 (auth-source-validate-backend "foo"
104 '((:source . "foo")
105 (:type . netrc)
106 (:search-function . auth-source-netrc-search)
107 (:create-function . auth-source-netrc-create))))
109 (ert-deftest auth-source-backend-parse-secrets ()
110 (provide 'secrets) ; simulates the presence of the `secrets' package
111 (let ((secrets-enabled t))
112 (auth-source-validate-backend '(:source (:secrets "foo"))
113 '((:source . "foo")
114 (:type . secrets)
115 (:search-function . auth-source-secrets-search)
116 (:create-function . auth-source-secrets-create)))))
118 (ert-deftest auth-source-backend-parse-secrets-strings ()
119 (provide 'secrets) ; simulates the presence of the `secrets' package
120 (let ((secrets-enabled t))
121 (auth-source-validate-backend "secrets:foo"
122 '((:source . "foo")
123 (:type . secrets)
124 (:search-function . auth-source-secrets-search)
125 (:create-function . auth-source-secrets-create)))))
127 (ert-deftest auth-source-backend-parse-secrets-alias ()
128 (provide 'secrets) ; simulates the presence of the `secrets' package
129 (let ((secrets-enabled t))
130 ;; Redefine `secrets-get-alias' to map 'foo to "foo"
131 (cl-letf (((symbol-function 'secrets-get-alias) (lambda (_) "foo")))
132 (auth-source-validate-backend '(:source (:secrets foo))
133 '((:source . "foo")
134 (:type . secrets)
135 (:search-function . auth-source-secrets-search)
136 (:create-function . auth-source-secrets-create))))))
138 (ert-deftest auth-source-backend-parse-secrets-symbol ()
139 (provide 'secrets) ; simulates the presence of the `secrets' package
140 (let ((secrets-enabled t))
141 ;; Redefine `secrets-get-alias' to map 'default to "foo"
142 (cl-letf (((symbol-function 'secrets-get-alias) (lambda (_) "foo")))
143 (auth-source-validate-backend 'default
144 '((:source . "foo")
145 (:type . secrets)
146 (:search-function . auth-source-secrets-search)
147 (:create-function . auth-source-secrets-create))))))
149 (ert-deftest auth-source-backend-parse-secrets-no-alias ()
150 (provide 'secrets) ; simulates the presence of the `secrets' package
151 (let ((secrets-enabled t))
152 ;; Redefine `secrets-get-alias' to map 'foo to nil (so that
153 ;; "Login" is used by default
154 (cl-letf (((symbol-function 'secrets-get-alias) (lambda (_) nil)))
155 (auth-source-validate-backend '(:source (:secrets foo))
156 '((:source . "Login")
157 (:type . secrets)
158 (:search-function . auth-source-secrets-search)
159 (:create-function . auth-source-secrets-create))))))
161 (ert-deftest auth-source-backend-parse-invalid-or-nil-source ()
162 (provide 'secrets) ; simulates the presence of the `secrets' package
163 (let ((secrets-enabled t))
164 (auth-source-ensure-ignored-backend nil)
165 (auth-source-ensure-ignored-backend '(:source '(foo)))
166 (auth-source-ensure-ignored-backend '(:source nil))))
168 (defun auth-source--test-netrc-parse-entry (entry host user port)
169 "Parse a netrc entry from buffer."
170 (auth-source-forget-all-cached)
171 (setq port (auth-source-ensure-strings port))
172 (with-temp-buffer
173 (insert entry)
174 (goto-char (point-min))
175 (let* ((check (lambda(alist)
176 (and alist
177 (auth-source-search-collection
178 host
180 (auth-source--aget alist "machine")
181 (auth-source--aget alist "host")
183 (auth-source-search-collection
184 user
186 (auth-source--aget alist "login")
187 (auth-source--aget alist "account")
188 (auth-source--aget alist "user")
190 (auth-source-search-collection
191 port
193 (auth-source--aget alist "port")
194 (auth-source--aget alist "protocol")
195 t)))))
196 (entries (auth-source-netrc-parse-entries check 1)))
197 entries)))
199 (ert-deftest auth-source-test-netrc-parse-entry ()
200 (should (equal (auth-source--test-netrc-parse-entry
201 "machine mymachine1 login user1 password pass1\n" t t t)
202 '((("password" . "pass1")
203 ("login" . "user1")
204 ("machine" . "mymachine1")))))
205 (should (equal (auth-source--test-netrc-parse-entry
206 "machine mymachine1 login user1 password pass1 port 100\n"
207 t t t)
208 '((("port" . "100")
209 ("password" . "pass1")
210 ("login" . "user1")
211 ("machine" . "mymachine1"))))))
213 (ert-deftest auth-source-test-format-prompt ()
214 (should (equal (auth-source-format-prompt "test %u %h %p" '((?u "user") (?h "host")))
215 "test user host %p")))
217 (ert-deftest auth-source-test-remembrances-of-things-past ()
218 (let ((password-cache t)
219 (password-data (copy-hash-table password-data)))
220 (auth-source-remember '(:host "wedd") '(4 5 6))
221 (should (auth-source-remembered-p '(:host "wedd")))
222 (should-not (auth-source-remembered-p '(:host "xedd")))
223 (auth-source-remember '(:host "xedd") '(1 2 3))
224 (should (auth-source-remembered-p '(:host "xedd")))
225 (should-not (auth-source-remembered-p '(:host "zedd")))
226 (should (auth-source-recall '(:host "xedd")))
227 (should-not (auth-source-recall nil))
228 (auth-source-forget+ :host t)
229 (should-not (auth-source-remembered-p '(:host "xedd")))
230 (should-not (auth-source-remembered-p '(:host t)))))
232 (ert-deftest auth-source-test-searches ()
233 "Test auth-source searches with various parameters"
234 :tags '(auth-source auth-source/netrc)
235 (let* ((entries '("machine a1 port a2 user a3 password a4"
236 "machine b1 port b2 user b3 password b4"
237 "machine c1 port c2 user c3 password c4"))
238 ;; First element: test description.
239 ;; Second element: expected return data, serialized to a string.
240 ;; Rest of elements: the parameters for `auth-source-search'.
241 (tests '(("any host, max 1"
242 "((:host \"a1\" :port \"a2\" :user \"a3\" :secret \"a4\"))"
243 :max 1 :host t)
244 ("any host, default max is 1"
245 "((:host \"a1\" :port \"a2\" :user \"a3\" :secret \"a4\"))"
246 :host t)
247 ("any host, boolean return"
249 :host t :max 0)
250 ("no parameters, default max is 1"
251 "((:host \"a1\" :port \"a2\" :user \"a3\" :secret \"a4\"))"
253 ("host c1, default max is 1"
254 "((:host \"c1\" :port \"c2\" :user \"c3\" :secret \"c4\"))"
255 :host "c1")
256 ("host list of (c1), default max is 1"
257 "((:host \"c1\" :port \"c2\" :user \"c3\" :secret \"c4\"))"
258 :host ("c1"))
259 ("any host, max 4"
260 "((:host \"a1\" :port \"a2\" :user \"a3\" :secret \"a4\") (:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\") (:host \"c1\" :port \"c2\" :user \"c3\" :secret \"c4\"))"
261 :host t :max 4)
262 ("host b1, default max is 1"
263 "((:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\"))"
264 :host "b1")
265 ("host b1, port b2, user b3, default max is 1"
266 "((:host \"b1\" :port \"b2\" :user \"b3\" :secret \"b4\"))"
267 :host "b1" :port "b2" :user "b3")
270 (netrc-file (make-temp-file "auth-source-test" nil nil
271 (mapconcat 'identity entries "\n")))
272 (auth-sources (list netrc-file))
273 (auth-source-do-cache nil)
274 found found-as-string)
276 (dolist (test tests)
277 (cl-destructuring-bind (testname needed &rest parameters) test
278 (setq found (apply #'auth-source-search parameters))
279 (when (listp found)
280 (dolist (f found)
281 (setf f (plist-put f :secret
282 (let ((secret (plist-get f :secret)))
283 (if (functionp secret)
284 (funcall secret)
285 secret))))))
287 (setq found-as-string (format "%s: %S" testname found))
288 ;; (message "With parameters %S found: [%s] needed: [%s]" parameters found-as-string needed)
289 (should (equal found-as-string (concat testname ": " needed)))))
290 (delete-file netrc-file)))
292 (provide 'auth-source-tests)
293 ;;; auth-source-tests.el ends here