Make tests framework agnostic

This commit is contained in:
Robbe Sneyders
2023-02-13 19:40:48 +01:00
parent 642a5f2dc3
commit 515e324c80
16 changed files with 478 additions and 470 deletions

View File

@@ -10,29 +10,21 @@ def test_parameter_validation(simple_app):
url = "/v1.0/test_parameter_validation"
response = app_client.get(
url, query_string={"date": "2015-08-26"}
) # type: flask.Response
response = app_client.get(url, params={"date": "2015-08-26"})
assert response.status_code == 200
for invalid_int in "", "foo", "0.1":
response = app_client.get(
url, query_string={"int": invalid_int}
) # type: flask.Response
response = app_client.get(url, params={"int": invalid_int})
assert response.status_code == 400
response = app_client.get(url, query_string={"int": "123"}) # type: flask.Response
response = app_client.get(url, params={"int": "123"})
assert response.status_code == 200
for invalid_bool in "", "foo", "yes":
response = app_client.get(
url, query_string={"bool": invalid_bool}
) # type: flask.Response
response = app_client.get(url, params={"bool": invalid_bool})
assert response.status_code == 400
response = app_client.get(
url, query_string={"bool": "true"}
) # type: flask.Response
response = app_client.get(url, params={"bool": "true"})
assert response.status_code == 200
@@ -43,7 +35,7 @@ def test_required_query_param(simple_app):
response = app_client.get(url)
assert response.status_code == 400
response = app_client.get(url, query_string={"n": "1.23"})
response = app_client.get(url, params={"n": "1.23"})
assert response.status_code == 200
@@ -52,38 +44,34 @@ def test_array_query_param(simple_app):
headers = {"Content-type": "application/json"}
url = "/v1.0/test_array_csv_query_param"
response = app_client.get(url, headers=headers)
array_response: List[str] = json.loads(response.data.decode("utf-8", "replace"))
array_response: List[str] = json.loads(response.text)
assert array_response == ["squash", "banana"]
url = "/v1.0/test_array_csv_query_param?items=one,two,three"
response = app_client.get(url, headers=headers)
array_response: List[str] = json.loads(response.data.decode("utf-8", "replace"))
array_response: List[str] = json.loads(response.text)
assert array_response == ["one", "two", "three"]
url = "/v1.0/test_array_pipes_query_param?items=1|2|3"
response = app_client.get(url, headers=headers)
array_response: List[int] = json.loads(response.data.decode("utf-8", "replace"))
array_response: List[int] = json.loads(response.text)
assert array_response == [1, 2, 3]
url = "/v1.0/test_array_unsupported_query_param?items=1;2;3"
response = app_client.get(url, headers=headers)
array_response: List[str] = json.loads(
response.data.decode("utf-8", "replace")
response.text
) # unsupported collectionFormat
assert array_response == ["1;2;3"]
url = "/v1.0/test_array_csv_query_param?items=A&items=B&items=C&items=D,E,F"
response = app_client.get(url, headers=headers)
array_response: List[str] = json.loads(
response.data.decode("utf-8", "replace")
) # multi array with csv format
array_response: List[str] = json.loads(response.text) # multi array with csv format
assert array_response == ["D", "E", "F"]
url = "/v1.0/test_array_multi_query_param?items=A&items=B&items=C&items=D,E,F"
response = app_client.get(url, headers=headers)
array_response: List[str] = json.loads(
response.data.decode("utf-8", "replace")
) # multi array with csv format
array_response: List[str] = json.loads(response.text) # multi array with csv format
assert array_response == ["A", "B", "C", "D", "E", "F"]
url = "/v1.0/test_array_pipes_query_param?items=4&items=5&items=6&items=7|8|9"
response = app_client.get(url, headers=headers)
array_response: List[int] = json.loads(
response.data.decode("utf-8", "replace")
response.text
) # multi array with pipes format
assert array_response == [7, 8, 9]
@@ -93,28 +81,26 @@ def test_array_form_param(simple_app):
headers = {"Content-type": "application/x-www-form-urlencoded"}
url = "/v1.0/test_array_csv_form_param"
response = app_client.post(url, headers=headers)
array_response: List[str] = json.loads(response.data.decode("utf-8", "replace"))
array_response: List[str] = json.loads(response.text)
assert array_response == ["squash", "banana"]
url = "/v1.0/test_array_csv_form_param"
response = app_client.post(url, headers=headers, data={"items": "one,two,three"})
array_response: List[str] = json.loads(response.data.decode("utf-8", "replace"))
array_response: List[str] = json.loads(response.text)
assert array_response == ["one", "two", "three"]
url = "/v1.0/test_array_pipes_form_param"
response = app_client.post(url, headers=headers, data={"items": "1|2|3"})
array_response: List[int] = json.loads(response.data.decode("utf-8", "replace"))
array_response: List[int] = json.loads(response.text)
assert array_response == [1, 2, 3]
url = "/v1.0/test_array_csv_form_param"
data = "items=A&items=B&items=C&items=D,E,F"
response = app_client.post(url, headers=headers, data=data)
array_response: List[str] = json.loads(
response.data.decode("utf-8", "replace")
) # multi array with csv format
array_response: List[str] = json.loads(response.text) # multi array with csv format
assert array_response == ["D", "E", "F"]
url = "/v1.0/test_array_pipes_form_param"
data = "items=4&items=5&items=6&items=7|8|9"
response = app_client.post(url, headers=headers, data=data)
array_response: List[int] = json.loads(
response.data.decode("utf-8", "replace")
response.text
) # multi array with pipes format
assert array_response == [7, 8, 9]
@@ -133,7 +119,7 @@ def test_strict_extra_query_param(strict_app):
url = "/v1.0/test_parameter_validation?extra_parameter=true"
resp = app_client.get(url, headers=headers)
assert resp.status_code == 400
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response["detail"] == "Extra query parameter(s) extra_parameter not in spec"
@@ -142,7 +128,7 @@ def test_strict_formdata_param(strict_app):
headers = {"Content-type": "application/x-www-form-urlencoded"}
url = "/v1.0/test_array_csv_form_param"
resp = app_client.post(url, headers=headers, data={"items": "mango"})
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response == ["mango"]
assert resp.status_code == 200
@@ -164,14 +150,14 @@ def test_strict_formdata_param(strict_app):
def test_path_parameter_someint(simple_app, arg, result):
assert isinstance(arg, str) # sanity check
app_client = simple_app.test_client()
resp = app_client.get(f"/v1.0/test-int-path/{arg}") # type: flask.Response
assert resp.data.decode("utf-8", "replace") == f'"{result}"\n'
resp = app_client.get(f"/v1.0/test-int-path/{arg}")
assert resp.text == f'"{result}"\n'
def test_path_parameter_someint__bad(simple_app):
# non-integer values will not match Flask route
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/test-int-path/foo") # type: flask.Response
resp = app_client.get("/v1.0/test-int-path/foo")
assert resp.status_code == 404, resp.text
@@ -197,14 +183,14 @@ def test_path_parameter_someint__bad(simple_app):
def test_path_parameter_somefloat(simple_app, arg, result):
assert isinstance(arg, str) # sanity check
app_client = simple_app.test_client()
resp = app_client.get(f"/v1.0/test-float-path/{arg}") # type: flask.Response
assert resp.data.decode("utf-8", "replace") == f'"{result}"\n'
resp = app_client.get(f"/v1.0/test-float-path/{arg}")
assert resp.text == f'"{result}"\n'
def test_path_parameter_somefloat__bad(simple_app):
# non-float values will not match Flask route
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/test-float-path/123,45") # type: flask.Response
resp = app_client.get("/v1.0/test-float-path/123,45")
assert resp.status_code == 404, resp.text
@@ -212,20 +198,20 @@ def test_default_param(strict_app):
app_client = strict_app.test_client()
resp = app_client.get("/v1.0/test-default-query-parameter")
assert resp.status_code == 200
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response["app_name"] == "connexion"
def test_falsy_param(simple_app):
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/test-falsy-param", query_string={"falsy": 0})
resp = app_client.get("/v1.0/test-falsy-param", params={"falsy": 0})
assert resp.status_code == 200
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response == 0
resp = app_client.get("/v1.0/test-falsy-param")
assert resp.status_code == 200
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response == 1
@@ -233,7 +219,7 @@ def test_formdata_param(simple_app):
app_client = simple_app.test_client()
resp = app_client.post("/v1.0/test-formData-param", data={"formData": "test"})
assert resp.status_code == 200
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response == "test"
@@ -241,7 +227,7 @@ def test_formdata_bad_request(simple_app):
app_client = simple_app.test_client()
resp = app_client.post("/v1.0/test-formData-param")
assert resp.status_code == 400
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response["detail"] in [
"Missing formdata parameter 'formData'",
"'formData' is a required property", # OAS3
@@ -270,7 +256,7 @@ def test_strict_formdata_extra_param(strict_app):
"/v1.0/test-formData-param", data={"formData": "test", "extra_formData": "test"}
)
assert resp.status_code == 400
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert (
response["detail"] == "Extra formData parameter(s) extra_formData not in spec"
)
@@ -281,9 +267,10 @@ def test_formdata_file_upload(simple_app):
resp = app_client.post(
"/v1.0/test-formData-file-upload",
data={"fileData": (BytesIO(b"file contents"), "filename.txt")},
headers={"content-type": "multipart/form-data"},
)
assert resp.status_code == 200
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response == {"filename.txt": "file contents"}
@@ -291,7 +278,7 @@ def test_formdata_file_upload_bad_request(simple_app):
app_client = simple_app.test_client()
resp = app_client.post("/v1.0/test-formData-file-upload")
assert resp.status_code == 400
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response["detail"] in [
"Missing formdata parameter 'fileData'",
"'fileData' is a required property", # OAS3
@@ -303,8 +290,9 @@ def test_formdata_file_upload_missing_param(simple_app):
resp = app_client.post(
"/v1.0/test-formData-file-upload-missing-param",
data={"missing_fileData": (BytesIO(b"file contents"), "example.txt")},
headers={"content-type": "multipart/form-data"},
)
assert resp.status_code == 200
assert resp.status_code == 200, resp.text
def test_body_not_allowed_additional_properties(simple_app):
@@ -317,7 +305,7 @@ def test_body_not_allowed_additional_properties(simple_app):
)
assert resp.status_code == 400
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert "Additional properties are not allowed" in response["detail"]
@@ -326,22 +314,22 @@ def test_bool_as_default_param(simple_app):
resp = app_client.get("/v1.0/test-bool-param")
assert resp.status_code == 200
resp = app_client.get("/v1.0/test-bool-param", query_string={"thruthiness": True})
resp = app_client.get("/v1.0/test-bool-param", params={"thruthiness": True})
assert resp.status_code == 200
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response is True
def test_bool_param(simple_app):
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/test-bool-param", query_string={"thruthiness": True})
resp = app_client.get("/v1.0/test-bool-param", params={"thruthiness": True})
assert resp.status_code == 200
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response is True
resp = app_client.get("/v1.0/test-bool-param", query_string={"thruthiness": False})
resp = app_client.get("/v1.0/test-bool-param", params={"thruthiness": False})
assert resp.status_code == 200
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response is False
@@ -349,13 +337,13 @@ def test_bool_array_param(simple_app):
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/test-bool-array-param?thruthiness=true,true,true")
assert resp.status_code == 200, resp.text
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response is True
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/test-bool-array-param?thruthiness=true,true,false")
assert resp.status_code == 200, resp.text
response = json.loads(resp.data.decode("utf-8", "replace"))
response = json.loads(resp.text)
assert response is False
app_client = simple_app.test_client()
@@ -369,7 +357,7 @@ def test_required_param_miss_config(simple_app):
resp = app_client.get("/v1.0/test-required-param")
assert resp.status_code == 400
resp = app_client.get("/v1.0/test-required-param", query_string={"simple": "test"})
resp = app_client.get("/v1.0/test-required-param", params={"simple": "test"})
assert resp.status_code == 200
resp = app_client.get("/v1.0/test-required-param")
@@ -380,7 +368,7 @@ def test_parameters_defined_in_path_level(simple_app):
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/parameters-in-root-path?title=nice-get")
assert resp.status_code == 200
assert json.loads(resp.data.decode("utf-8", "replace")) == ["nice-get"]
assert json.loads(resp.text) == ["nice-get"]
resp = app_client.get("/v1.0/parameters-in-root-path")
assert resp.status_code == 400
@@ -389,10 +377,10 @@ def test_parameters_defined_in_path_level(simple_app):
def test_array_in_path(simple_app):
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/test-array-in-path/one_item")
assert json.loads(resp.data.decode("utf-8", "replace")) == ["one_item"]
assert json.loads(resp.text) == ["one_item"]
resp = app_client.get("/v1.0/test-array-in-path/one_item,another_item")
assert json.loads(resp.data.decode("utf-8", "replace")) == [
assert json.loads(resp.text) == [
"one_item",
"another_item",
]
@@ -401,43 +389,43 @@ def test_array_in_path(simple_app):
def test_nullable_parameter(simple_app):
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/nullable-parameters?time_start=null")
assert json.loads(resp.data.decode("utf-8", "replace")) == "it was None"
assert json.loads(resp.text) == "it was None"
resp = app_client.get("/v1.0/nullable-parameters?time_start=None")
assert json.loads(resp.data.decode("utf-8", "replace")) == "it was None"
assert json.loads(resp.text) == "it was None"
time_start = 1010
resp = app_client.get(f"/v1.0/nullable-parameters?time_start={time_start}")
assert json.loads(resp.data.decode("utf-8", "replace")) == time_start
assert json.loads(resp.text) == time_start
resp = app_client.post("/v1.0/nullable-parameters", data={"post_param": "None"})
assert json.loads(resp.data.decode("utf-8", "replace")) == "it was None"
assert json.loads(resp.text) == "it was None"
resp = app_client.post("/v1.0/nullable-parameters", data={"post_param": "null"})
assert json.loads(resp.data.decode("utf-8", "replace")) == "it was None"
assert json.loads(resp.text) == "it was None"
headers = {"Content-Type": "application/json"}
resp = app_client.put("/v1.0/nullable-parameters", data="null", headers=headers)
assert json.loads(resp.data.decode("utf-8", "replace")) == "it was None"
assert json.loads(resp.text) == "it was None"
resp = app_client.put("/v1.0/nullable-parameters", data="None", headers=headers)
assert json.loads(resp.data.decode("utf-8", "replace")) == "it was None"
assert json.loads(resp.text) == "it was None"
resp = app_client.put(
"/v1.0/nullable-parameters-noargs", data="None", headers=headers
)
assert json.loads(resp.data.decode("utf-8", "replace")) == "hello"
assert json.loads(resp.text) == "hello"
def test_args_kwargs(simple_app):
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/query-params-as-kwargs")
assert resp.status_code == 200
assert json.loads(resp.data.decode("utf-8", "replace")) == {}
assert json.loads(resp.text) == {}
resp = app_client.get("/v1.0/query-params-as-kwargs?foo=a&bar=b")
assert resp.status_code == 200
assert json.loads(resp.data.decode("utf-8", "replace")) == {"foo": "a"}
assert json.loads(resp.text) == {"foo": "a"}
if simple_app._spec_file == "openapi.yaml":
body = {"foo": "a", "bar": "b"}
@@ -448,7 +436,7 @@ def test_args_kwargs(simple_app):
)
assert resp.status_code == 200
# having only kwargs, the handler would have been passed 'body'
assert json.loads(resp.data.decode("utf-8", "replace")) == {
assert json.loads(resp.text) == {
"body": {"foo": "a", "bar": "b"},
}
@@ -457,13 +445,13 @@ def test_param_sanitization(simple_app):
app_client = simple_app.test_client()
resp = app_client.post("/v1.0/param-sanitization")
assert resp.status_code == 200
assert json.loads(resp.data.decode("utf-8", "replace")) == {}
assert json.loads(resp.text) == {}
resp = app_client.post(
"/v1.0/param-sanitization?$query=queryString", data={"$form": "formString"}
)
assert resp.status_code == 200
assert json.loads(resp.data.decode("utf-8", "replace")) == {
assert json.loads(resp.text) == {
"query": "queryString",
"form": "formString",
}
@@ -475,7 +463,7 @@ def test_param_sanitization(simple_app):
headers={"Content-Type": "application/json"},
)
assert resp.status_code == 200
assert json.loads(resp.data.decode("utf-8", "replace")) == body
assert json.loads(resp.text) == body
body = {"body1": "bodyString", "body2": 12, "body3": {"a": "otherString"}}
resp = app_client.post(
@@ -484,7 +472,7 @@ def test_param_sanitization(simple_app):
headers={"Content-Type": "application/json"},
)
assert resp.status_code == 200
assert json.loads(resp.data.decode("utf-8", "replace")) == body
assert json.loads(resp.text) == body
body = {
"body1": "bodyString",
@@ -497,7 +485,7 @@ def test_param_sanitization(simple_app):
headers={"Content-Type": "application/json"},
)
assert resp.status_code == 200
assert json.loads(resp.data.decode("utf-8", "replace")) == body
assert json.loads(resp.text) == body
def test_no_sanitization_in_request_body(simple_app):
@@ -514,7 +502,7 @@ def test_no_sanitization_in_request_body(simple_app):
response = app_client.post("/v1.0/forward", json=data)
assert response.status_code == 200
assert response.json == data
assert json.loads(response.text) == data
def test_parameters_snake_case(snake_case_app):
@@ -558,19 +546,25 @@ def test_parameters_snake_case(snake_case_app):
"/v1.0/test-get-camel-case-version?truthiness=true&orderBy=asc"
)
assert resp.status_code == 200, resp.text
assert resp.get_json() == {"truthiness": True, "order_by": "asc"}
assert json.loads(resp.text) == {"truthiness": True, "order_by": "asc"}
resp = app_client.get("/v1.0/test-get-camel-case-version?truthiness=5")
assert resp.status_code == 400
assert resp.get_json()["detail"].startswith("'5' is not of type 'boolean'")
assert json.loads(resp.text)["detail"].startswith("'5' is not of type 'boolean'")
# Incorrectly cased params should be ignored
resp = app_client.get(
"/v1.0/test-get-camel-case-version?Truthiness=true&order_by=asc"
)
assert resp.status_code == 200
assert resp.get_json() == {"truthiness": False, "order_by": None} # default values
assert json.loads(resp.text) == {
"truthiness": False,
"order_by": None,
} # default values
resp = app_client.get("/v1.0/test-get-camel-case-version?Truthiness=5&order_by=4")
assert resp.status_code == 200
assert resp.get_json() == {"truthiness": False, "order_by": None} # default values
assert json.loads(resp.text) == {
"truthiness": False,
"order_by": None,
} # default values
# TODO: Add tests for body parameters
@@ -579,12 +573,15 @@ def test_get_unicode_request(simple_app):
app_client = simple_app.test_client()
resp = app_client.get("/v1.0/get_unicode_request?price=%C2%A319.99") # £19.99
assert resp.status_code == 200
assert json.loads(resp.data.decode("utf-8"))["price"] == "£19.99"
assert json.loads(resp.text)["price"] == "£19.99"
def test_cookie_param(simple_app):
app_client = simple_app.test_client()
app_client.set_cookie("localhost", "test_cookie", "hello")
try:
app_client = simple_app.test_client(cookies={"test_cookie": "hello"})
except TypeError:
app_client = simple_app.test_client()
app_client.set_cookie("localhost", "test_cookie", "hello")
response = app_client.get("/v1.0/test-cookie-param")
assert response.status_code == 200
assert response.json == {"cookie_value": "hello"}