FlaskTester 1.4__tar.gz → 2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FlaskTester
3
- Version: 1.4
3
+ Version: 2.0
4
4
  Summary: Pytest fixtures for Flask internal and external authenticated tests
5
5
  Author-email: Fabien Coelho <flask.tester@coelho.net>
6
6
  License: CC0
@@ -32,7 +32,7 @@ Requires-Dist: twine; extra == "dev"
32
32
  Requires-Dist: wheel; extra == "dev"
33
33
  Requires-Dist: types-flask; extra == "dev"
34
34
  Requires-Dist: types-requests; extra == "dev"
35
- Requires-Dist: FlaskSimpleAuth; extra == "dev"
35
+ Requires-Dist: FlaskSimpleAuth>=29.4; extra == "dev"
36
36
  Requires-Dist: passlib; extra == "dev"
37
37
  Provides-Extra: doc
38
38
  Requires-Dist: sphinx; extra == "doc"
@@ -86,6 +86,9 @@ def app(ft_client):
86
86
  res = ft_client.post("/login", login="hobbes", auth="param", status=201)
87
87
  assert res.is_json
88
88
  ft_client.setToken("hobbes", res.json["token"])
89
+ # also set a cookie
90
+ ft_client.setCookie("hobbes", "lang", "fr_FR")
91
+ ft_client.setCookie("calvin", "lang", "en_EN")
89
92
  # return working client
90
93
  yield ft_client
91
94
 
@@ -155,6 +158,7 @@ The package provides two fixtures:
155
158
  The fixture has 3 main methods:
156
159
  - `setPass` to associate a password to a user, set to _None_ to remove credential.
157
160
  - `setToken` to associate a token to a user, set to _None_ to remove credential.
161
+ - `setCookie` to add a cookie to a user, set value to _None_ to remove cookie.
158
162
  - `setAuth` to add authentication data to a request `kwargs`.
159
163
 
160
164
  - `ft_client` for app testing, which depends on the previous fixture, plus
@@ -175,7 +179,7 @@ The package provides two fixtures:
175
179
  The fixture then provides test methods to issue test requests against a Flask application:
176
180
  - `request` generic request with `login`, `auth`, `status` end `content` extensions.
177
181
  - `get post put patch delete` methods with `login`, `auth` and `status` extensions.
178
- Moreover, `setPass` and `setToken` are forwarded to the internal authenticator.
182
+ Moreover, `setPass`, `setToken` and `setCookie` are forwarded to the internal authenticator.
179
183
 
180
184
  Authenticator environment variables can be set from the pytest Python test file by
181
185
  assigning them through `os.environ`.
@@ -238,6 +242,12 @@ Packages are distributed from [PyPI](https://pypi.org/project/FlaskTester/),
238
242
  see also the [documentation](https://zx80.github.io/flask-tester/),
239
243
  please report any [issues](https://github.com/zx80/flask-tester/issues).
240
244
 
245
+ ### 2.0 on 2024-03-23
246
+
247
+ Add support for cookies.
248
+ Improved documentation and code.
249
+ Improved tests.
250
+
241
251
  ### 1.4 on 2024-03-19
242
252
 
243
253
  Test expected assert failures.
@@ -13,7 +13,7 @@ twine
13
13
  wheel
14
14
  types-flask
15
15
  types-requests
16
- FlaskSimpleAuth
16
+ FlaskSimpleAuth>=29.4
17
17
  passlib
18
18
 
19
19
  [doc]
@@ -60,6 +60,7 @@ class Authenticator:
60
60
  _TOKEN_SCHEMES = {"bearer", "header", "cookie", "tparam"}
61
61
  _PASS_SCHEMES = {"basic", "param"}
62
62
 
63
+ # all supported authentication schemes
63
64
  _AUTH_SCHEMES = {"fake"}
64
65
  _AUTH_SCHEMES.update(_TOKEN_SCHEMES)
65
66
  _AUTH_SCHEMES.update(_PASS_SCHEMES)
@@ -96,21 +97,25 @@ class Authenticator:
96
97
  self._cookie = cookie
97
98
  self._tparam = tparam
98
99
 
99
- # password and token credentials
100
+ # password and token credentials, cookies
100
101
  self._passes: dict[str, str] = {}
101
102
  self._tokens: dict[str, str] = {}
103
+ self._cookies: dict[str, dict[str, str]] = {}
102
104
 
103
- def _set(self, login: str, val: str|None, store: dict[str, str]):
105
+ def _set(self, key: str, val: str|None, store: dict[str, str]):
104
106
  """Set a key/value in a directory, with None for delete."""
105
107
  if val is None:
106
- if login in store:
107
- del store[login]
108
+ if key in store:
109
+ del store[key]
108
110
  else:
109
111
  assert isinstance(val, str)
110
- store[login] = val
112
+ store[key] = val
111
113
 
112
114
  def setPass(self, login: str, pw: str|None):
113
- """Associate a password to a user."""
115
+ """Associate a password to a user.
116
+
117
+ Set to *None* to remove the password entry.
118
+ """
114
119
  if not self._has_pass:
115
120
  raise AuthError("cannot set password, no password scheme allowed")
116
121
  self._set(login, pw, self._passes)
@@ -122,11 +127,20 @@ class Authenticator:
122
127
  self.setPass(login, pw)
123
128
 
124
129
  def setToken(self, login: str, token: str|None):
125
- """Associate a token to a user."""
130
+ """Associate a token to a user.
131
+
132
+ Set to *None* to remove the token entry.
133
+ """
126
134
  if not self._has_token:
127
135
  raise AuthError("cannot set token, no token scheme allowed")
128
136
  self._set(login, token, self._tokens)
129
137
 
138
+ def setCookie(self, login: str, name: str, val: str|None = None):
139
+ """Associate a cookie and its value to a login, *None* to remove."""
140
+ if login not in self._cookies:
141
+ self._cookies[login] = {}
142
+ self._set(name, val, self._cookies[login])
143
+
130
144
  def _param(self, kwargs: dict[str, Any], key: str, val: Any):
131
145
  """Add request parameter to "json" or "data"."""
132
146
 
@@ -143,12 +157,16 @@ class Authenticator:
143
157
  """Whether to try this authentication scheme."""
144
158
  return auth in (None, scheme) and scheme in self._allow
145
159
 
146
- def setAuth(self, login: str|None, kwargs: dict[str, Any], auth: str|None = None):
160
+ def setAuth(self, login: str|None, kwargs: dict[str, Any], cookies: dict[str, str], auth: str|None = None):
147
161
  """Set request authentication.
148
162
 
149
163
  - login: login target, None means no authentication
150
164
  - kwargs: request parameters
151
- - auth: authentication method, default None is to try allowed schemes, tokens first.
165
+ - cookies: request cookies
166
+ - auth: authentication method, default is None
167
+
168
+ The default behavior is to try allowed schemes: tokens first,
169
+ then password, then fake.
152
170
  """
153
171
 
154
172
  log.debug(f"setAuth: login={login} auth={auth} allow={self._allow}")
@@ -156,29 +174,29 @@ class Authenticator:
156
174
  if login is None: # not needed
157
175
  return
158
176
 
177
+ cookies.update(self._cookies.get(login, {}))
178
+
159
179
  if auth is not None:
160
180
  if auth not in self._AUTH_SCHEMES:
161
181
  raise AuthError(f"unexpected auth: {auth}")
162
182
  if auth not in self._allow:
163
183
  raise AuthError(f"auth is not allowed: {auth}")
164
184
 
185
+ headers = kwargs.get("headers", {})
186
+
165
187
  # use token if available and allowed
166
188
  if login in self._tokens and auth in (None, "bearer", "header", "cookie", "tparam"):
167
189
 
168
190
  token = self._tokens[login]
169
191
 
170
- if "headers" not in kwargs:
171
- kwargs["headers"] = {}
172
-
173
192
  if self._try_auth(auth, "bearer"):
174
- kwargs["headers"]["Authorization"] = self._bearer + " " + token
193
+ headers["Authorization"] = self._bearer + " " + token
175
194
  elif self._try_auth(auth, "header"):
176
- kwargs["headers"][self._header] = token
195
+ headers[self._header] = token
177
196
  elif self._try_auth(auth, "tparam"):
178
197
  self._param(kwargs, self._tparam, token)
179
198
  elif self._try_auth(auth, "cookie"):
180
- # FIXME cookie?
181
- kwargs["headers"]["Cookie"] = self._cookie + "=" + token
199
+ cookies[self._cookie] = token
182
200
  else:
183
201
  raise AuthError(f"no token carrier: login={login} auth={auth} allow={self._allow}")
184
202
 
@@ -200,6 +218,9 @@ class Authenticator:
200
218
 
201
219
  raise AuthError(f"no authentication for login={login} auth={auth} allow={self._allow}")
202
220
 
221
+ if headers: # put headers back if needed
222
+ kwargs["headers"] = headers
223
+
203
224
 
204
225
  class RequestFlaskResponse:
205
226
  """Wrapper to return a Flask-looking response from a request response.
@@ -238,16 +259,17 @@ class RequestFlaskResponse:
238
259
 
239
260
 
240
261
  class Client:
241
- """Common class for flask authenticated testing.
262
+ """Common (partial) class for flask authenticated testing.
242
263
 
243
264
  Constructor parameters:
244
265
 
245
266
  - ``auth`` authenticator
246
- - ``default_login`` if not ``login`` is set.
267
+ - ``default_login`` if ``login`` is not set.
247
268
  """
248
269
 
249
270
  def __init__(self, auth: Authenticator, default_login: str|None = None):
250
271
  self._auth = auth
272
+ self._cookies: dict[str, dict[str, str]] = {} # login -> name -> value
251
273
  self._default_login = default_login
252
274
 
253
275
  def setToken(self, login: str, token: str|None):
@@ -258,7 +280,11 @@ class Client:
258
280
  """Associate a password to a login, *None* to remove."""
259
281
  self._auth.setPass(login, password)
260
282
 
261
- def _request(self, method: str, path: str, **kwargs):
283
+ def setCookie(self, login: str, name: str, val: str|None):
284
+ """Associate a cookie to a login, *None* name to remove."""
285
+ self._auth.setCookie(login, name, val)
286
+
287
+ def _request(self, method: str, path: str, cookies: dict[str, str], **kwargs):
262
288
  """Run a request and return response."""
263
289
  raise NotImplementedError()
264
290
 
@@ -274,7 +300,7 @@ class Client:
274
300
 
275
301
  - ``status``: expected HTTP status, *None* to skip status check
276
302
  - ``login``: authenticated user, use **explicit** *None* to skip
277
- - ``auth``: authentication scheme to use
303
+ - ``auth``: authentication scheme to use instead of default behavior
278
304
  - ``**kwargs``: more request parameters (headers, data, json…)
279
305
  """
280
306
 
@@ -284,8 +310,13 @@ class Client:
284
310
  else: # if unset, use default
285
311
  login = self._default_login
286
312
 
287
- self._auth.setAuth(login, kwargs, auth=auth)
288
- res = self._request(method, path, **kwargs) # type: ignore
313
+ cookies: dict[str, str] = {}
314
+ if "cookies" in kwargs:
315
+ cookies.update(kwargs["cookies"])
316
+ del kwargs["cookies"]
317
+
318
+ self._auth.setAuth(login, kwargs, cookies, auth=auth)
319
+ res = self._request(method, path, cookies, **kwargs) # type: ignore
289
320
 
290
321
  if status is not None:
291
322
  if res.status_code != status: # show error before aborting
@@ -349,7 +380,7 @@ class RequestClient(Client):
349
380
 
350
381
  - ``auth`` authenticator
351
382
  - ``base_url`` target server
352
- - ``default_login`` if not ``login`` is set.
383
+ - ``default_login`` if ``login`` is not set.
353
384
  """
354
385
 
355
386
  def __init__(self, auth: Authenticator, base_url: str, default_login=None):
@@ -359,7 +390,7 @@ class RequestClient(Client):
359
390
  from requests import Session
360
391
  self._requests = Session()
361
392
 
362
- def _request(self, method: str, path: str, **kwargs):
393
+ def _request(self, method: str, path: str, cookies: dict[str, str], **kwargs):
363
394
  """Actual request handling."""
364
395
 
365
396
  if "data" in kwargs:
@@ -383,7 +414,7 @@ class RequestClient(Client):
383
414
  # sanity
384
415
  assert not (files and "json" in kwargs), "cannot mix file upload and json?"
385
416
 
386
- res = self._requests.request(method, self._base_url + path, **kwargs)
417
+ res = self._requests.request(method, self._base_url + path, cookies=cookies, **kwargs)
387
418
 
388
419
  return RequestFlaskResponse(res)
389
420
 
@@ -394,16 +425,29 @@ class FlaskClient(Client):
394
425
  Constructor parameters:
395
426
 
396
427
  - ``auth`` authenticator
397
- - ``client`` Flask ``test_client``
398
- - ``default_login`` if not ``login`` is set.
428
+ - ``client`` Flask actual ``test_client``
429
+ - ``default_login`` if ``login`` is not set.
430
+
431
+ Note: this client handles `cookies`.
399
432
  """
400
433
 
401
434
  def __init__(self, auth: Authenticator, client, default_login=None):
402
435
  super().__init__(auth, default_login)
403
436
  self._client = client
437
+ self._cookie_names: set[str] = set() # FIXME all encountered cookies for cleanup :-/
404
438
 
405
- def _request(self, method: str, path: str, **kwargs):
439
+ def _request(self, method: str, path: str, cookies: dict[str, str], **kwargs):
406
440
  """Actual request handling."""
441
+
442
+ # hack to cleanup client state :-/
443
+ for cookie in self._cookie_names:
444
+ self._client.delete_cookie(cookie)
445
+
446
+ for cookie, val in cookies.items():
447
+ if cookie not in self._cookie_names:
448
+ self._cookie_names.add(cookie)
449
+ self._client.set_cookie(cookie, val)
450
+
407
451
  return self._client.open(method=method, path=path, **kwargs)
408
452
 
409
453
 
@@ -415,6 +459,7 @@ def ft_authenticator():
415
459
 
416
460
  - ``FLASK_TESTER_LOG_LEVEL``: package log level in
417
461
  ``DEBUG INFO WARNING ERROR CRITICAL NOSET``.
462
+ Default is ``NOTSET``.
418
463
  - ``FLASK_TESTER_ALLOW``: allowed space-separated authentication schemes, in
419
464
  ``basic param bearer header cookie tparam fake``.
420
465
  Default is ``bearer basic param``.
@@ -433,6 +478,7 @@ def ft_authenticator():
433
478
  - ``FLASK_TESTER_TPARAM``: parameter for *token* authentication.
434
479
  Default is ``AUTH``.
435
480
  - ``FLASK_TESTER_AUTH``: initial comma-separated list of *login:password*.
481
+ Default is not set.
436
482
  """
437
483
 
438
484
  level = os.environ.get("FLASK_TESTER_LOG_LEVEL", "NOTSET")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: FlaskTester
3
- Version: 1.4
3
+ Version: 2.0
4
4
  Summary: Pytest fixtures for Flask internal and external authenticated tests
5
5
  Author-email: Fabien Coelho <flask.tester@coelho.net>
6
6
  License: CC0
@@ -32,7 +32,7 @@ Requires-Dist: twine; extra == "dev"
32
32
  Requires-Dist: wheel; extra == "dev"
33
33
  Requires-Dist: types-flask; extra == "dev"
34
34
  Requires-Dist: types-requests; extra == "dev"
35
- Requires-Dist: FlaskSimpleAuth; extra == "dev"
35
+ Requires-Dist: FlaskSimpleAuth>=29.4; extra == "dev"
36
36
  Requires-Dist: passlib; extra == "dev"
37
37
  Provides-Extra: doc
38
38
  Requires-Dist: sphinx; extra == "doc"
@@ -86,6 +86,9 @@ def app(ft_client):
86
86
  res = ft_client.post("/login", login="hobbes", auth="param", status=201)
87
87
  assert res.is_json
88
88
  ft_client.setToken("hobbes", res.json["token"])
89
+ # also set a cookie
90
+ ft_client.setCookie("hobbes", "lang", "fr_FR")
91
+ ft_client.setCookie("calvin", "lang", "en_EN")
89
92
  # return working client
90
93
  yield ft_client
91
94
 
@@ -155,6 +158,7 @@ The package provides two fixtures:
155
158
  The fixture has 3 main methods:
156
159
  - `setPass` to associate a password to a user, set to _None_ to remove credential.
157
160
  - `setToken` to associate a token to a user, set to _None_ to remove credential.
161
+ - `setCookie` to add a cookie to a user, set value to _None_ to remove cookie.
158
162
  - `setAuth` to add authentication data to a request `kwargs`.
159
163
 
160
164
  - `ft_client` for app testing, which depends on the previous fixture, plus
@@ -175,7 +179,7 @@ The package provides two fixtures:
175
179
  The fixture then provides test methods to issue test requests against a Flask application:
176
180
  - `request` generic request with `login`, `auth`, `status` end `content` extensions.
177
181
  - `get post put patch delete` methods with `login`, `auth` and `status` extensions.
178
- Moreover, `setPass` and `setToken` are forwarded to the internal authenticator.
182
+ Moreover, `setPass`, `setToken` and `setCookie` are forwarded to the internal authenticator.
179
183
 
180
184
  Authenticator environment variables can be set from the pytest Python test file by
181
185
  assigning them through `os.environ`.
@@ -238,6 +242,12 @@ Packages are distributed from [PyPI](https://pypi.org/project/FlaskTester/),
238
242
  see also the [documentation](https://zx80.github.io/flask-tester/),
239
243
  please report any [issues](https://github.com/zx80/flask-tester/issues).
240
244
 
245
+ ### 2.0 on 2024-03-23
246
+
247
+ Add support for cookies.
248
+ Improved documentation and code.
249
+ Improved tests.
250
+
241
251
  ### 1.4 on 2024-03-19
242
252
 
243
253
  Test expected assert failures.
@@ -43,6 +43,9 @@ def app(ft_client):
43
43
  res = ft_client.post("/login", login="hobbes", auth="param", status=201)
44
44
  assert res.is_json
45
45
  ft_client.setToken("hobbes", res.json["token"])
46
+ # also set a cookie
47
+ ft_client.setCookie("hobbes", "lang", "fr_FR")
48
+ ft_client.setCookie("calvin", "lang", "en_EN")
46
49
  # return working client
47
50
  yield ft_client
48
51
 
@@ -112,6 +115,7 @@ The package provides two fixtures:
112
115
  The fixture has 3 main methods:
113
116
  - `setPass` to associate a password to a user, set to _None_ to remove credential.
114
117
  - `setToken` to associate a token to a user, set to _None_ to remove credential.
118
+ - `setCookie` to add a cookie to a user, set value to _None_ to remove cookie.
115
119
  - `setAuth` to add authentication data to a request `kwargs`.
116
120
 
117
121
  - `ft_client` for app testing, which depends on the previous fixture, plus
@@ -132,7 +136,7 @@ The package provides two fixtures:
132
136
  The fixture then provides test methods to issue test requests against a Flask application:
133
137
  - `request` generic request with `login`, `auth`, `status` end `content` extensions.
134
138
  - `get post put patch delete` methods with `login`, `auth` and `status` extensions.
135
- Moreover, `setPass` and `setToken` are forwarded to the internal authenticator.
139
+ Moreover, `setPass`, `setToken` and `setCookie` are forwarded to the internal authenticator.
136
140
 
137
141
  Authenticator environment variables can be set from the pytest Python test file by
138
142
  assigning them through `os.environ`.
@@ -195,6 +199,12 @@ Packages are distributed from [PyPI](https://pypi.org/project/FlaskTester/),
195
199
  see also the [documentation](https://zx80.github.io/flask-tester/),
196
200
  please report any [issues](https://github.com/zx80/flask-tester/issues).
197
201
 
202
+ ### 2.0 on 2024-03-23
203
+
204
+ Add support for cookies.
205
+ Improved documentation and code.
206
+ Improved tests.
207
+
198
208
  ### 1.4 on 2024-03-19
199
209
 
200
210
  Test expected assert failures.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "FlaskTester"
7
- version = "1.4"
7
+ version = "2.0"
8
8
  authors = [ { name = "Fabien Coelho", email = "flask.tester@coelho.net" } ]
9
9
  description = "Pytest fixtures for Flask internal and external authenticated tests"
10
10
  readme = "README.md"
@@ -33,7 +33,7 @@ package = "https://pypi.org/project/FlaskTester/"
33
33
 
34
34
  [project.optional-dependencies]
35
35
  # various dev tools
36
- dev = ["mypy", "pyright", "ruff", "coverage", "pymarkdownlnt!=0.9.5", "build", "twine", "wheel", "types-flask", "types-requests", "FlaskSimpleAuth", "passlib"]
36
+ dev = ["mypy", "pyright", "ruff", "coverage", "pymarkdownlnt!=0.9.5", "build", "twine", "wheel", "types-flask", "types-requests", "FlaskSimpleAuth>=29.4", "passlib"]
37
37
  # documentation generation
38
38
  doc = ["sphinx", "sphinx_rtd_theme", "sphinx-autoapi", "sphinx-lint", "myst_parser"]
39
39
 
@@ -10,6 +10,8 @@ import io
10
10
  import logging
11
11
 
12
12
  logging.basicConfig(level=logging.INFO)
13
+ # logging.basicConfig(level=logging.DEBUG)
14
+ # log = logging.getLogger("test")
13
15
 
14
16
  # set authn for ft_authenticator
15
17
  os.environ.update(
@@ -20,6 +22,7 @@ os.environ.update(
20
22
  def test_sanity():
21
23
  # must provide url or package of Flask application to test
22
24
  assert "FLASK_TESTER_URL" in os.environ or "FLASK_TESTER_APP" in os.environ
25
+ # log.debug(f"TEST_SEED={os.environ.get('TEST_SEED')}")
23
26
 
24
27
  # example from README.md
25
28
  @pytest.fixture
@@ -34,6 +37,9 @@ def app(ft_client):
34
37
  res = ft_client.post("/login", login="hobbes", auth="param", status=201)
35
38
  assert res.is_json
36
39
  ft_client.setToken("hobbes", res.json["token"])
40
+ # also set a cookie
41
+ ft_client.setCookie("hobbes", "lang", "fr_FR")
42
+ ft_client.setCookie("calvin", "lang", "en_EN")
37
43
  # return working client
38
44
  yield ft_client
39
45
 
@@ -59,6 +65,9 @@ def api(ft_client):
59
65
  ft_client.setToken("moe", None)
60
66
  ft_client.setPass("moe", "bad password")
61
67
  ft_client.setToken("moe", "bad token")
68
+ # cookies
69
+ ft_client.setCookie("calvin", "lang", "en_EN")
70
+ ft_client.setCookie("hobbes", "lang", "fr_FR")
62
71
  # get valid tokens using password authn
63
72
  res = ft_client.get("/login", login="calvin", auth="basic", status=200)
64
73
  assert res.json["user"] == "calvin"
@@ -69,13 +78,13 @@ def api(ft_client):
69
78
  res = ft_client.post("/login", login="susie", auth="param", status=201, json={})
70
79
  assert res.json["user"] == "susie"
71
80
  ft_client._auth.setToken("susie", res.json["token"])
72
- # check that token auth is ok
81
+ # check that token auth and cookie is ok
73
82
  res = ft_client.get("/who-am-i", login="calvin", status=200, auth="bearer")
74
- assert res.json["user"] == "calvin"
83
+ assert res.json["user"] == "calvin" and res.json["lang"] == "en_EN"
75
84
  res = ft_client.get("/who-am-i", login="hobbes", status=200, auth="bearer")
76
- assert res.json["user"] == "hobbes"
85
+ assert res.json["user"] == "hobbes" and res.json["lang"] == "fr_FR"
77
86
  res = ft_client.get("/who-am-i", login="susie", status=200, auth="bearer")
78
- assert res.json["user"] == "susie"
87
+ assert res.json["user"] == "susie" and res.json["lang"] is None
79
88
  # with defaults
80
89
  res = ft_client.get("/who-am-i", auth="basic", status=200)
81
90
  assert res.json["user"] == "calvin"
@@ -116,7 +125,8 @@ def test_errors(api):
116
125
  assert True, "expected error"
117
126
 
118
127
  def test_methods(api):
119
- api.get("/who-am-i", login="hobbes", status=200)
128
+ res = api.get("/who-am-i", login="susie", status=200, cookies={"lang": "python"})
129
+ assert res.json["lang"] == "python"
120
130
  api.post("/who-am-i", login="hobbes", status=405)
121
131
  api.put("/who-am-i", login="hobbes", status=405)
122
132
  api.patch("/who-am-i", login="hobbes", status=405)
@@ -129,25 +139,31 @@ def test_authenticator_token():
129
139
  auth.setToken("susie", "ss-token")
130
140
  auth.setToken("hobbes", "hbs-token")
131
141
  auth.setToken("moe", "m-token")
132
- kwargs = {}
133
- auth.setAuth("calvin", kwargs, auth="bearer")
142
+ auth.setCookie("calvin", "what", "clv-cookie")
143
+ kwargs, cookies = {}, {}
144
+ auth.setAuth("calvin", kwargs, cookies, auth="bearer")
134
145
  assert kwargs["headers"]["Authorization"] == "Bearer clv-token"
135
- kwargs = {}
136
- auth.setAuth("susie", kwargs, auth="header")
146
+ assert cookies["what"] == "clv-cookie"
147
+ kwargs, cookies = {}, {}
148
+ auth.setAuth("susie", kwargs, cookies, auth="header")
137
149
  assert kwargs["headers"]["Auth"] == "ss-token"
138
- kwargs = {"data": {}}
139
- auth.setAuth("hobbes", kwargs, auth="tparam")
150
+ assert not cookies
151
+ kwargs, cookies = {"data": {}}, {}
152
+ auth.setAuth("hobbes", kwargs, cookies, auth="tparam")
140
153
  assert kwargs["data"]["AUTH"] == "hbs-token"
141
- kwargs = {"json": {}}
142
- auth.setAuth("hobbes", kwargs, auth="tparam")
154
+ assert not cookies
155
+ kwargs, cookies = {"json": {}}, {}
156
+ auth.setAuth("hobbes", kwargs, cookies, auth="tparam")
143
157
  assert kwargs["json"]["AUTH"] == "hbs-token"
144
- kwargs = {}
145
- auth.setAuth("moe", kwargs, auth="cookie")
146
- assert kwargs["headers"]["Cookie"] == "auth=m-token"
158
+ assert not cookies
159
+ kwargs, cookies = {}, {}
160
+ auth.setAuth("moe", kwargs, cookies, auth="cookie")
161
+ assert not kwargs
162
+ assert cookies["auth"] == "m-token"
147
163
  # dad does not have a token
148
164
  try:
149
- kwargs = {}
150
- auth.setAuth("dad", kwargs)
165
+ kwargs, cookies = {}, {}
166
+ auth.setAuth("dad", kwargs, cookies)
151
167
  pytest.fail("must raise an error") # pragma: no cover
152
168
  except ft.FlaskTesterError:
153
169
  assert True, "error raised"
@@ -161,8 +177,8 @@ def test_authenticator_token():
161
177
  auth._has_pass = True
162
178
  auth.setPass("rosalyn", "rsln-pass")
163
179
  try:
164
- kwargs={}
165
- auth.setAuth("rosalyn", kwargs)
180
+ kwargs, cookies = {}, {}
181
+ auth.setAuth("rosalyn", kwargs, cookies)
166
182
  pytest.fail("must raise an error") # pragma: no cover
167
183
  except ft.FlaskTesterError:
168
184
  assert True, "error raised"
@@ -174,21 +190,27 @@ def test_authenticator_password():
174
190
  auth.setPass("hobbes", "hbs-pass")
175
191
  auth.setPass("moe", "m-pass")
176
192
  auth.setPass("rosalyn", "rsln-pass")
177
- kwargs = {}
178
- auth.setAuth("calvin", kwargs, auth="basic")
193
+ auth.setCookie("moe", "hello", "world!")
194
+ kwargs, cookies = {}, {}
195
+ auth.setAuth("calvin", kwargs, cookies, auth="basic")
179
196
  assert kwargs["auth"] == ("calvin", "clv-pass")
180
- kwargs = {"data": {}}
181
- auth.setAuth("hobbes", kwargs, auth="param")
197
+ assert not cookies
198
+ kwargs, cookies = {"data": {}}, {}
199
+ auth.setAuth("hobbes", kwargs, cookies, auth="param")
182
200
  assert kwargs["data"]["USER"] == "hobbes" and kwargs["data"]["PASS"] == "hbs-pass"
183
- kwargs = {"json": {}}
184
- auth.setAuth("moe", kwargs, auth="param")
201
+ assert not cookies
202
+ kwargs, cookies = {"json": {}}, {}
203
+ auth.setAuth("moe", kwargs, cookies, auth="param")
185
204
  assert kwargs["json"]["USER"] == "moe" and kwargs["json"]["PASS"] == "m-pass"
186
- kwargs = {"data": {}}
187
- auth.setAuth("rosalyn", kwargs, auth="fake")
205
+ assert cookies["hello"] == "world!"
206
+ kwargs, cookies = {"data": {}}, {}
207
+ auth.setAuth("rosalyn", kwargs, cookies, auth="fake")
188
208
  assert kwargs["data"]["LOGIN"] == "rosalyn"
189
- kwargs = {"json": {}}
190
- auth.setAuth("hobbes", kwargs, auth="fake")
209
+ assert not cookies
210
+ kwargs, cookies = {"json": {}}, {}
211
+ auth.setAuth("hobbes", kwargs, cookies, auth="fake")
191
212
  assert kwargs["json"]["LOGIN"] == "hobbes"
213
+ assert not cookies
192
214
  # susie as a token, but no token carrier is allowed
193
215
  try:
194
216
  auth.setToken("susie", "ss-token")
@@ -199,8 +221,8 @@ def test_authenticator_password():
199
221
  auth._has_token = True
200
222
  auth.setToken("susie", "ss-token")
201
223
  try:
202
- kwargs={}
203
- auth.setAuth("susie", kwargs)
224
+ kwargs, cookies = {}, {}
225
+ auth.setAuth("susie", kwargs, cookies)
204
226
  pytest.fail("must raise an error") # pragma: no cover
205
227
  except ft.FlaskTesterError:
206
228
  assert True, "error raised"
@@ -233,7 +255,7 @@ def test_request_flask_response():
233
255
  def test_client():
234
256
  client = ft.Client(ft.Authenticator())
235
257
  try:
236
- client._request("GET", "/")
258
+ client._request("GET", "/", {})
237
259
  pytest.fail("must raise an error") # pragma: no cover
238
260
  except NotImplementedError:
239
261
  assert True, "expected error raised"
File without changes
File without changes
File without changes