FlaskTester 4.3__tar.gz → 5.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.
- {flasktester-4.3 → flasktester-5.0}/FlaskTester.egg-info/PKG-INFO +19 -17
- {flasktester-4.3 → flasktester-5.0}/FlaskTester.egg-info/requires.txt +6 -5
- {flasktester-4.3 → flasktester-5.0}/FlaskTester.py +22 -2
- {flasktester-4.3 → flasktester-5.0}/PKG-INFO +19 -17
- {flasktester-4.3 → flasktester-5.0}/README.md +12 -10
- {flasktester-4.3 → flasktester-5.0}/pyproject.toml +3 -4
- {flasktester-4.3 → flasktester-5.0}/tests/test_app.py +24 -17
- {flasktester-4.3 → flasktester-5.0}/FlaskTester.egg-info/SOURCES.txt +0 -0
- {flasktester-4.3 → flasktester-5.0}/FlaskTester.egg-info/dependency_links.txt +0 -0
- {flasktester-4.3 → flasktester-5.0}/FlaskTester.egg-info/top_level.txt +0 -0
- {flasktester-4.3 → flasktester-5.0}/LICENSE +0 -0
- {flasktester-4.3 → flasktester-5.0}/MANIFEST.in +0 -0
- {flasktester-4.3 → flasktester-5.0}/setup.cfg +0 -0
- {flasktester-4.3 → flasktester-5.0}/tests/test_app2.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: FlaskTester
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.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
|
|
@@ -26,13 +26,9 @@ Requires-Dist: pyright; extra == "dev"
|
|
|
26
26
|
Requires-Dist: ruff; extra == "dev"
|
|
27
27
|
Requires-Dist: coverage; extra == "dev"
|
|
28
28
|
Requires-Dist: pymarkdownlnt!=0.9.5; extra == "dev"
|
|
29
|
-
Requires-Dist: build; extra == "dev"
|
|
30
|
-
Requires-Dist: twine; extra == "dev"
|
|
31
|
-
Requires-Dist: wheel; extra == "dev"
|
|
32
29
|
Requires-Dist: types-flask; extra == "dev"
|
|
33
30
|
Requires-Dist: types-requests; extra == "dev"
|
|
34
|
-
Requires-Dist: FlaskSimpleAuth>=
|
|
35
|
-
Requires-Dist: passlib; extra == "dev"
|
|
31
|
+
Requires-Dist: FlaskSimpleAuth>=35.0; extra == "dev"
|
|
36
32
|
Requires-Dist: bcrypt; extra == "dev"
|
|
37
33
|
Requires-Dist: pydantic; extra == "dev"
|
|
38
34
|
Provides-Extra: doc
|
|
@@ -41,6 +37,10 @@ Requires-Dist: sphinx_rtd_theme; extra == "doc"
|
|
|
41
37
|
Requires-Dist: sphinx-autoapi; extra == "doc"
|
|
42
38
|
Requires-Dist: sphinx-lint; extra == "doc"
|
|
43
39
|
Requires-Dist: myst_parser; extra == "doc"
|
|
40
|
+
Provides-Extra: pub
|
|
41
|
+
Requires-Dist: build; extra == "pub"
|
|
42
|
+
Requires-Dist: twine; extra == "pub"
|
|
43
|
+
Requires-Dist: wheel; extra == "pub"
|
|
44
44
|
|
|
45
45
|
# FlaskTester - Pytest fixtures for Flask internal and external authenticated tests
|
|
46
46
|
|
|
@@ -53,7 +53,7 @@ Only one set of tests is needed, switching from internal to external is
|
|
|
53
53
|
achieved by setting an environment variable.
|
|
54
54
|
|
|
55
55
|

|
|
56
|
-

|
|
57
57
|

|
|
58
58
|

|
|
59
59
|

|
|
@@ -75,18 +75,20 @@ import pytest
|
|
|
75
75
|
from FlaskTester import ft_authenticator, ft_client
|
|
76
76
|
import secret
|
|
77
77
|
|
|
78
|
+
def authHook(api, user: str, pwd: str|None):
|
|
79
|
+
if pwd is not None: # get a token when a login/password is provided
|
|
80
|
+
res = api.get("/login", login=user, auth="basic", status=200)
|
|
81
|
+
api.setToken(user, res.json["token"])
|
|
82
|
+
else: # remove token
|
|
83
|
+
api.setToken(user, None)
|
|
84
|
+
|
|
78
85
|
@pytest.fixture
|
|
79
86
|
def app(ft_client):
|
|
87
|
+
# register authentication hook
|
|
88
|
+
ft_client.setHook(authHook)
|
|
80
89
|
# add test passwords for Calvin and Hobbes (must be consistent with app!)
|
|
81
90
|
ft_client.setPass("calvin", secret.PASSES["calvin"])
|
|
82
91
|
ft_client.setPass("hobbes", secret.PASSES["hobbes"])
|
|
83
|
-
# get user tokens, assume json result {"token": "<token-value>"}
|
|
84
|
-
res = ft_client.get("/login", login="calvin", auth="basic", status=200)
|
|
85
|
-
assert res.is_json
|
|
86
|
-
ft_client.setToken("calvin", res.json["token"])
|
|
87
|
-
res = ft_client.post("/login", login="hobbes", auth="param", status=201)
|
|
88
|
-
assert res.is_json
|
|
89
|
-
ft_client.setToken("hobbes", res.json["token"])
|
|
90
92
|
# also set a cookie
|
|
91
93
|
ft_client.setCookie("hobbes", "lang", "fr")
|
|
92
94
|
ft_client.setCookie("calvin", "lang", "en")
|
|
@@ -102,13 +104,13 @@ def test_app_admin(app):
|
|
|
102
104
|
assert 'not in group "ADMIN"' in res.text
|
|
103
105
|
```
|
|
104
106
|
|
|
105
|
-
This can be run against a
|
|
107
|
+
This can be run against a local or remote server:
|
|
106
108
|
|
|
107
109
|
```shell
|
|
108
110
|
export TEST_SEED="some-random-data" # shared test seed
|
|
109
111
|
flask --app app:app run & # start flask app
|
|
110
112
|
pid=$! # keep pid
|
|
111
|
-
export FLASK_TESTER_APP="http://localhost:5000" # set app local
|
|
113
|
+
export FLASK_TESTER_APP="http://localhost:5000" # set app url, local or remote
|
|
112
114
|
pytest test.py # run external tests
|
|
113
115
|
kill $pid # stop app with pid
|
|
114
116
|
```
|
|
@@ -7,13 +7,9 @@ pyright
|
|
|
7
7
|
ruff
|
|
8
8
|
coverage
|
|
9
9
|
pymarkdownlnt!=0.9.5
|
|
10
|
-
build
|
|
11
|
-
twine
|
|
12
|
-
wheel
|
|
13
10
|
types-flask
|
|
14
11
|
types-requests
|
|
15
|
-
FlaskSimpleAuth>=
|
|
16
|
-
passlib
|
|
12
|
+
FlaskSimpleAuth>=35.0
|
|
17
13
|
bcrypt
|
|
18
14
|
pydantic
|
|
19
15
|
|
|
@@ -23,3 +19,8 @@ sphinx_rtd_theme
|
|
|
23
19
|
sphinx-autoapi
|
|
24
20
|
sphinx-lint
|
|
25
21
|
myst_parser
|
|
22
|
+
|
|
23
|
+
[pub]
|
|
24
|
+
build
|
|
25
|
+
twine
|
|
26
|
+
wheel
|
|
@@ -6,7 +6,8 @@ PYTEST_DONT_REWRITE: local assertions are really that, not pytest assertions.
|
|
|
6
6
|
import os
|
|
7
7
|
import io
|
|
8
8
|
import re
|
|
9
|
-
|
|
9
|
+
# Python >= 3.11: Self
|
|
10
|
+
from typing import Any, Callable
|
|
10
11
|
import importlib
|
|
11
12
|
import logging
|
|
12
13
|
import pytest # for explicit fail calls, see _pytestFail
|
|
@@ -89,6 +90,9 @@ class Authenticator:
|
|
|
89
90
|
_AUTH_SCHEMES.update(_TOKEN_SCHEMES)
|
|
90
91
|
_AUTH_SCHEMES.update(_PASS_SCHEMES)
|
|
91
92
|
|
|
93
|
+
# authenticator login/pass hook
|
|
94
|
+
_AuthHook = Callable[[str, str|None], None]
|
|
95
|
+
|
|
92
96
|
def __init__(self,
|
|
93
97
|
allow: list[str] = ["bearer", "basic", "param", "none"],
|
|
94
98
|
# parameter names for "basic" and "param"
|
|
@@ -124,6 +128,9 @@ class Authenticator:
|
|
|
124
128
|
assert ptype in ("json", "data")
|
|
125
129
|
self._ptype = ptype
|
|
126
130
|
|
|
131
|
+
# _AuthHook|None, but python cannot stand it:-(
|
|
132
|
+
self._auth_hook: Any = None
|
|
133
|
+
|
|
127
134
|
# password and token credentials, cookies
|
|
128
135
|
self._passes: dict[str, str] = {}
|
|
129
136
|
self._tokens: dict[str, str] = {}
|
|
@@ -138,6 +145,10 @@ class Authenticator:
|
|
|
138
145
|
assert isinstance(val, str)
|
|
139
146
|
store[key] = val
|
|
140
147
|
|
|
148
|
+
def setHook(self, hook: _AuthHook):
|
|
149
|
+
"""Set on password hook."""
|
|
150
|
+
self._auth_hook = hook
|
|
151
|
+
|
|
141
152
|
def setPass(self, login: str, pw: str|None):
|
|
142
153
|
"""Associate a password to a user.
|
|
143
154
|
|
|
@@ -146,6 +157,7 @@ class Authenticator:
|
|
|
146
157
|
if not self._has_pass:
|
|
147
158
|
raise AuthError("cannot set password, no password scheme allowed")
|
|
148
159
|
self._set(login, pw, self._passes)
|
|
160
|
+
_ = self._auth_hook and self._auth_hook(login, pw)
|
|
149
161
|
|
|
150
162
|
def setPasses(self, pws: list[str]):
|
|
151
163
|
"""Associate a list of *login:password*."""
|
|
@@ -298,11 +310,19 @@ class Client:
|
|
|
298
310
|
:param default_login: When ``login`` is not set.
|
|
299
311
|
"""
|
|
300
312
|
|
|
313
|
+
# client login/pass hook (with mypy workaround)
|
|
314
|
+
# Python >= 3.11: Self
|
|
315
|
+
AuthHook = Callable[[Any, str, str|None], None] # type: ignore
|
|
316
|
+
|
|
301
317
|
def __init__(self, auth: Authenticator, default_login: str|None = None):
|
|
302
318
|
self._auth = auth
|
|
303
319
|
self._cookies: dict[str, dict[str, str]] = {} # login -> name -> value
|
|
304
320
|
self._default_login = default_login
|
|
305
321
|
|
|
322
|
+
def setHook(self, hook: AuthHook):
|
|
323
|
+
"""Set on password hook."""
|
|
324
|
+
self._auth.setHook(lambda u, p: hook(self, u, p))
|
|
325
|
+
|
|
306
326
|
def setToken(self, login: str, token: str|None):
|
|
307
327
|
"""Associate a token to a login, *None* to remove."""
|
|
308
328
|
self._auth.setToken(login, token)
|
|
@@ -603,7 +623,7 @@ def _ft_client(authenticator):
|
|
|
603
623
|
# none found
|
|
604
624
|
if not app:
|
|
605
625
|
raise FlaskTesterError(f"cannot find Flask app in {pkg_name} ({test_app})")
|
|
606
|
-
client = FlaskClient(authenticator, app.test_client(), default_login)
|
|
626
|
+
client = FlaskClient(authenticator, app.test_client(), default_login) # type: ignore
|
|
607
627
|
|
|
608
628
|
return client
|
|
609
629
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: FlaskTester
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.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
|
|
@@ -26,13 +26,9 @@ Requires-Dist: pyright; extra == "dev"
|
|
|
26
26
|
Requires-Dist: ruff; extra == "dev"
|
|
27
27
|
Requires-Dist: coverage; extra == "dev"
|
|
28
28
|
Requires-Dist: pymarkdownlnt!=0.9.5; extra == "dev"
|
|
29
|
-
Requires-Dist: build; extra == "dev"
|
|
30
|
-
Requires-Dist: twine; extra == "dev"
|
|
31
|
-
Requires-Dist: wheel; extra == "dev"
|
|
32
29
|
Requires-Dist: types-flask; extra == "dev"
|
|
33
30
|
Requires-Dist: types-requests; extra == "dev"
|
|
34
|
-
Requires-Dist: FlaskSimpleAuth>=
|
|
35
|
-
Requires-Dist: passlib; extra == "dev"
|
|
31
|
+
Requires-Dist: FlaskSimpleAuth>=35.0; extra == "dev"
|
|
36
32
|
Requires-Dist: bcrypt; extra == "dev"
|
|
37
33
|
Requires-Dist: pydantic; extra == "dev"
|
|
38
34
|
Provides-Extra: doc
|
|
@@ -41,6 +37,10 @@ Requires-Dist: sphinx_rtd_theme; extra == "doc"
|
|
|
41
37
|
Requires-Dist: sphinx-autoapi; extra == "doc"
|
|
42
38
|
Requires-Dist: sphinx-lint; extra == "doc"
|
|
43
39
|
Requires-Dist: myst_parser; extra == "doc"
|
|
40
|
+
Provides-Extra: pub
|
|
41
|
+
Requires-Dist: build; extra == "pub"
|
|
42
|
+
Requires-Dist: twine; extra == "pub"
|
|
43
|
+
Requires-Dist: wheel; extra == "pub"
|
|
44
44
|
|
|
45
45
|
# FlaskTester - Pytest fixtures for Flask internal and external authenticated tests
|
|
46
46
|
|
|
@@ -53,7 +53,7 @@ Only one set of tests is needed, switching from internal to external is
|
|
|
53
53
|
achieved by setting an environment variable.
|
|
54
54
|
|
|
55
55
|

|
|
56
|
-

|
|
57
57
|

|
|
58
58
|

|
|
59
59
|

|
|
@@ -75,18 +75,20 @@ import pytest
|
|
|
75
75
|
from FlaskTester import ft_authenticator, ft_client
|
|
76
76
|
import secret
|
|
77
77
|
|
|
78
|
+
def authHook(api, user: str, pwd: str|None):
|
|
79
|
+
if pwd is not None: # get a token when a login/password is provided
|
|
80
|
+
res = api.get("/login", login=user, auth="basic", status=200)
|
|
81
|
+
api.setToken(user, res.json["token"])
|
|
82
|
+
else: # remove token
|
|
83
|
+
api.setToken(user, None)
|
|
84
|
+
|
|
78
85
|
@pytest.fixture
|
|
79
86
|
def app(ft_client):
|
|
87
|
+
# register authentication hook
|
|
88
|
+
ft_client.setHook(authHook)
|
|
80
89
|
# add test passwords for Calvin and Hobbes (must be consistent with app!)
|
|
81
90
|
ft_client.setPass("calvin", secret.PASSES["calvin"])
|
|
82
91
|
ft_client.setPass("hobbes", secret.PASSES["hobbes"])
|
|
83
|
-
# get user tokens, assume json result {"token": "<token-value>"}
|
|
84
|
-
res = ft_client.get("/login", login="calvin", auth="basic", status=200)
|
|
85
|
-
assert res.is_json
|
|
86
|
-
ft_client.setToken("calvin", res.json["token"])
|
|
87
|
-
res = ft_client.post("/login", login="hobbes", auth="param", status=201)
|
|
88
|
-
assert res.is_json
|
|
89
|
-
ft_client.setToken("hobbes", res.json["token"])
|
|
90
92
|
# also set a cookie
|
|
91
93
|
ft_client.setCookie("hobbes", "lang", "fr")
|
|
92
94
|
ft_client.setCookie("calvin", "lang", "en")
|
|
@@ -102,13 +104,13 @@ def test_app_admin(app):
|
|
|
102
104
|
assert 'not in group "ADMIN"' in res.text
|
|
103
105
|
```
|
|
104
106
|
|
|
105
|
-
This can be run against a
|
|
107
|
+
This can be run against a local or remote server:
|
|
106
108
|
|
|
107
109
|
```shell
|
|
108
110
|
export TEST_SEED="some-random-data" # shared test seed
|
|
109
111
|
flask --app app:app run & # start flask app
|
|
110
112
|
pid=$! # keep pid
|
|
111
|
-
export FLASK_TESTER_APP="http://localhost:5000" # set app local
|
|
113
|
+
export FLASK_TESTER_APP="http://localhost:5000" # set app url, local or remote
|
|
112
114
|
pytest test.py # run external tests
|
|
113
115
|
kill $pid # stop app with pid
|
|
114
116
|
```
|
|
@@ -9,7 +9,7 @@ Only one set of tests is needed, switching from internal to external is
|
|
|
9
9
|
achieved by setting an environment variable.
|
|
10
10
|
|
|
11
11
|

|
|
12
|
-

|
|
13
13
|

|
|
14
14
|

|
|
15
15
|

|
|
@@ -31,18 +31,20 @@ import pytest
|
|
|
31
31
|
from FlaskTester import ft_authenticator, ft_client
|
|
32
32
|
import secret
|
|
33
33
|
|
|
34
|
+
def authHook(api, user: str, pwd: str|None):
|
|
35
|
+
if pwd is not None: # get a token when a login/password is provided
|
|
36
|
+
res = api.get("/login", login=user, auth="basic", status=200)
|
|
37
|
+
api.setToken(user, res.json["token"])
|
|
38
|
+
else: # remove token
|
|
39
|
+
api.setToken(user, None)
|
|
40
|
+
|
|
34
41
|
@pytest.fixture
|
|
35
42
|
def app(ft_client):
|
|
43
|
+
# register authentication hook
|
|
44
|
+
ft_client.setHook(authHook)
|
|
36
45
|
# add test passwords for Calvin and Hobbes (must be consistent with app!)
|
|
37
46
|
ft_client.setPass("calvin", secret.PASSES["calvin"])
|
|
38
47
|
ft_client.setPass("hobbes", secret.PASSES["hobbes"])
|
|
39
|
-
# get user tokens, assume json result {"token": "<token-value>"}
|
|
40
|
-
res = ft_client.get("/login", login="calvin", auth="basic", status=200)
|
|
41
|
-
assert res.is_json
|
|
42
|
-
ft_client.setToken("calvin", res.json["token"])
|
|
43
|
-
res = ft_client.post("/login", login="hobbes", auth="param", status=201)
|
|
44
|
-
assert res.is_json
|
|
45
|
-
ft_client.setToken("hobbes", res.json["token"])
|
|
46
48
|
# also set a cookie
|
|
47
49
|
ft_client.setCookie("hobbes", "lang", "fr")
|
|
48
50
|
ft_client.setCookie("calvin", "lang", "en")
|
|
@@ -58,13 +60,13 @@ def test_app_admin(app):
|
|
|
58
60
|
assert 'not in group "ADMIN"' in res.text
|
|
59
61
|
```
|
|
60
62
|
|
|
61
|
-
This can be run against a
|
|
63
|
+
This can be run against a local or remote server:
|
|
62
64
|
|
|
63
65
|
```shell
|
|
64
66
|
export TEST_SEED="some-random-data" # shared test seed
|
|
65
67
|
flask --app app:app run & # start flask app
|
|
66
68
|
pid=$! # keep pid
|
|
67
|
-
export FLASK_TESTER_APP="http://localhost:5000" # set app local
|
|
69
|
+
export FLASK_TESTER_APP="http://localhost:5000" # set app url, local or remote
|
|
68
70
|
pytest test.py # run external tests
|
|
69
71
|
kill $pid # stop app with pid
|
|
70
72
|
```
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "FlaskTester"
|
|
7
|
-
version = "
|
|
7
|
+
version = "5.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"
|
|
@@ -35,13 +35,12 @@ package = "https://pypi.org/project/FlaskTester/"
|
|
|
35
35
|
dev = [
|
|
36
36
|
# static checks…
|
|
37
37
|
"mypy", "pyright", "ruff", "coverage", "pymarkdownlnt!=0.9.5",
|
|
38
|
-
# packaging
|
|
39
|
-
"build", "twine", "wheel",
|
|
40
38
|
# tests
|
|
41
|
-
"types-flask", "types-requests", "FlaskSimpleAuth>=
|
|
39
|
+
"types-flask", "types-requests", "FlaskSimpleAuth>=35.0", "bcrypt", "pydantic"
|
|
42
40
|
]
|
|
43
41
|
# documentation generation
|
|
44
42
|
doc = ["sphinx", "sphinx_rtd_theme", "sphinx-autoapi", "sphinx-lint", "myst_parser"]
|
|
43
|
+
pub = ["build", "twine", "wheel"]
|
|
45
44
|
|
|
46
45
|
[tool.setuptools]
|
|
47
46
|
py-modules = [ "FlaskTester" ]
|
|
@@ -12,7 +12,7 @@ import model
|
|
|
12
12
|
|
|
13
13
|
logging.basicConfig(level=logging.INFO)
|
|
14
14
|
# logging.basicConfig(level=logging.DEBUG)
|
|
15
|
-
|
|
15
|
+
log = logging.getLogger("test")
|
|
16
16
|
|
|
17
17
|
# set authn for ft_authenticator
|
|
18
18
|
os.environ.update(
|
|
@@ -27,23 +27,31 @@ def test_sanity():
|
|
|
27
27
|
# log.debug(f"TEST_SEED={os.environ.get('TEST_SEED')}")
|
|
28
28
|
|
|
29
29
|
# example from README.md
|
|
30
|
+
def authHook(api, user: str, pwd: str|None):
|
|
31
|
+
if pwd is not None: # get token
|
|
32
|
+
try:
|
|
33
|
+
res = api.get("/login", login=user, auth="basic", status=200)
|
|
34
|
+
api.setToken(user, res.json["token"])
|
|
35
|
+
except ft.FlaskTesterError as e: # pragma: no cover
|
|
36
|
+
log.warning(f"error: {e}")
|
|
37
|
+
else: # cleanup
|
|
38
|
+
api.setToken(user, None)
|
|
39
|
+
|
|
30
40
|
@pytest.fixture
|
|
31
41
|
def app(ft_client):
|
|
32
|
-
#
|
|
42
|
+
# hook when adding login/passwords
|
|
43
|
+
ft_client.setHook(authHook)
|
|
44
|
+
# Calvin authentication
|
|
33
45
|
ft_client.setPass("calvin", secret.PASSES["calvin"])
|
|
34
|
-
ft_client.setPass("hobbes", secret.PASSES["hobbes"])
|
|
35
|
-
# get user tokens, assume json result {"token": "<token-value>"}
|
|
36
|
-
res = ft_client.get("/login", login="calvin", auth="basic", status=200)
|
|
37
|
-
assert res.is_json
|
|
38
|
-
ft_client.setToken("calvin", res.json["token"])
|
|
39
|
-
res = ft_client.post("/login", login="hobbes", auth="param", status=201)
|
|
40
|
-
assert res.is_json
|
|
41
|
-
ft_client.setToken("hobbes", res.json["token"])
|
|
42
|
-
# also set a cookie
|
|
43
46
|
ft_client.setCookie("hobbes", "lang", "fr")
|
|
47
|
+
# Hobbes authentication
|
|
48
|
+
ft_client.setPass("hobbes", secret.PASSES["hobbes"])
|
|
44
49
|
ft_client.setCookie("calvin", "lang", "en")
|
|
45
50
|
# return working client
|
|
46
51
|
yield ft_client
|
|
52
|
+
# cleanup
|
|
53
|
+
ft_client.setPass("calvin", None)
|
|
54
|
+
ft_client.setPass("hobbes", None)
|
|
47
55
|
|
|
48
56
|
def test_app_admin(app): # GET /admin
|
|
49
57
|
app.get("/admin", login=None, status=401)
|
|
@@ -343,6 +351,7 @@ def test_client_fixture():
|
|
|
343
351
|
def test_classes(api):
|
|
344
352
|
|
|
345
353
|
def thing_eq(ta, tb):
|
|
354
|
+
ta = model.Thing1(**ta) if isinstance(ta, dict) else ta
|
|
346
355
|
tb = model.Thing1(**tb) if isinstance(tb, dict) else tb
|
|
347
356
|
return ta.tid == tb.tid and ta.name == tb.name and ta.owner == tb.owner
|
|
348
357
|
|
|
@@ -356,17 +365,15 @@ def test_classes(api):
|
|
|
356
365
|
# check all combinations
|
|
357
366
|
for path in ["/t0", "/t1", "/t2", "/t3"]:
|
|
358
367
|
for param in [t0, t1, t2, t3]:
|
|
359
|
-
for tclass in [model.Thing1, model.Thing2, model.Thing3]:
|
|
368
|
+
for tclass in [dict, model.Thing1, model.Thing2, model.Thing3]:
|
|
360
369
|
for method in ["GET", "POST"]:
|
|
361
370
|
for mode in ["data", "json"]:
|
|
362
371
|
n +=1
|
|
363
372
|
parameter = {mode: {"t": param}}
|
|
364
373
|
res = api.request(method, path, 200, **parameter)
|
|
365
|
-
assert res.is_json
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
assert thing_eq(tclass(**json), param)
|
|
369
|
-
assert n == 192
|
|
374
|
+
assert res.is_json and isinstance(res.json, dict)
|
|
375
|
+
assert thing_eq(tclass(**res.json), param)
|
|
376
|
+
assert n == 256
|
|
370
377
|
|
|
371
378
|
# simple types translation
|
|
372
379
|
assert api.get("/t0", 200, json={"t": None}).json is None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|