FlaskTester 2.0__tar.gz → 3.1__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.
- {FlaskTester-2.0 → FlaskTester-3.1}/FlaskTester.egg-info/PKG-INFO +17 -7
- {FlaskTester-2.0 → FlaskTester-3.1}/FlaskTester.egg-info/requires.txt +1 -1
- {FlaskTester-2.0 → FlaskTester-3.1}/FlaskTester.py +64 -51
- {FlaskTester-2.0 → FlaskTester-3.1}/PKG-INFO +17 -7
- {FlaskTester-2.0 → FlaskTester-3.1}/README.md +15 -5
- {FlaskTester-2.0 → FlaskTester-3.1}/pyproject.toml +2 -2
- {FlaskTester-2.0 → FlaskTester-3.1}/tests/test.py +72 -9
- {FlaskTester-2.0 → FlaskTester-3.1}/FlaskTester.egg-info/SOURCES.txt +0 -0
- {FlaskTester-2.0 → FlaskTester-3.1}/FlaskTester.egg-info/dependency_links.txt +0 -0
- {FlaskTester-2.0 → FlaskTester-3.1}/FlaskTester.egg-info/top_level.txt +0 -0
- {FlaskTester-2.0 → FlaskTester-3.1}/LICENSE +0 -0
- {FlaskTester-2.0 → FlaskTester-3.1}/MANIFEST.in +0 -0
- {FlaskTester-2.0 → FlaskTester-3.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: FlaskTester
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.1
|
|
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>=29.
|
|
35
|
+
Requires-Dist: FlaskSimpleAuth>=29.5; extra == "dev"
|
|
36
36
|
Requires-Dist: passlib; extra == "dev"
|
|
37
37
|
Provides-Extra: doc
|
|
38
38
|
Requires-Dist: sphinx; extra == "doc"
|
|
@@ -52,7 +52,7 @@ Only one set of tests is needed, switching from internal to external is
|
|
|
52
52
|
achieved through environment variables.
|
|
53
53
|
|
|
54
54
|

|
|
55
|
-

|
|
56
56
|

|
|
57
57
|

|
|
58
58
|

|
|
@@ -87,8 +87,8 @@ def app(ft_client):
|
|
|
87
87
|
assert res.is_json
|
|
88
88
|
ft_client.setToken("hobbes", res.json["token"])
|
|
89
89
|
# also set a cookie
|
|
90
|
-
ft_client.setCookie("hobbes", "lang", "
|
|
91
|
-
ft_client.setCookie("calvin", "lang", "
|
|
90
|
+
ft_client.setCookie("hobbes", "lang", "fr")
|
|
91
|
+
ft_client.setCookie("calvin", "lang", "en")
|
|
92
92
|
# return working client
|
|
93
93
|
yield ft_client
|
|
94
94
|
|
|
@@ -136,7 +136,7 @@ The package provides two fixtures:
|
|
|
136
136
|
- `ft_authenticator` for app authentication, which depends on environment variables:
|
|
137
137
|
|
|
138
138
|
- `FLASK_TESTER_ALLOW` space-separated list of allowed authentication schemes,
|
|
139
|
-
default is `["bearer", "basic", "param"]`.
|
|
139
|
+
default is `["bearer", "basic", "param", "none"]`.
|
|
140
140
|
- `FLASK_TESTER_AUTH` comma-separated list of _login:password_ credentials.
|
|
141
141
|
- `FLASK_TESTER_USER` user login parameter for `param` password authentication,
|
|
142
142
|
default is `USER`.
|
|
@@ -159,7 +159,7 @@ The package provides two fixtures:
|
|
|
159
159
|
- `setPass` to associate a password to a user, set to _None_ to remove credential.
|
|
160
160
|
- `setToken` to associate a token to a user, set to _None_ to remove credential.
|
|
161
161
|
- `setCookie` to add a cookie to a user, set value to _None_ to remove cookie.
|
|
162
|
-
- `setAuth` to add authentication data to a request `kwargs`.
|
|
162
|
+
- `setAuth` to add authentication data to a request `kwargs` and `cookies`.
|
|
163
163
|
|
|
164
164
|
- `ft_client` for app testing, which depends on the previous fixture, plus
|
|
165
165
|
environment variables which allow to find the application, at least one must
|
|
@@ -242,6 +242,16 @@ Packages are distributed from [PyPI](https://pypi.org/project/FlaskTester/),
|
|
|
242
242
|
see also the [documentation](https://zx80.github.io/flask-tester/),
|
|
243
243
|
please report any [issues](https://github.com/zx80/flask-tester/issues).
|
|
244
244
|
|
|
245
|
+
### 3.1 on 2024-03-24
|
|
246
|
+
|
|
247
|
+
More consistent test and demo code.
|
|
248
|
+
Reach actual full coverage, without _any_ pragma.
|
|
249
|
+
Fix default allowed authenticator schemes.
|
|
250
|
+
|
|
251
|
+
### 3.0 on 2024-03-23
|
|
252
|
+
|
|
253
|
+
Add support for `none` authentication, with only cookies.
|
|
254
|
+
|
|
245
255
|
### 2.0 on 2024-03-23
|
|
246
256
|
|
|
247
257
|
Add support for cookies.
|
|
@@ -36,11 +36,12 @@ class Authenticator:
|
|
|
36
36
|
- ``cookie``: token in a cookie
|
|
37
37
|
- ``tparam``: token in a parameter
|
|
38
38
|
- ``fake``: fake scheme, login directly passed as a parameter
|
|
39
|
+
- ``none``: no authentication, only cookies
|
|
39
40
|
|
|
40
41
|
Constructor parameters:
|
|
41
42
|
|
|
42
43
|
- ``allow``: list of allowed schemes.
|
|
43
|
-
default is ``["bearer", "basic", "param"]``
|
|
44
|
+
default is ``["bearer", "basic", "param", "none"]``
|
|
44
45
|
- ``user``: parameter for user on ``param`` password authentication,
|
|
45
46
|
default is ``USER``
|
|
46
47
|
- ``pwd``: parameter for password on ``param`` password authentication,
|
|
@@ -61,12 +62,12 @@ class Authenticator:
|
|
|
61
62
|
_PASS_SCHEMES = {"basic", "param"}
|
|
62
63
|
|
|
63
64
|
# all supported authentication schemes
|
|
64
|
-
_AUTH_SCHEMES = {"fake"}
|
|
65
|
+
_AUTH_SCHEMES = {"fake", "none"}
|
|
65
66
|
_AUTH_SCHEMES.update(_TOKEN_SCHEMES)
|
|
66
67
|
_AUTH_SCHEMES.update(_PASS_SCHEMES)
|
|
67
68
|
|
|
68
69
|
def __init__(self,
|
|
69
|
-
allow: list[str] = ["bearer", "basic", "param"],
|
|
70
|
+
allow: list[str] = ["bearer", "basic", "param", "none"],
|
|
70
71
|
# parameter names for "basic" and "param"
|
|
71
72
|
user: str = "USER",
|
|
72
73
|
pwd: str = "PASS",
|
|
@@ -214,6 +215,10 @@ class Authenticator:
|
|
|
214
215
|
|
|
215
216
|
self._param(kwargs, self._login, login)
|
|
216
217
|
|
|
218
|
+
elif self._try_auth(auth, "none"):
|
|
219
|
+
|
|
220
|
+
pass
|
|
221
|
+
|
|
217
222
|
else:
|
|
218
223
|
|
|
219
224
|
raise AuthError(f"no authentication for login={login} auth={auth} allow={self._allow}")
|
|
@@ -450,36 +455,8 @@ class FlaskClient(Client):
|
|
|
450
455
|
|
|
451
456
|
return self._client.open(method=method, path=path, **kwargs)
|
|
452
457
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
def ft_authenticator():
|
|
456
|
-
"""Pytest Fixture: ft_authenticator.
|
|
457
|
-
|
|
458
|
-
Environment variables:
|
|
459
|
-
|
|
460
|
-
- ``FLASK_TESTER_LOG_LEVEL``: package log level in
|
|
461
|
-
``DEBUG INFO WARNING ERROR CRITICAL NOSET``.
|
|
462
|
-
Default is ``NOTSET``.
|
|
463
|
-
- ``FLASK_TESTER_ALLOW``: allowed space-separated authentication schemes, in
|
|
464
|
-
``basic param bearer header cookie tparam fake``.
|
|
465
|
-
Default is ``bearer basic param``.
|
|
466
|
-
- ``FLASK_TESTER_USER``: user login parameter for ``param`` authentication.
|
|
467
|
-
Default is ``USER``.
|
|
468
|
-
- ``FLASK_TESTER_PASS``: user password parameter for ``param`` authentication.
|
|
469
|
-
Default is ``PASS``.
|
|
470
|
-
- ``FLASK_TESTER_LOGIN``: user login parameter for ``fake`` authentication.
|
|
471
|
-
Default is ``LOGIN``.
|
|
472
|
-
- ``FLASK_TESTER_BEARER``: bearer name for *token* authentication.
|
|
473
|
-
Default is ``Bearer``.
|
|
474
|
-
- ``FLASK_TESTER_HEADER``: header name for *token* authentication.
|
|
475
|
-
Default is ``Auth``.
|
|
476
|
-
- ``FLASK_TESTER_COOKIE``: cookie name for *token* authentication.
|
|
477
|
-
Default is ``auth``.
|
|
478
|
-
- ``FLASK_TESTER_TPARAM``: parameter for *token* authentication.
|
|
479
|
-
Default is ``AUTH``.
|
|
480
|
-
- ``FLASK_TESTER_AUTH``: initial comma-separated list of *login:password*.
|
|
481
|
-
Default is not set.
|
|
482
|
-
"""
|
|
458
|
+
def _ft_authenticator():
|
|
459
|
+
"""Fixture implementation separated for testing."""
|
|
483
460
|
|
|
484
461
|
level = os.environ.get("FLASK_TESTER_LOG_LEVEL", "NOTSET")
|
|
485
462
|
log.setLevel(logging.DEBUG if level == "DEBUG" else
|
|
@@ -489,7 +466,7 @@ def ft_authenticator():
|
|
|
489
466
|
logging.CRITICAL if level == "CRITICAL" else
|
|
490
467
|
logging.NOTSET)
|
|
491
468
|
|
|
492
|
-
allow = os.environ.get("FLASK_TESTER_ALLOW", "bearer basic param").split(" ")
|
|
469
|
+
allow = os.environ.get("FLASK_TESTER_ALLOW", "bearer basic param none").split(" ")
|
|
493
470
|
|
|
494
471
|
# per-scheme parameters, must be consistent with FSA configuration
|
|
495
472
|
user = os.environ.get("FLASK_TESTER_USER", "USER")
|
|
@@ -506,31 +483,50 @@ def ft_authenticator():
|
|
|
506
483
|
if "FLASK_TESTER_AUTH" in os.environ:
|
|
507
484
|
auth.setPasses(os.environ["FLASK_TESTER_AUTH"].split(","))
|
|
508
485
|
|
|
509
|
-
|
|
510
|
-
|
|
486
|
+
return auth
|
|
511
487
|
|
|
512
488
|
@pytest.fixture
|
|
513
|
-
def
|
|
514
|
-
"""Pytest Fixture:
|
|
489
|
+
def ft_authenticator():
|
|
490
|
+
"""Pytest Fixture: ft_authenticator.
|
|
515
491
|
|
|
516
|
-
|
|
492
|
+
Environment variables:
|
|
517
493
|
|
|
518
|
-
- ``
|
|
519
|
-
|
|
494
|
+
- ``FLASK_TESTER_LOG_LEVEL``: package log level in
|
|
495
|
+
``DEBUG INFO WARNING ERROR CRITICAL NOSET``.
|
|
496
|
+
Default is ``NOTSET``.
|
|
497
|
+
- ``FLASK_TESTER_ALLOW``: allowed space-separated authentication schemes, in
|
|
498
|
+
``basic param bearer header cookie tparam fake none``.
|
|
499
|
+
Default is ``bearer basic param``.
|
|
500
|
+
- ``FLASK_TESTER_USER``: user login parameter for ``param`` authentication.
|
|
501
|
+
Default is ``USER``.
|
|
502
|
+
- ``FLASK_TESTER_PASS``: user password parameter for ``param`` authentication.
|
|
503
|
+
Default is ``PASS``.
|
|
504
|
+
- ``FLASK_TESTER_LOGIN``: user login parameter for ``fake`` authentication.
|
|
505
|
+
Default is ``LOGIN``.
|
|
506
|
+
- ``FLASK_TESTER_BEARER``: bearer name for *token* authentication.
|
|
507
|
+
Default is ``Bearer``.
|
|
508
|
+
- ``FLASK_TESTER_HEADER``: header name for *token* authentication.
|
|
509
|
+
Default is ``Auth``.
|
|
510
|
+
- ``FLASK_TESTER_COOKIE``: cookie name for *token* authentication.
|
|
511
|
+
Default is ``auth``.
|
|
512
|
+
- ``FLASK_TESTER_TPARAM``: parameter for *token* authentication.
|
|
513
|
+
Default is ``AUTH``.
|
|
514
|
+
- ``FLASK_TESTER_AUTH``: initial comma-separated list of *login:password*.
|
|
515
|
+
Default is not set.
|
|
516
|
+
"""
|
|
520
517
|
|
|
521
|
-
|
|
518
|
+
yield _ft_authenticator()
|
|
522
519
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
"""
|
|
520
|
+
def _ft_client(authenticator):
|
|
521
|
+
"""Fixture implementation separated for testing."""
|
|
526
522
|
|
|
527
523
|
default_login = os.environ.get("FLASK_TESTER_DEFAULT", None)
|
|
528
524
|
client: Client
|
|
529
525
|
|
|
530
|
-
if "FLASK_TESTER_URL" in os.environ:
|
|
526
|
+
if "FLASK_TESTER_URL" in os.environ:
|
|
531
527
|
|
|
532
528
|
app_url = os.environ["FLASK_TESTER_URL"]
|
|
533
|
-
client = RequestClient(
|
|
529
|
+
client = RequestClient(authenticator, app_url, default_login)
|
|
534
530
|
|
|
535
531
|
elif "FLASK_TESTER_APP" in os.environ:
|
|
536
532
|
|
|
@@ -548,12 +544,29 @@ def ft_client(ft_authenticator):
|
|
|
548
544
|
if callable(app) and not hasattr(app, "test_client"):
|
|
549
545
|
app = app()
|
|
550
546
|
break
|
|
551
|
-
if not app:
|
|
547
|
+
if not app:
|
|
552
548
|
raise FlaskTesterError(f"cannot find Flask app in {pkg_name}")
|
|
553
|
-
client = FlaskClient(
|
|
549
|
+
client = FlaskClient(authenticator, app.test_client(), default_login)
|
|
554
550
|
|
|
555
|
-
else:
|
|
551
|
+
else:
|
|
556
552
|
|
|
557
553
|
raise FlaskTesterError("no Flask application to test")
|
|
558
554
|
|
|
559
|
-
|
|
555
|
+
return client
|
|
556
|
+
|
|
557
|
+
@pytest.fixture
|
|
558
|
+
def ft_client(ft_authenticator):
|
|
559
|
+
"""Pytest Fixture: ft_client.
|
|
560
|
+
|
|
561
|
+
Target environment variable, one **must** be defined:
|
|
562
|
+
|
|
563
|
+
- ``FLASK_TESTER_URL``: application HTTP base URL.
|
|
564
|
+
- ``FLASK_TESTER_APP``: Flask application, eg ``app:create_app``.
|
|
565
|
+
|
|
566
|
+
Other environment variable:
|
|
567
|
+
|
|
568
|
+
- ``FLASK_TESTER_DEFAULT``: Default client login, default is *None* for no
|
|
569
|
+
default.
|
|
570
|
+
"""
|
|
571
|
+
|
|
572
|
+
yield _ft_client(ft_authenticator)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: FlaskTester
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.1
|
|
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>=29.
|
|
35
|
+
Requires-Dist: FlaskSimpleAuth>=29.5; extra == "dev"
|
|
36
36
|
Requires-Dist: passlib; extra == "dev"
|
|
37
37
|
Provides-Extra: doc
|
|
38
38
|
Requires-Dist: sphinx; extra == "doc"
|
|
@@ -52,7 +52,7 @@ Only one set of tests is needed, switching from internal to external is
|
|
|
52
52
|
achieved through environment variables.
|
|
53
53
|
|
|
54
54
|

|
|
55
|
-

|
|
56
56
|

|
|
57
57
|

|
|
58
58
|

|
|
@@ -87,8 +87,8 @@ def app(ft_client):
|
|
|
87
87
|
assert res.is_json
|
|
88
88
|
ft_client.setToken("hobbes", res.json["token"])
|
|
89
89
|
# also set a cookie
|
|
90
|
-
ft_client.setCookie("hobbes", "lang", "
|
|
91
|
-
ft_client.setCookie("calvin", "lang", "
|
|
90
|
+
ft_client.setCookie("hobbes", "lang", "fr")
|
|
91
|
+
ft_client.setCookie("calvin", "lang", "en")
|
|
92
92
|
# return working client
|
|
93
93
|
yield ft_client
|
|
94
94
|
|
|
@@ -136,7 +136,7 @@ The package provides two fixtures:
|
|
|
136
136
|
- `ft_authenticator` for app authentication, which depends on environment variables:
|
|
137
137
|
|
|
138
138
|
- `FLASK_TESTER_ALLOW` space-separated list of allowed authentication schemes,
|
|
139
|
-
default is `["bearer", "basic", "param"]`.
|
|
139
|
+
default is `["bearer", "basic", "param", "none"]`.
|
|
140
140
|
- `FLASK_TESTER_AUTH` comma-separated list of _login:password_ credentials.
|
|
141
141
|
- `FLASK_TESTER_USER` user login parameter for `param` password authentication,
|
|
142
142
|
default is `USER`.
|
|
@@ -159,7 +159,7 @@ The package provides two fixtures:
|
|
|
159
159
|
- `setPass` to associate a password to a user, set to _None_ to remove credential.
|
|
160
160
|
- `setToken` to associate a token to a user, set to _None_ to remove credential.
|
|
161
161
|
- `setCookie` to add a cookie to a user, set value to _None_ to remove cookie.
|
|
162
|
-
- `setAuth` to add authentication data to a request `kwargs`.
|
|
162
|
+
- `setAuth` to add authentication data to a request `kwargs` and `cookies`.
|
|
163
163
|
|
|
164
164
|
- `ft_client` for app testing, which depends on the previous fixture, plus
|
|
165
165
|
environment variables which allow to find the application, at least one must
|
|
@@ -242,6 +242,16 @@ Packages are distributed from [PyPI](https://pypi.org/project/FlaskTester/),
|
|
|
242
242
|
see also the [documentation](https://zx80.github.io/flask-tester/),
|
|
243
243
|
please report any [issues](https://github.com/zx80/flask-tester/issues).
|
|
244
244
|
|
|
245
|
+
### 3.1 on 2024-03-24
|
|
246
|
+
|
|
247
|
+
More consistent test and demo code.
|
|
248
|
+
Reach actual full coverage, without _any_ pragma.
|
|
249
|
+
Fix default allowed authenticator schemes.
|
|
250
|
+
|
|
251
|
+
### 3.0 on 2024-03-23
|
|
252
|
+
|
|
253
|
+
Add support for `none` authentication, with only cookies.
|
|
254
|
+
|
|
245
255
|
### 2.0 on 2024-03-23
|
|
246
256
|
|
|
247
257
|
Add support for cookies.
|
|
@@ -9,7 +9,7 @@ Only one set of tests is needed, switching from internal to external is
|
|
|
9
9
|
achieved through environment variables.
|
|
10
10
|
|
|
11
11
|

|
|
12
|
-

|
|
13
13
|

|
|
14
14
|

|
|
15
15
|

|
|
@@ -44,8 +44,8 @@ def app(ft_client):
|
|
|
44
44
|
assert res.is_json
|
|
45
45
|
ft_client.setToken("hobbes", res.json["token"])
|
|
46
46
|
# also set a cookie
|
|
47
|
-
ft_client.setCookie("hobbes", "lang", "
|
|
48
|
-
ft_client.setCookie("calvin", "lang", "
|
|
47
|
+
ft_client.setCookie("hobbes", "lang", "fr")
|
|
48
|
+
ft_client.setCookie("calvin", "lang", "en")
|
|
49
49
|
# return working client
|
|
50
50
|
yield ft_client
|
|
51
51
|
|
|
@@ -93,7 +93,7 @@ The package provides two fixtures:
|
|
|
93
93
|
- `ft_authenticator` for app authentication, which depends on environment variables:
|
|
94
94
|
|
|
95
95
|
- `FLASK_TESTER_ALLOW` space-separated list of allowed authentication schemes,
|
|
96
|
-
default is `["bearer", "basic", "param"]`.
|
|
96
|
+
default is `["bearer", "basic", "param", "none"]`.
|
|
97
97
|
- `FLASK_TESTER_AUTH` comma-separated list of _login:password_ credentials.
|
|
98
98
|
- `FLASK_TESTER_USER` user login parameter for `param` password authentication,
|
|
99
99
|
default is `USER`.
|
|
@@ -116,7 +116,7 @@ The package provides two fixtures:
|
|
|
116
116
|
- `setPass` to associate a password to a user, set to _None_ to remove credential.
|
|
117
117
|
- `setToken` to associate a token to a user, set to _None_ to remove credential.
|
|
118
118
|
- `setCookie` to add a cookie to a user, set value to _None_ to remove cookie.
|
|
119
|
-
- `setAuth` to add authentication data to a request `kwargs`.
|
|
119
|
+
- `setAuth` to add authentication data to a request `kwargs` and `cookies`.
|
|
120
120
|
|
|
121
121
|
- `ft_client` for app testing, which depends on the previous fixture, plus
|
|
122
122
|
environment variables which allow to find the application, at least one must
|
|
@@ -199,6 +199,16 @@ Packages are distributed from [PyPI](https://pypi.org/project/FlaskTester/),
|
|
|
199
199
|
see also the [documentation](https://zx80.github.io/flask-tester/),
|
|
200
200
|
please report any [issues](https://github.com/zx80/flask-tester/issues).
|
|
201
201
|
|
|
202
|
+
### 3.1 on 2024-03-24
|
|
203
|
+
|
|
204
|
+
More consistent test and demo code.
|
|
205
|
+
Reach actual full coverage, without _any_ pragma.
|
|
206
|
+
Fix default allowed authenticator schemes.
|
|
207
|
+
|
|
208
|
+
### 3.0 on 2024-03-23
|
|
209
|
+
|
|
210
|
+
Add support for `none` authentication, with only cookies.
|
|
211
|
+
|
|
202
212
|
### 2.0 on 2024-03-23
|
|
203
213
|
|
|
204
214
|
Add support for cookies.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "FlaskTester"
|
|
7
|
-
version = "
|
|
7
|
+
version = "3.1"
|
|
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>=29.
|
|
36
|
+
dev = ["mypy", "pyright", "ruff", "coverage", "pymarkdownlnt!=0.9.5", "build", "twine", "wheel", "types-flask", "types-requests", "FlaskSimpleAuth>=29.5", "passlib"]
|
|
37
37
|
# documentation generation
|
|
38
38
|
doc = ["sphinx", "sphinx_rtd_theme", "sphinx-autoapi", "sphinx-lint", "myst_parser"]
|
|
39
39
|
|
|
@@ -15,7 +15,7 @@ logging.basicConfig(level=logging.INFO)
|
|
|
15
15
|
|
|
16
16
|
# set authn for ft_authenticator
|
|
17
17
|
os.environ.update(
|
|
18
|
-
FLASK_TESTER_ALLOW="bearer basic param",
|
|
18
|
+
FLASK_TESTER_ALLOW="bearer basic param none",
|
|
19
19
|
FLASK_TESTER_AUTH=",".join(f"{l}:{p}" for l, p in secret.PASSES.items()),
|
|
20
20
|
)
|
|
21
21
|
|
|
@@ -38,8 +38,8 @@ def app(ft_client):
|
|
|
38
38
|
assert res.is_json
|
|
39
39
|
ft_client.setToken("hobbes", res.json["token"])
|
|
40
40
|
# also set a cookie
|
|
41
|
-
ft_client.setCookie("hobbes", "lang", "
|
|
42
|
-
ft_client.setCookie("calvin", "lang", "
|
|
41
|
+
ft_client.setCookie("hobbes", "lang", "fr")
|
|
42
|
+
ft_client.setCookie("calvin", "lang", "en")
|
|
43
43
|
# return working client
|
|
44
44
|
yield ft_client
|
|
45
45
|
|
|
@@ -66,8 +66,8 @@ def api(ft_client):
|
|
|
66
66
|
ft_client.setPass("moe", "bad password")
|
|
67
67
|
ft_client.setToken("moe", "bad token")
|
|
68
68
|
# cookies
|
|
69
|
-
ft_client.setCookie("calvin", "lang", "
|
|
70
|
-
ft_client.setCookie("hobbes", "lang", "
|
|
69
|
+
ft_client.setCookie("calvin", "lang", "en")
|
|
70
|
+
ft_client.setCookie("hobbes", "lang", "fr")
|
|
71
71
|
# get valid tokens using password authn
|
|
72
72
|
res = ft_client.get("/login", login="calvin", auth="basic", status=200)
|
|
73
73
|
assert res.json["user"] == "calvin"
|
|
@@ -78,11 +78,12 @@ def api(ft_client):
|
|
|
78
78
|
res = ft_client.post("/login", login="susie", auth="param", status=201, json={})
|
|
79
79
|
assert res.json["user"] == "susie"
|
|
80
80
|
ft_client._auth.setToken("susie", res.json["token"])
|
|
81
|
+
ft_client.get("/login", login="calvin", auth="none", status=401)
|
|
81
82
|
# check that token auth and cookie is ok
|
|
82
83
|
res = ft_client.get("/who-am-i", login="calvin", status=200, auth="bearer")
|
|
83
|
-
assert res.json["user"] == "calvin" and res.json["lang"] == "
|
|
84
|
+
assert res.json["user"] == "calvin" and res.json["lang"] == "en"
|
|
84
85
|
res = ft_client.get("/who-am-i", login="hobbes", status=200, auth="bearer")
|
|
85
|
-
assert res.json["user"] == "hobbes" and res.json["lang"] == "
|
|
86
|
+
assert res.json["user"] == "hobbes" and res.json["lang"] == "fr"
|
|
86
87
|
res = ft_client.get("/who-am-i", login="susie", status=200, auth="bearer")
|
|
87
88
|
assert res.json["user"] == "susie" and res.json["lang"] is None
|
|
88
89
|
# with defaults
|
|
@@ -117,6 +118,7 @@ def test_admin(api):
|
|
|
117
118
|
assert "NOT THERE" in str(e)
|
|
118
119
|
|
|
119
120
|
def test_errors(api):
|
|
121
|
+
# these schemes are not allowed
|
|
120
122
|
for scheme in ("header", "cookie", "fake", "tparam", "unexpected"):
|
|
121
123
|
try:
|
|
122
124
|
api.get("/login", login="calvin", auth=scheme)
|
|
@@ -125,13 +127,27 @@ def test_errors(api):
|
|
|
125
127
|
assert True, "expected error"
|
|
126
128
|
|
|
127
129
|
def test_methods(api):
|
|
128
|
-
res = api.get("/who-am-i", login="susie", status=200, cookies={"lang": "
|
|
129
|
-
assert res.json["lang"] == "
|
|
130
|
+
res = api.get("/who-am-i", login="susie", status=200, cookies={"lang": "it"})
|
|
131
|
+
assert res.json["lang"] == "it"
|
|
130
132
|
api.post("/who-am-i", login="hobbes", status=405)
|
|
131
133
|
api.put("/who-am-i", login="hobbes", status=405)
|
|
132
134
|
api.patch("/who-am-i", login="hobbes", status=405)
|
|
133
135
|
api.delete("/who-am-i", login="hobbes", status=405)
|
|
134
136
|
|
|
137
|
+
def test_hello(api):
|
|
138
|
+
res = api.get("/hello", login="calvin", auth="none", status=200)
|
|
139
|
+
assert res.json["lang"] == "en" and res.json["hello"] == "Hi"
|
|
140
|
+
assert res.headers["FSA-User"] == "None (None)"
|
|
141
|
+
res = api.get("/hello", login="hobbes", auth="none", status=200)
|
|
142
|
+
assert res.json["lang"] == "fr" and res.json["hello"] == "Salut"
|
|
143
|
+
assert res.headers["FSA-User"] == "None (None)"
|
|
144
|
+
res = api.get("/hello", login="susie", auth="none", status=200, cookies={"lang": "it"})
|
|
145
|
+
assert res.json["lang"] == "it" and res.json["hello"] == "Ciao"
|
|
146
|
+
assert res.headers["FSA-User"] == "None (None)"
|
|
147
|
+
res = api.get("/hello", login="moe", auth="none", status=200)
|
|
148
|
+
assert res.json["lang"] == "en" and res.json["hello"] == "Hi"
|
|
149
|
+
assert res.headers["FSA-User"] == "None (None)"
|
|
150
|
+
|
|
135
151
|
def test_authenticator_token():
|
|
136
152
|
# all token carriers
|
|
137
153
|
auth = ft.Authenticator(allow=["bearer", "header", "tparam", "cookie"])
|
|
@@ -253,6 +269,7 @@ def test_request_flask_response():
|
|
|
253
269
|
assert not xres.is_json and xres.json is None
|
|
254
270
|
|
|
255
271
|
def test_client():
|
|
272
|
+
# abstract class for coverage
|
|
256
273
|
client = ft.Client(ft.Authenticator())
|
|
257
274
|
try:
|
|
258
275
|
client._request("GET", "/", {})
|
|
@@ -261,6 +278,7 @@ def test_client():
|
|
|
261
278
|
assert True, "expected error raised"
|
|
262
279
|
|
|
263
280
|
def test_request_client():
|
|
281
|
+
# start a tmp server on port 8888 for URL client coverage
|
|
264
282
|
httpd = htsv.HTTPServer(("", 8888), htsv.SimpleHTTPRequestHandler)
|
|
265
283
|
thread = threading.Thread(target = lambda: httpd.serve_forever())
|
|
266
284
|
thread.start()
|
|
@@ -274,3 +292,48 @@ def test_request_client():
|
|
|
274
292
|
client.post("/", status=501, data={"hello": "world!"})
|
|
275
293
|
finally:
|
|
276
294
|
httpd.shutdown()
|
|
295
|
+
|
|
296
|
+
def test_client_fixture():
|
|
297
|
+
# ft_client coverage
|
|
298
|
+
auth = ft._ft_authenticator()
|
|
299
|
+
# check and save env
|
|
300
|
+
# assert "FLASK_TESTER_URL" not in os.environ
|
|
301
|
+
url = None
|
|
302
|
+
if "FLASK_TESTER_URL" in os.environ: # pragma: no cover
|
|
303
|
+
url = os.environ["FLASK_TESTER_URL"]
|
|
304
|
+
del os.environ["FLASK_TESTER_URL"]
|
|
305
|
+
app = None
|
|
306
|
+
if "FLASK_TESTER_APP" in os.environ:
|
|
307
|
+
app = os.environ["FLASK_TESTER_APP"]
|
|
308
|
+
del os.environ["FLASK_TESTER_APP"]
|
|
309
|
+
# no url nor app
|
|
310
|
+
try:
|
|
311
|
+
init = ft._ft_client(auth)
|
|
312
|
+
pytest.fail("must fail without environment variables") # pragma: no cover
|
|
313
|
+
except ft.FlaskTesterError:
|
|
314
|
+
assert True, "expected error raised"
|
|
315
|
+
# url
|
|
316
|
+
os.environ["FLASK_TESTER_URL"] = "http://localhost:5000"
|
|
317
|
+
init = ft._ft_client(auth)
|
|
318
|
+
assert isinstance(init, ft.RequestClient)
|
|
319
|
+
del os.environ["FLASK_TESTER_URL"]
|
|
320
|
+
# bad package
|
|
321
|
+
os.environ["FLASK_TESTER_APP"] = "no_such_package"
|
|
322
|
+
try:
|
|
323
|
+
init = ft._ft_client(auth)
|
|
324
|
+
pytest.fail("must fail on missing package") # pragma: no cover
|
|
325
|
+
except ModuleNotFoundError:
|
|
326
|
+
assert True, "expected error raised"
|
|
327
|
+
# bad name
|
|
328
|
+
os.environ["FLASK_TESTER_APP"] = "app:no_such_app"
|
|
329
|
+
try:
|
|
330
|
+
init = ft._ft_client(auth)
|
|
331
|
+
pytest.fail("must fail on missing package") # pragma: no cover
|
|
332
|
+
except ft.FlaskTesterError:
|
|
333
|
+
assert True, "expected error raised"
|
|
334
|
+
del os.environ["FLASK_TESTER_APP"]
|
|
335
|
+
# reset env
|
|
336
|
+
if url: # pragma: no cover
|
|
337
|
+
os.environ["FLASK_TESTER_URL"] = url
|
|
338
|
+
if app:
|
|
339
|
+
os.environ["FLASK_TESTER_APP"] = app
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|