Browse Source

Refactor OpenAPI tests, prepare for Pydantic v2 (#9503)

*  Refactor OpenAPI tests, move inline, prepare for Pydantic v2 tests

*  Fix test module loading for conditional OpenAPI

* 🐛 Fix missing pytest marker

*  Fix test for coverage
pull/9504/head
Sebastián Ramírez 2 years ago
committed by GitHub
parent
commit
50c1a928fb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      tests/test_additional_properties.py
  2. 27
      tests/test_additional_response_extra.py
  3. 24
      tests/test_additional_responses_custom_model_in_callback.py
  4. 21
      tests/test_additional_responses_custom_validationerror.py
  5. 21
      tests/test_additional_responses_default_validationerror.py
  6. 21
      tests/test_additional_responses_response_class.py
  7. 73
      tests/test_additional_responses_router.py
  8. 195
      tests/test_annotated.py
  9. 107
      tests/test_application.py
  10. 55
      tests/test_custom_route_class.py
  11. 91
      tests/test_dependency_duplicates.py
  12. 24
      tests/test_deprecated_openapi_prefix.py
  13. 29
      tests/test_duplicate_models_openapi.py
  14. 100
      tests/test_extra_routes.py
  15. 59
      tests/test_filter_pydantic_sub_model.py
  16. 27
      tests/test_get_request_body.py
  17. 1238
      tests/test_include_router_defaults_overrides.py
  18. 68
      tests/test_modules_same_name_body/test_main.py
  19. 130
      tests/test_multi_body_errors.py
  20. 70
      tests/test_multi_query_errors.py
  21. 27
      tests/test_openapi_query_parameter_extension.py
  22. 23
      tests/test_openapi_route_extensions.py
  23. 21
      tests/test_openapi_servers.py
  24. 26
      tests/test_param_in_path_and_dependency.py
  25. 39
      tests/test_put_no_body.py
  26. 30
      tests/test_repeated_parameter_alias.py
  27. 27
      tests/test_reponse_set_reponse_code_empty.py
  28. 151
      tests/test_response_by_alias.py
  29. 21
      tests/test_response_class_no_mediatype.py
  30. 35
      tests/test_response_code_no_body.py
  31. 767
      tests/test_response_model_as_return_annotation.py
  32. 38
      tests/test_response_model_sub_types.py
  33. 103
      tests/test_schema_extra_examples.py
  34. 41
      tests/test_security_api_key_cookie.py
  35. 41
      tests/test_security_api_key_cookie_description.py
  36. 41
      tests/test_security_api_key_cookie_optional.py
  37. 36
      tests/test_security_api_key_header.py
  38. 36
      tests/test_security_api_key_header_description.py
  39. 36
      tests/test_security_api_key_header_optional.py
  40. 36
      tests/test_security_api_key_query.py
  41. 36
      tests/test_security_api_key_query_description.py
  42. 36
      tests/test_security_api_key_query_optional.py
  43. 36
      tests/test_security_http_base.py
  44. 36
      tests/test_security_http_base_description.py
  45. 36
      tests/test_security_http_base_optional.py
  46. 56
      tests/test_security_http_basic_optional.py
  47. 56
      tests/test_security_http_basic_realm.py
  48. 68
      tests/test_security_http_basic_realm_description.py
  49. 48
      tests/test_security_http_bearer.py
  50. 48
      tests/test_security_http_bearer_description.py
  51. 48
      tests/test_security_http_bearer_optional.py
  52. 52
      tests/test_security_http_digest.py
  53. 52
      tests/test_security_http_digest_description.py
  54. 52
      tests/test_security_http_digest_optional.py
  55. 196
      tests/test_security_oauth2.py
  56. 48
      tests/test_security_oauth2_authorization_code_bearer.py
  57. 48
      tests/test_security_oauth2_authorization_code_bearer_description.py
  58. 196
      tests/test_security_oauth2_optional.py
  59. 196
      tests/test_security_oauth2_optional_description.py
  60. 48
      tests/test_security_oauth2_password_bearer_optional.py
  61. 48
      tests/test_security_oauth2_password_bearer_optional_description.py
  62. 53
      tests/test_security_openid_connect.py
  63. 48
      tests/test_security_openid_connect_description.py
  64. 53
      tests/test_security_openid_connect_optional.py
  65. 92
      tests/test_starlette_exception.py
  66. 41
      tests/test_sub_callbacks.py
  67. 112
      tests/test_tuples.py
  68. 40
      tests/test_tutorial/test_additional_responses/test_tutorial001.py
  69. 46
      tests/test_tutorial/test_additional_responses/test_tutorial002.py
  70. 45
      tests/test_tutorial/test_additional_responses/test_tutorial003.py
  71. 46
      tests/test_tutorial/test_additional_responses/test_tutorial004.py
  72. 54
      tests/test_tutorial/test_async_sql_databases/test_tutorial001.py
  73. 24
      tests/test_tutorial/test_behind_a_proxy/test_tutorial001.py
  74. 24
      tests/test_tutorial/test_behind_a_proxy/test_tutorial002.py
  75. 29
      tests/test_tutorial/test_behind_a_proxy/test_tutorial003.py
  76. 29
      tests/test_tutorial/test_behind_a_proxy/test_tutorial004.py
  77. 323
      tests/test_tutorial/test_bigger_applications/test_main.py
  78. 323
      tests/test_tutorial/test_bigger_applications/test_main_an.py
  79. 357
      tests/test_tutorial/test_bigger_applications/test_main_an_py39.py
  80. 166
      tests/test_tutorial/test_body/test_tutorial001.py
  81. 168
      tests/test_tutorial/test_body/test_tutorial001_py310.py
  82. 123
      tests/test_tutorial/test_body_fields/test_tutorial001.py
  83. 123
      tests/test_tutorial/test_body_fields/test_tutorial001_an.py
  84. 144
      tests/test_tutorial/test_body_fields/test_tutorial001_an_py310.py
  85. 144
      tests/test_tutorial/test_body_fields/test_tutorial001_an_py39.py
  86. 144
      tests/test_tutorial/test_body_fields/test_tutorial001_py310.py
  87. 96
      tests/test_tutorial/test_body_multiple_params/test_tutorial001.py
  88. 96
      tests/test_tutorial/test_body_multiple_params/test_tutorial001_an.py
  89. 116
      tests/test_tutorial/test_body_multiple_params/test_tutorial001_an_py310.py
  90. 116
      tests/test_tutorial/test_body_multiple_params/test_tutorial001_an_py39.py
  91. 116
      tests/test_tutorial/test_body_multiple_params/test_tutorial001_py310.py
  92. 176
      tests/test_tutorial/test_body_multiple_params/test_tutorial003.py
  93. 176
      tests/test_tutorial/test_body_multiple_params/test_tutorial003_an.py
  94. 196
      tests/test_tutorial/test_body_multiple_params/test_tutorial003_an_py310.py
  95. 196
      tests/test_tutorial/test_body_multiple_params/test_tutorial003_an_py39.py
  96. 196
      tests/test_tutorial/test_body_multiple_params/test_tutorial003_py310.py
  97. 60
      tests/test_tutorial/test_body_nested_models/test_tutorial009.py
  98. 82
      tests/test_tutorial/test_body_nested_models/test_tutorial009_py39.py
  99. 66
      tests/test_tutorial/test_body_updates/test_tutorial001.py
  100. 88
      tests/test_tutorial/test_body_updates/test_tutorial001_py310.py

27
tests/test_additional_properties.py

@ -19,7 +19,16 @@ def foo(items: Items):
client = TestClient(app)
openapi_schema = {
def test_additional_properties_post():
response = client.post("/foo", json={"items": {"foo": 1, "bar": 2}})
assert response.status_code == 200, response.text
assert response.json() == {"foo": 1, "bar": 2}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -76,7 +85,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -96,15 +107,3 @@ openapi_schema = {
}
},
}
def test_additional_properties_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_additional_properties_post():
response = client.post("/foo", json={"items": {"foo": 1, "bar": 2}})
assert response.status_code == 200, response.text
assert response.json() == {"foo": 1, "bar": 2}

27
tests/test_additional_response_extra.py

@ -17,8 +17,19 @@ router.include_router(sub_router, prefix="/items")
app.include_router(router)
client = TestClient(app)
def test_path_operation():
response = client.get("/items/")
assert response.status_code == 200, response.text
assert response.json() == {"id": "foo"}
openapi_schema = {
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -36,17 +47,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_path_operation():
response = client.get("/items/")
assert response.status_code == 200, response.text
assert response.json() == {"id": "foo"}

24
tests/test_additional_responses_custom_model_in_callback.py

@ -25,7 +25,13 @@ def main_route(callback_url: HttpUrl):
pass # pragma: no cover
openapi_schema = {
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -82,7 +88,9 @@ openapi_schema = {
},
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
"content": {
"application/json": {"schema": {}}
},
},
},
}
@ -119,7 +127,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -128,11 +138,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema

21
tests/test_additional_responses_custom_validationerror.py

@ -30,7 +30,13 @@ async def a(id):
pass # pragma: no cover
openapi_schema = {
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -41,7 +47,9 @@ openapi_schema = {
"description": "Error",
"content": {
"application/vnd.api+json": {
"schema": {"$ref": "#/components/schemas/JsonApiError"}
"schema": {
"$ref": "#/components/schemas/JsonApiError"
}
}
},
},
@ -89,12 +97,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema

21
tests/test_additional_responses_default_validationerror.py

@ -9,7 +9,13 @@ async def a(id):
pass # pragma: no cover
openapi_schema = {
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -54,7 +60,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -74,12 +82,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema

21
tests/test_additional_responses_response_class.py

@ -35,7 +35,13 @@ async def b():
pass # pragma: no cover
openapi_schema = {
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -46,7 +52,9 @@ openapi_schema = {
"description": "Error",
"content": {
"application/vnd.api+json": {
"schema": {"$ref": "#/components/schemas/JsonApiError"}
"schema": {
"$ref": "#/components/schemas/JsonApiError"
}
}
},
},
@ -106,12 +114,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema

73
tests/test_additional_responses_router.py

@ -53,7 +53,38 @@ async def d():
app.include_router(router)
openapi_schema = {
client = TestClient(app)
def test_a():
response = client.get("/a")
assert response.status_code == 200, response.text
assert response.json() == "a"
def test_b():
response = client.get("/b")
assert response.status_code == 200, response.text
assert response.json() == "b"
def test_c():
response = client.get("/c")
assert response.status_code == 200, response.text
assert response.json() == "c"
def test_d():
response = client.get("/d")
assert response.status_code == 200, response.text
assert response.json() == "d"
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -107,7 +138,9 @@ openapi_schema = {
"description": "Server Error",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/ResponseModel"}
"schema": {
"$ref": "#/components/schemas/ResponseModel"
}
}
},
},
@ -119,7 +152,9 @@ openapi_schema = {
"description": "Default Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/ResponseModel"}
"schema": {
"$ref": "#/components/schemas/ResponseModel"
}
}
},
},
@ -140,35 +175,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_a():
response = client.get("/a")
assert response.status_code == 200, response.text
assert response.json() == "a"
def test_b():
response = client.get("/b")
assert response.status_code == 200, response.text
assert response.json() == "b"
def test_c():
response = client.get("/c")
assert response.status_code == 200, response.text
assert response.json() == "c"
def test_d():
response = client.get("/d")
assert response.status_code == 200, response.text
assert response.json() == "d"

195
tests/test_annotated.py

@ -28,7 +28,96 @@ async def unrelated(foo: Annotated[str, object()]):
client = TestClient(app)
openapi_schema = {
foo_is_missing = {
"detail": [
{
"loc": ["query", "foo"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
foo_is_short = {
"detail": [
{
"ctx": {"limit_value": 1},
"loc": ["query", "foo"],
"msg": "ensure this value has at least 1 characters",
"type": "value_error.any_str.min_length",
}
]
}
@pytest.mark.parametrize(
"path,expected_status,expected_response",
[
("/default", 200, {"foo": "foo"}),
("/default?foo=bar", 200, {"foo": "bar"}),
("/required?foo=bar", 200, {"foo": "bar"}),
("/required", 422, foo_is_missing),
("/required?foo=", 422, foo_is_short),
("/multiple?foo=bar", 200, {"foo": "bar"}),
("/multiple", 422, foo_is_missing),
("/multiple?foo=", 422, foo_is_short),
("/unrelated?foo=bar", 200, {"foo": "bar"}),
("/unrelated", 422, foo_is_missing),
],
)
def test_get(path, expected_status, expected_response):
response = client.get(path)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_multiple_path():
app = FastAPI()
@app.get("/test1")
@app.get("/test2")
async def test(var: Annotated[str, Query()] = "bar"):
return {"foo": var}
client = TestClient(app)
response = client.get("/test1")
assert response.status_code == 200
assert response.json() == {"foo": "bar"}
response = client.get("/test1", params={"var": "baz"})
assert response.status_code == 200
assert response.json() == {"foo": "baz"}
response = client.get("/test2")
assert response.status_code == 200
assert response.json() == {"foo": "bar"}
response = client.get("/test2", params={"var": "baz"})
assert response.status_code == 200
assert response.json() == {"foo": "baz"}
def test_nested_router():
app = FastAPI()
router = APIRouter(prefix="/nested")
@router.get("/test")
async def test(var: Annotated[str, Query()] = "bar"):
return {"foo": var}
app.include_router(router)
client = TestClient(app)
response = client.get("/nested/test")
assert response.status_code == 200
assert response.json() == {"foo": "bar"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -39,7 +128,11 @@ openapi_schema = {
"parameters": [
{
"required": False,
"schema": {"title": "Foo", "type": "string", "default": "foo"},
"schema": {
"title": "Foo",
"type": "string",
"default": "foo",
},
"name": "foo",
"in": "query",
}
@ -69,7 +162,11 @@ openapi_schema = {
"parameters": [
{
"required": True,
"schema": {"title": "Foo", "minLength": 1, "type": "string"},
"schema": {
"title": "Foo",
"minLength": 1,
"type": "string",
},
"name": "foo",
"in": "query",
}
@ -99,7 +196,11 @@ openapi_schema = {
"parameters": [
{
"required": True,
"schema": {"title": "Foo", "minLength": 1, "type": "string"},
"schema": {
"title": "Foo",
"minLength": 1,
"type": "string",
},
"name": "foo",
"in": "query",
}
@ -174,7 +275,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -183,85 +286,3 @@ openapi_schema = {
}
},
}
foo_is_missing = {
"detail": [
{
"loc": ["query", "foo"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
foo_is_short = {
"detail": [
{
"ctx": {"limit_value": 1},
"loc": ["query", "foo"],
"msg": "ensure this value has at least 1 characters",
"type": "value_error.any_str.min_length",
}
]
}
@pytest.mark.parametrize(
"path,expected_status,expected_response",
[
("/default", 200, {"foo": "foo"}),
("/default?foo=bar", 200, {"foo": "bar"}),
("/required?foo=bar", 200, {"foo": "bar"}),
("/required", 422, foo_is_missing),
("/required?foo=", 422, foo_is_short),
("/multiple?foo=bar", 200, {"foo": "bar"}),
("/multiple", 422, foo_is_missing),
("/multiple?foo=", 422, foo_is_short),
("/unrelated?foo=bar", 200, {"foo": "bar"}),
("/unrelated", 422, foo_is_missing),
("/openapi.json", 200, openapi_schema),
],
)
def test_get(path, expected_status, expected_response):
response = client.get(path)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_multiple_path():
@app.get("/test1")
@app.get("/test2")
async def test(var: Annotated[str, Query()] = "bar"):
return {"foo": var}
response = client.get("/test1")
assert response.status_code == 200
assert response.json() == {"foo": "bar"}
response = client.get("/test1", params={"var": "baz"})
assert response.status_code == 200
assert response.json() == {"foo": "baz"}
response = client.get("/test2")
assert response.status_code == 200
assert response.json() == {"foo": "bar"}
response = client.get("/test2", params={"var": "baz"})
assert response.status_code == 200
assert response.json() == {"foo": "baz"}
def test_nested_router():
app = FastAPI()
router = APIRouter(prefix="/nested")
@router.get("/test")
async def test(var: Annotated[str, Query()] = "bar"):
return {"foo": var}
app.include_router(router)
client = TestClient(app)
response = client.get("/nested/test")
assert response.status_code == 200
assert response.json() == {"foo": "bar"}

107
tests/test_application.py

@ -5,7 +5,56 @@ from .main import app
client = TestClient(app)
openapi_schema = {
@pytest.mark.parametrize(
"path,expected_status,expected_response",
[
("/api_route", 200, {"message": "Hello World"}),
("/non_decorated_route", 200, {"message": "Hello World"}),
("/nonexistent", 404, {"detail": "Not Found"}),
],
)
def test_get_path(path, expected_status, expected_response):
response = client.get(path)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_swagger_ui():
response = client.get("/docs")
assert response.status_code == 200, response.text
assert response.headers["content-type"] == "text/html; charset=utf-8"
assert "swagger-ui-dist" in response.text
assert (
"oauth2RedirectUrl: window.location.origin + '/docs/oauth2-redirect'"
in response.text
)
def test_swagger_ui_oauth2_redirect():
response = client.get("/docs/oauth2-redirect")
assert response.status_code == 200, response.text
assert response.headers["content-type"] == "text/html; charset=utf-8"
assert "window.opener.swaggerUIRedirectOauth2" in response.text
def test_redoc():
response = client.get("/redoc")
assert response.status_code == 200, response.text
assert response.headers["content-type"] == "text/html; charset=utf-8"
assert "redoc@next" in response.text
def test_enum_status_code_response():
response = client.get("/enum-status-code")
assert response.status_code == 201, response.text
assert response.json() == "foo bar"
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -951,7 +1000,11 @@ openapi_schema = {
"parameters": [
{
"required": False,
"schema": {"title": "Query", "type": "integer", "default": 10},
"schema": {
"title": "Query",
"type": "integer",
"default": 10,
},
"name": "query",
"in": "query",
}
@ -1106,7 +1159,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -1126,49 +1181,3 @@ openapi_schema = {
}
},
}
@pytest.mark.parametrize(
"path,expected_status,expected_response",
[
("/api_route", 200, {"message": "Hello World"}),
("/non_decorated_route", 200, {"message": "Hello World"}),
("/nonexistent", 404, {"detail": "Not Found"}),
("/openapi.json", 200, openapi_schema),
],
)
def test_get_path(path, expected_status, expected_response):
response = client.get(path)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_swagger_ui():
response = client.get("/docs")
assert response.status_code == 200, response.text
assert response.headers["content-type"] == "text/html; charset=utf-8"
assert "swagger-ui-dist" in response.text
assert (
"oauth2RedirectUrl: window.location.origin + '/docs/oauth2-redirect'"
in response.text
)
def test_swagger_ui_oauth2_redirect():
response = client.get("/docs/oauth2-redirect")
assert response.status_code == 200, response.text
assert response.headers["content-type"] == "text/html; charset=utf-8"
assert "window.opener.swaggerUIRedirectOauth2" in response.text
def test_redoc():
response = client.get("/redoc")
assert response.status_code == 200, response.text
assert response.headers["content-type"] == "text/html; charset=utf-8"
assert "redoc@next" in response.text
def test_enum_status_code_response():
response = client.get("/enum-status-code")
assert response.status_code == 201, response.text
assert response.json() == "foo bar"

55
tests/test_custom_route_class.py

@ -46,7 +46,35 @@ app.include_router(router=router_a, prefix="/a")
client = TestClient(app)
openapi_schema = {
@pytest.mark.parametrize(
"path,expected_status,expected_response",
[
("/a", 200, {"msg": "A"}),
("/a/b", 200, {"msg": "B"}),
("/a/b/c", 200, {"msg": "C"}),
],
)
def test_get_path(path, expected_status, expected_response):
response = client.get(path)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_route_classes():
routes = {}
for r in app.router.routes:
assert isinstance(r, Route)
routes[r.path] = r
assert getattr(routes["/a/"], "x_type") == "A" # noqa: B009
assert getattr(routes["/a/b/"], "x_type") == "B" # noqa: B009
assert getattr(routes["/a/b/c/"], "x_type") == "C" # noqa: B009
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -88,28 +116,3 @@ openapi_schema = {
},
},
}
@pytest.mark.parametrize(
"path,expected_status,expected_response",
[
("/a", 200, {"msg": "A"}),
("/a/b", 200, {"msg": "B"}),
("/a/b/c", 200, {"msg": "C"}),
("/openapi.json", 200, openapi_schema),
],
)
def test_get_path(path, expected_status, expected_response):
response = client.get(path)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_route_classes():
routes = {}
for r in app.router.routes:
assert isinstance(r, Route)
routes[r.path] = r
assert getattr(routes["/a/"], "x_type") == "A" # noqa: B009
assert getattr(routes["/a/b/"], "x_type") == "B" # noqa: B009
assert getattr(routes["/a/b/c/"], "x_type") == "C" # noqa: B009

91
tests/test_dependency_duplicates.py

@ -44,7 +44,48 @@ async def no_duplicates_sub(
return [item, sub_items]
openapi_schema = {
def test_no_duplicates_invalid():
response = client.post("/no-duplicates", json={"item": {"data": "myitem"}})
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["body", "item2"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
def test_no_duplicates():
response = client.post(
"/no-duplicates",
json={"item": {"data": "myitem"}, "item2": {"data": "myitem2"}},
)
assert response.status_code == 200, response.text
assert response.json() == [{"data": "myitem"}, {"data": "myitem2"}]
def test_duplicates():
response = client.post("/with-duplicates", json={"data": "myitem"})
assert response.status_code == 200, response.text
assert response.json() == [{"data": "myitem"}, {"data": "myitem"}]
def test_sub_duplicates():
response = client.post("/with-duplicates-sub", json={"data": "myitem"})
assert response.status_code == 200, response.text
assert response.json() == [
{"data": "myitem"},
[{"data": "myitem"}, {"data": "myitem"}],
]
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -177,7 +218,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -186,47 +229,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_no_duplicates_invalid():
response = client.post("/no-duplicates", json={"item": {"data": "myitem"}})
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["body", "item2"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
def test_no_duplicates():
response = client.post(
"/no-duplicates",
json={"item": {"data": "myitem"}, "item2": {"data": "myitem2"}},
)
assert response.status_code == 200, response.text
assert response.json() == [{"data": "myitem"}, {"data": "myitem2"}]
def test_duplicates():
response = client.post("/with-duplicates", json={"data": "myitem"})
assert response.status_code == 200, response.text
assert response.json() == [{"data": "myitem"}, {"data": "myitem"}]
def test_sub_duplicates():
response = client.post("/with-duplicates-sub", json={"data": "myitem"})
assert response.status_code == 200, response.text
assert response.json() == [
{"data": "myitem"},
[{"data": "myitem"}, {"data": "myitem"}],
]

24
tests/test_deprecated_openapi_prefix.py

@ -11,7 +11,17 @@ def read_main(request: Request):
client = TestClient(app)
openapi_schema = {
def test_main():
response = client.get("/app")
assert response.status_code == 200
assert response.json() == {"message": "Hello World", "root_path": "/api/v1"}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -30,15 +40,3 @@ openapi_schema = {
},
"servers": [{"url": "/api/v1"}],
}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == openapi_schema
def test_main():
response = client.get("/app")
assert response.status_code == 200
assert response.json() == {"message": "Hello World", "root_path": "/api/v1"}

29
tests/test_duplicate_models_openapi.py

@ -23,7 +23,19 @@ def f():
return {"c": {}, "d": {"a": {}}}
openapi_schema = {
client = TestClient(app)
def test_get_api_route():
response = client.get("/")
assert response.status_code == 200, response.text
assert response.json() == {"c": {}, "d": {"a": {}}}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -65,18 +77,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_get_api_route():
response = client.get("/")
assert response.status_code == 200, response.text
assert response.json() == {"c": {}, "d": {"a": {}}}

100
tests/test_extra_routes.py

@ -52,7 +52,53 @@ def trace_item(item_id: str):
client = TestClient(app)
openapi_schema = {
def test_get_api_route():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo"}
def test_get_api_route_not_decorated():
response = client.get("/items-not-decorated/foo")
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo"}
def test_delete():
response = client.request("DELETE", "/items/foo", json={"name": "Foo"})
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo", "item": {"name": "Foo", "price": None}}
def test_head():
response = client.head("/items/foo")
assert response.status_code == 200, response.text
assert response.headers["x-fastapi-item-id"] == "foo"
def test_options():
response = client.options("/items/foo")
assert response.status_code == 200, response.text
assert response.headers["x-fastapi-item-id"] == "foo"
def test_patch():
response = client.patch("/items/foo", json={"name": "Foo"})
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo", "item": {"name": "Foo", "price": None}}
def test_trace():
response = client.request("trace", "/items/foo")
assert response.status_code == 200, response.text
assert response.headers["content-type"] == "message/http"
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -292,7 +338,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -312,51 +360,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_get_api_route():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo"}
def test_get_api_route_not_decorated():
response = client.get("/items-not-decorated/foo")
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo"}
def test_delete():
response = client.request("DELETE", "/items/foo", json={"name": "Foo"})
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo", "item": {"name": "Foo", "price": None}}
def test_head():
response = client.head("/items/foo")
assert response.status_code == 200, response.text
assert response.headers["x-fastapi-item-id"] == "foo"
def test_options():
response = client.options("/items/foo")
assert response.status_code == 200, response.text
assert response.headers["x-fastapi-item-id"] == "foo"
def test_patch():
response = client.patch("/items/foo", json={"name": "Foo"})
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo", "item": {"name": "Foo", "price": None}}
def test_trace():
response = client.request("trace", "/items/foo")
assert response.status_code == 200, response.text
assert response.headers["content-type"] == "message/http"

59
tests/test_filter_pydantic_sub_model.py

@ -40,7 +40,32 @@ async def get_model_a(name: str, model_c=Depends(get_model_c)):
client = TestClient(app)
openapi_schema = {
def test_filter_sub_model():
response = client.get("/model/modelA")
assert response.status_code == 200, response.text
assert response.json() == {
"name": "modelA",
"description": "model-a-desc",
"model_b": {"username": "test-user"},
}
def test_validator_is_cloned():
with pytest.raises(ValidationError) as err:
client.get("/model/modelX")
assert err.value.errors() == [
{
"loc": ("response", "name"),
"msg": "name must end in A",
"type": "value_error",
}
]
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -116,7 +141,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -125,31 +152,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_filter_sub_model():
response = client.get("/model/modelA")
assert response.status_code == 200, response.text
assert response.json() == {
"name": "modelA",
"description": "model-a-desc",
"model_b": {"username": "test-user"},
}
def test_validator_is_cloned():
with pytest.raises(ValidationError) as err:
client.get("/model/modelX")
assert err.value.errors() == [
{
"loc": ("response", "name"),
"msg": "name must end in A",
"type": "value_error",
}
]

27
tests/test_get_request_body.py

@ -19,7 +19,16 @@ async def create_item(product: Product):
client = TestClient(app)
openapi_schema = {
def test_get_with_body():
body = {"name": "Foo", "description": "Some description", "price": 5.5}
response = client.request("GET", "/product", json=body)
assert response.json() == body
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -85,7 +94,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -94,15 +105,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_get_with_body():
body = {"name": "Foo", "description": "Some description", "price": 5.5}
response = client.request("GET", "/product", json=body)
assert response.json() == body

1238
tests/test_include_router_defaults_overrides.py

File diff suppressed because it is too large

68
tests/test_modules_same_name_body/test_main.py

@ -4,7 +4,37 @@ from .app.main import app
client = TestClient(app)
openapi_schema = {
def test_post_a():
data = {"a": 2, "b": "foo"}
response = client.post("/a/compute", json=data)
assert response.status_code == 200, response.text
data = response.json()
def test_post_a_invalid():
data = {"a": "bar", "b": "foo"}
response = client.post("/a/compute", json=data)
assert response.status_code == 422, response.text
def test_post_b():
data = {"a": 2, "b": "foo"}
response = client.post("/b/compute/", json=data)
assert response.status_code == 200, response.text
data = response.json()
def test_post_b_invalid():
data = {"a": "bar", "b": "foo"}
response = client.post("/b/compute/", json=data)
assert response.status_code == 422, response.text
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -101,7 +131,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -121,35 +153,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_post_a():
data = {"a": 2, "b": "foo"}
response = client.post("/a/compute", json=data)
assert response.status_code == 200, response.text
data = response.json()
def test_post_a_invalid():
data = {"a": "bar", "b": "foo"}
response = client.post("/a/compute", json=data)
assert response.status_code == 422, response.text
def test_post_b():
data = {"a": 2, "b": "foo"}
response = client.post("/b/compute/", json=data)
assert response.status_code == 200, response.text
data = response.json()
def test_post_b_invalid():
data = {"a": "bar", "b": "foo"}
response = client.post("/b/compute/", json=data)
assert response.status_code == 422, response.text

130
tests/test_multi_body_errors.py

@ -21,7 +21,65 @@ def save_item_no_body(item: List[Item]):
client = TestClient(app)
openapi_schema = {
single_error = {
"detail": [
{
"ctx": {"limit_value": 0.0},
"loc": ["body", 0, "age"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
multiple_errors = {
"detail": [
{
"loc": ["body", 0, "name"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", 0, "age"],
"msg": "value is not a valid decimal",
"type": "type_error.decimal",
},
{
"loc": ["body", 1, "name"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", 1, "age"],
"msg": "value is not a valid decimal",
"type": "type_error.decimal",
},
]
}
def test_put_correct_body():
response = client.post("/items/", json=[{"name": "Foo", "age": 5}])
assert response.status_code == 200, response.text
assert response.json() == {"item": [{"name": "Foo", "age": 5}]}
def test_jsonable_encoder_requiring_error():
response = client.post("/items/", json=[{"name": "Foo", "age": -1.0}])
assert response.status_code == 422, response.text
assert response.json() == single_error
def test_put_incorrect_body_multiple():
response = client.post("/items/", json=[{"age": "five"}, {"age": "six"}])
assert response.status_code == 422, response.text
assert response.json() == multiple_errors
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -68,7 +126,11 @@ openapi_schema = {
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"age": {"title": "Age", "exclusiveMinimum": 0.0, "type": "number"},
"age": {
"title": "Age",
"exclusiveMinimum": 0.0,
"type": "number",
},
},
},
"ValidationError": {
@ -79,7 +141,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -99,63 +163,3 @@ openapi_schema = {
}
},
}
single_error = {
"detail": [
{
"ctx": {"limit_value": 0.0},
"loc": ["body", 0, "age"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
multiple_errors = {
"detail": [
{
"loc": ["body", 0, "name"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", 0, "age"],
"msg": "value is not a valid decimal",
"type": "type_error.decimal",
},
{
"loc": ["body", 1, "name"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", 1, "age"],
"msg": "value is not a valid decimal",
"type": "type_error.decimal",
},
]
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_put_correct_body():
response = client.post("/items/", json=[{"name": "Foo", "age": 5}])
assert response.status_code == 200, response.text
assert response.json() == {"item": [{"name": "Foo", "age": 5}]}
def test_jsonable_encoder_requiring_error():
response = client.post("/items/", json=[{"name": "Foo", "age": -1.0}])
assert response.status_code == 422, response.text
assert response.json() == single_error
def test_put_incorrect_body_multiple():
response = client.post("/items/", json=[{"age": "five"}, {"age": "six"}])
assert response.status_code == 422, response.text
assert response.json() == multiple_errors

70
tests/test_multi_query_errors.py

@ -14,7 +14,38 @@ def read_items(q: List[int] = Query(default=None)):
client = TestClient(app)
openapi_schema = {
multiple_errors = {
"detail": [
{
"loc": ["query", "q", 0],
"msg": "value is not a valid integer",
"type": "type_error.integer",
},
{
"loc": ["query", "q", 1],
"msg": "value is not a valid integer",
"type": "type_error.integer",
},
]
}
def test_multi_query():
response = client.get("/items/?q=5&q=6")
assert response.status_code == 200, response.text
assert response.json() == {"q": [5, 6]}
def test_multi_query_incorrect():
response = client.get("/items/?q=five&q=six")
assert response.status_code == 422, response.text
assert response.json() == multiple_errors
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -63,7 +94,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -83,36 +116,3 @@ openapi_schema = {
}
},
}
multiple_errors = {
"detail": [
{
"loc": ["query", "q", 0],
"msg": "value is not a valid integer",
"type": "type_error.integer",
},
{
"loc": ["query", "q", 1],
"msg": "value is not a valid integer",
"type": "type_error.integer",
},
]
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_multi_query():
response = client.get("/items/?q=5&q=6")
assert response.status_code == 200, response.text
assert response.json() == {"q": [5, 6]}
def test_multi_query_incorrect():
response = client.get("/items/?q=five&q=six")
assert response.status_code == 422, response.text
assert response.json() == multiple_errors

27
tests/test_openapi_query_parameter_extension.py

@ -32,7 +32,16 @@ def route_with_extra_query_parameters(standard_query_param: Optional[int] = 50):
client = TestClient(app)
openapi_schema = {
def test_get_route():
response = client.get("/")
assert response.status_code == 200, response.text
assert response.json() == {}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -104,7 +113,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -113,15 +124,3 @@ openapi_schema = {
}
},
}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_get_route():
response = client.get("/")
assert response.status_code == 200, response.text
assert response.json() == {}

23
tests/test_openapi_route_extensions.py

@ -12,7 +12,16 @@ def route_with_extras():
client = TestClient(app)
openapi_schema = {
def test_get_route():
response = client.get("/")
assert response.status_code == 200, response.text
assert response.json() == {}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -31,15 +40,3 @@ openapi_schema = {
},
},
}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_get_route():
response = client.get("/")
assert response.status_code == 200, response.text
assert response.json() == {}

21
tests/test_openapi_servers.py

@ -21,7 +21,15 @@ def foo():
client = TestClient(app)
openapi_schema = {
def test_app():
response = client.get("/foo")
assert response.status_code == 200, response.text
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"servers": [
@ -47,14 +55,3 @@ openapi_schema = {
}
},
}
def test_openapi_servers():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_app():
response = client.get("/foo")
assert response.status_code == 200, response.text

26
tests/test_param_in_path_and_dependency.py

@ -15,7 +15,16 @@ async def read_users(user_id: int):
client = TestClient(app)
openapi_schema = {
def test_read_users():
response = client.get("/users/42")
assert response.status_code == 200, response.text
def test_openapi_schema():
response = client.get("/openapi.json")
data = response.json()
assert data == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -71,7 +80,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -80,14 +91,3 @@ openapi_schema = {
}
},
}
def test_reused_param():
response = client.get("/openapi.json")
data = response.json()
assert data == openapi_schema
def test_read_users():
response = client.get("/users/42")
assert response.status_code == 200, response.text

39
tests/test_put_no_body.py

@ -12,7 +12,22 @@ def save_item_no_body(item_id: str):
client = TestClient(app)
openapi_schema = {
def test_put_no_body():
response = client.put("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo"}
def test_put_no_body_with_body():
response = client.put("/items/foo", json={"name": "Foo"})
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -57,7 +72,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -77,21 +94,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_put_no_body():
response = client.put("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo"}
def test_put_no_body_with_body():
response = client.put("/items/foo", json={"name": "Foo"})
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "foo"}

30
tests/test_repeated_parameter_alias.py

@ -14,7 +14,18 @@ def get_parameters_with_repeated_aliases(
client = TestClient(app)
openapi_schema = {
def test_get_parameters():
response = client.get("/test_path", params={"repeated_alias": "test_query"})
assert response.status_code == 200, response.text
assert response.json() == {"path": "test_path", "query": "test_query"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == status.HTTP_200_OK
actual_schema = response.json()
assert actual_schema == {
"components": {
"schemas": {
"HTTPValidationError": {
@ -31,7 +42,9 @@ openapi_schema = {
"ValidationError": {
"properties": {
"loc": {
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
"title": "Location",
"type": "array",
},
@ -85,16 +98,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == status.HTTP_200_OK
actual_schema = response.json()
assert actual_schema == openapi_schema
def test_get_parameters():
response = client.get("/test_path", params={"repeated_alias": "test_query"})
assert response.status_code == 200, response.text
assert response.json() == {"path": "test_path", "query": "test_query"}

27
tests/test_reponse_set_reponse_code_empty.py

@ -22,7 +22,16 @@ async def delete_deployment(
client = TestClient(app)
openapi_schema = {
def test_dependency_set_status_code():
response = client.delete("/1")
assert response.status_code == 400 and response.content
assert response.json() == {"msg": "Status overwritten", "id": 1}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -75,7 +84,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -84,15 +95,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_dependency_set_status_code():
response = client.delete("/1")
assert response.status_code == 400 and response.content
assert response.json() == {"msg": "Status overwritten", "id": 1}

151
tests/test_response_by_alias.py

@ -68,7 +68,76 @@ def no_alias_list():
return [{"name": "Foo"}, {"name": "Bar"}]
openapi_schema = {
client = TestClient(app)
def test_read_dict():
response = client.get("/dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo"}
def test_read_model():
response = client.get("/model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo"}
def test_read_list():
response = client.get("/list")
assert response.status_code == 200, response.text
assert response.json() == [
{"name": "Foo"},
{"name": "Bar"},
]
def test_read_dict_by_alias():
response = client.get("/by-alias/dict")
assert response.status_code == 200, response.text
assert response.json() == {"alias": "Foo"}
def test_read_model_by_alias():
response = client.get("/by-alias/model")
assert response.status_code == 200, response.text
assert response.json() == {"alias": "Foo"}
def test_read_list_by_alias():
response = client.get("/by-alias/list")
assert response.status_code == 200, response.text
assert response.json() == [
{"alias": "Foo"},
{"alias": "Bar"},
]
def test_read_dict_no_alias():
response = client.get("/no-alias/dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo"}
def test_read_model_no_alias():
response = client.get("/no-alias/model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo"}
def test_read_list_no_alias():
response = client.get("/no-alias/list")
assert response.status_code == 200, response.text
assert response.json() == [
{"name": "Foo"},
{"name": "Bar"},
]
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -185,7 +254,9 @@ openapi_schema = {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/ModelNoAlias"}
"schema": {
"$ref": "#/components/schemas/ModelNoAlias"
}
}
},
}
@ -201,7 +272,9 @@ openapi_schema = {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/ModelNoAlias"}
"schema": {
"$ref": "#/components/schemas/ModelNoAlias"
}
}
},
}
@ -249,75 +322,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_read_dict():
response = client.get("/dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo"}
def test_read_model():
response = client.get("/model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo"}
def test_read_list():
response = client.get("/list")
assert response.status_code == 200, response.text
assert response.json() == [
{"name": "Foo"},
{"name": "Bar"},
]
def test_read_dict_by_alias():
response = client.get("/by-alias/dict")
assert response.status_code == 200, response.text
assert response.json() == {"alias": "Foo"}
def test_read_model_by_alias():
response = client.get("/by-alias/model")
assert response.status_code == 200, response.text
assert response.json() == {"alias": "Foo"}
def test_read_list_by_alias():
response = client.get("/by-alias/list")
assert response.status_code == 200, response.text
assert response.json() == [
{"alias": "Foo"},
{"alias": "Bar"},
]
def test_read_dict_no_alias():
response = client.get("/no-alias/dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo"}
def test_read_model_no_alias():
response = client.get("/no-alias/model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo"}
def test_read_list_no_alias():
response = client.get("/no-alias/list")
assert response.status_code == 200, response.text
assert response.json() == [
{"name": "Foo"},
{"name": "Bar"},
]

21
tests/test_response_class_no_mediatype.py

@ -35,7 +35,13 @@ async def b():
pass # pragma: no cover
openapi_schema = {
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -46,7 +52,9 @@ openapi_schema = {
"description": "Error",
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/JsonApiError"}
"schema": {
"$ref": "#/components/schemas/JsonApiError"
}
}
},
},
@ -103,12 +111,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema

35
tests/test_response_code_no_body.py

@ -36,7 +36,20 @@ async def b():
pass # pragma: no cover
openapi_schema = {
client = TestClient(app)
def test_get_response():
response = client.get("/a")
assert response.status_code == 204, response.text
assert "content-length" not in response.headers
assert response.content == b""
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -47,7 +60,9 @@ openapi_schema = {
"description": "Error",
"content": {
"application/vnd.api+json": {
"schema": {"$ref": "#/components/schemas/JsonApiError"}
"schema": {
"$ref": "#/components/schemas/JsonApiError"
}
}
},
},
@ -97,19 +112,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_get_response():
response = client.get("/a")
assert response.status_code == 204, response.text
assert "content-length" not in response.headers
assert response.content == b""

767
tests/test_response_model_as_return_annotation.py

@ -249,7 +249,264 @@ def no_response_model_annotation_json_response_class() -> JSONResponse:
return JSONResponse(content={"foo": "bar"})
openapi_schema = {
client = TestClient(app)
def test_no_response_model_no_annotation_return_model():
response = client.get("/no_response_model-no_annotation-return_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_no_annotation_return_dict():
response = client.get("/no_response_model-no_annotation-return_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_no_annotation_return_same_model():
response = client.get("/response_model-no_annotation-return_same_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_no_annotation_return_exact_dict():
response = client.get("/response_model-no_annotation-return_exact_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_no_annotation_return_invalid_dict():
with pytest.raises(ValidationError):
client.get("/response_model-no_annotation-return_invalid_dict")
def test_response_model_no_annotation_return_invalid_model():
with pytest.raises(ValidationError):
client.get("/response_model-no_annotation-return_invalid_model")
def test_response_model_no_annotation_return_dict_with_extra_data():
response = client.get("/response_model-no_annotation-return_dict_with_extra_data")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_no_annotation_return_submodel_with_extra_data():
response = client.get(
"/response_model-no_annotation-return_submodel_with_extra_data"
)
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_annotation_return_same_model():
response = client.get("/no_response_model-annotation-return_same_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_annotation_return_exact_dict():
response = client.get("/no_response_model-annotation-return_exact_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_annotation_return_invalid_dict():
with pytest.raises(ValidationError):
client.get("/no_response_model-annotation-return_invalid_dict")
def test_no_response_model_annotation_return_invalid_model():
with pytest.raises(ValidationError):
client.get("/no_response_model-annotation-return_invalid_model")
def test_no_response_model_annotation_return_dict_with_extra_data():
response = client.get("/no_response_model-annotation-return_dict_with_extra_data")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_annotation_return_submodel_with_extra_data():
response = client.get(
"/no_response_model-annotation-return_submodel_with_extra_data"
)
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_none_annotation_return_same_model():
response = client.get("/response_model_none-annotation-return_same_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_none_annotation_return_exact_dict():
response = client.get("/response_model_none-annotation-return_exact_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_none_annotation_return_invalid_dict():
response = client.get("/response_model_none-annotation-return_invalid_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John"}
def test_response_model_none_annotation_return_invalid_model():
response = client.get("/response_model_none-annotation-return_invalid_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo", "price": 42.0}
def test_response_model_none_annotation_return_dict_with_extra_data():
response = client.get("/response_model_none-annotation-return_dict_with_extra_data")
assert response.status_code == 200, response.text
assert response.json() == {
"name": "John",
"surname": "Doe",
"password_hash": "secret",
}
def test_response_model_none_annotation_return_submodel_with_extra_data():
response = client.get(
"/response_model_none-annotation-return_submodel_with_extra_data"
)
assert response.status_code == 200, response.text
assert response.json() == {
"name": "John",
"surname": "Doe",
"password_hash": "secret",
}
def test_response_model_model1_annotation_model2_return_same_model():
response = client.get("/response_model_model1-annotation_model2-return_same_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_model1_annotation_model2_return_exact_dict():
response = client.get("/response_model_model1-annotation_model2-return_exact_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_model1_annotation_model2_return_invalid_dict():
with pytest.raises(ValidationError):
client.get("/response_model_model1-annotation_model2-return_invalid_dict")
def test_response_model_model1_annotation_model2_return_invalid_model():
with pytest.raises(ValidationError):
client.get("/response_model_model1-annotation_model2-return_invalid_model")
def test_response_model_model1_annotation_model2_return_dict_with_extra_data():
response = client.get(
"/response_model_model1-annotation_model2-return_dict_with_extra_data"
)
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_model1_annotation_model2_return_submodel_with_extra_data():
response = client.get(
"/response_model_model1-annotation_model2-return_submodel_with_extra_data"
)
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_filtering_model_annotation_submodel_return_submodel():
response = client.get(
"/response_model_filtering_model-annotation_submodel-return_submodel"
)
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_list_of_model_no_annotation():
response = client.get("/response_model_list_of_model-no_annotation")
assert response.status_code == 200, response.text
assert response.json() == [
{"name": "John", "surname": "Doe"},
{"name": "Jane", "surname": "Does"},
]
def test_no_response_model_annotation_list_of_model():
response = client.get("/no_response_model-annotation_list_of_model")
assert response.status_code == 200, response.text
assert response.json() == [
{"name": "John", "surname": "Doe"},
{"name": "Jane", "surname": "Does"},
]
def test_no_response_model_annotation_forward_ref_list_of_model():
response = client.get("/no_response_model-annotation_forward_ref_list_of_model")
assert response.status_code == 200, response.text
assert response.json() == [
{"name": "John", "surname": "Doe"},
{"name": "Jane", "surname": "Does"},
]
def test_response_model_union_no_annotation_return_model1():
response = client.get("/response_model_union-no_annotation-return_model1")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_union_no_annotation_return_model2():
response = client.get("/response_model_union-no_annotation-return_model2")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo", "price": 42.0}
def test_no_response_model_annotation_union_return_model1():
response = client.get("/no_response_model-annotation_union-return_model1")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_annotation_union_return_model2():
response = client.get("/no_response_model-annotation_union-return_model2")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo", "price": 42.0}
def test_no_response_model_annotation_return_class():
response = client.get("/no_response_model-annotation_response_class")
assert response.status_code == 200, response.text
assert response.text == "Foo"
def test_no_response_model_annotation_json_response_class():
response = client.get("/no_response_model-annotation_json_response_class")
assert response.status_code == 200, response.text
assert response.json() == {"foo": "bar"}
def test_invalid_response_model_field():
app = FastAPI()
with pytest.raises(FastAPIError) as e:
@app.get("/")
def read_root() -> Union[Response, None]:
return Response(content="Foo") # pragma: no cover
assert "valid Pydantic field type" in e.value.args[0]
assert "parameter response_model=None" in e.value.args[0]
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -723,389 +980,129 @@ openapi_schema = {
"content": {
"application/json": {
"schema": {
"title": "Response Response Model Union No Annotation Return Model1 Response Model Union No Annotation Return Model1 Get",
"anyOf": [
{"$ref": "#/components/schemas/User"},
{"$ref": "#/components/schemas/Item"},
],
}
}
},
}
},
}
},
"/response_model_union-no_annotation-return_model2": {
"get": {
"summary": "Response Model Union No Annotation Return Model2",
"operationId": "response_model_union_no_annotation_return_model2_response_model_union_no_annotation_return_model2_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"title": "Response Response Model Union No Annotation Return Model2 Response Model Union No Annotation Return Model2 Get",
"anyOf": [
{"$ref": "#/components/schemas/User"},
{"$ref": "#/components/schemas/Item"},
],
}
}
},
}
},
}
},
"/no_response_model-annotation_union-return_model1": {
"get": {
"summary": "No Response Model Annotation Union Return Model1",
"operationId": "no_response_model_annotation_union_return_model1_no_response_model_annotation_union_return_model1_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"title": "Response No Response Model Annotation Union Return Model1 No Response Model Annotation Union Return Model1 Get",
"anyOf": [
{"$ref": "#/components/schemas/User"},
{"$ref": "#/components/schemas/Item"},
],
}
}
},
}
},
}
},
"/no_response_model-annotation_union-return_model2": {
"get": {
"summary": "No Response Model Annotation Union Return Model2",
"operationId": "no_response_model_annotation_union_return_model2_no_response_model_annotation_union_return_model2_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"title": "Response No Response Model Annotation Union Return Model2 No Response Model Annotation Union Return Model2 Get",
"anyOf": [
{"$ref": "#/components/schemas/User"},
{"$ref": "#/components/schemas/Item"},
],
}
}
},
}
},
}
},
"/no_response_model-annotation_response_class": {
"get": {
"summary": "No Response Model Annotation Response Class",
"operationId": "no_response_model_annotation_response_class_no_response_model_annotation_response_class_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
}
},
"/no_response_model-annotation_json_response_class": {
"get": {
"summary": "No Response Model Annotation Json Response Class",
"operationId": "no_response_model_annotation_json_response_class_no_response_model_annotation_json_response_class_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
}
},
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
},
},
"User": {
"title": "User",
"required": ["name", "surname"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"surname": {"title": "Surname", "type": "string"},
},
},
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_no_response_model_no_annotation_return_model():
response = client.get("/no_response_model-no_annotation-return_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_no_annotation_return_dict():
response = client.get("/no_response_model-no_annotation-return_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_no_annotation_return_same_model():
response = client.get("/response_model-no_annotation-return_same_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_no_annotation_return_exact_dict():
response = client.get("/response_model-no_annotation-return_exact_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_no_annotation_return_invalid_dict():
with pytest.raises(ValidationError):
client.get("/response_model-no_annotation-return_invalid_dict")
def test_response_model_no_annotation_return_invalid_model():
with pytest.raises(ValidationError):
client.get("/response_model-no_annotation-return_invalid_model")
def test_response_model_no_annotation_return_dict_with_extra_data():
response = client.get("/response_model-no_annotation-return_dict_with_extra_data")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_no_annotation_return_submodel_with_extra_data():
response = client.get(
"/response_model-no_annotation-return_submodel_with_extra_data"
)
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_annotation_return_same_model():
response = client.get("/no_response_model-annotation-return_same_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_annotation_return_exact_dict():
response = client.get("/no_response_model-annotation-return_exact_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_annotation_return_invalid_dict():
with pytest.raises(ValidationError):
client.get("/no_response_model-annotation-return_invalid_dict")
def test_no_response_model_annotation_return_invalid_model():
with pytest.raises(ValidationError):
client.get("/no_response_model-annotation-return_invalid_model")
def test_no_response_model_annotation_return_dict_with_extra_data():
response = client.get("/no_response_model-annotation-return_dict_with_extra_data")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_annotation_return_submodel_with_extra_data():
response = client.get(
"/no_response_model-annotation-return_submodel_with_extra_data"
)
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_none_annotation_return_same_model():
response = client.get("/response_model_none-annotation-return_same_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_none_annotation_return_exact_dict():
response = client.get("/response_model_none-annotation-return_exact_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_none_annotation_return_invalid_dict():
response = client.get("/response_model_none-annotation-return_invalid_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John"}
def test_response_model_none_annotation_return_invalid_model():
response = client.get("/response_model_none-annotation-return_invalid_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo", "price": 42.0}
def test_response_model_none_annotation_return_dict_with_extra_data():
response = client.get("/response_model_none-annotation-return_dict_with_extra_data")
assert response.status_code == 200, response.text
assert response.json() == {
"name": "John",
"surname": "Doe",
"password_hash": "secret",
"title": "Response Response Model Union No Annotation Return Model1 Response Model Union No Annotation Return Model1 Get",
"anyOf": [
{"$ref": "#/components/schemas/User"},
{"$ref": "#/components/schemas/Item"},
],
}
def test_response_model_none_annotation_return_submodel_with_extra_data():
response = client.get(
"/response_model_none-annotation-return_submodel_with_extra_data"
)
assert response.status_code == 200, response.text
assert response.json() == {
"name": "John",
"surname": "Doe",
"password_hash": "secret",
}
def test_response_model_model1_annotation_model2_return_same_model():
response = client.get("/response_model_model1-annotation_model2-return_same_model")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_model1_annotation_model2_return_exact_dict():
response = client.get("/response_model_model1-annotation_model2-return_exact_dict")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_model1_annotation_model2_return_invalid_dict():
with pytest.raises(ValidationError):
client.get("/response_model_model1-annotation_model2-return_invalid_dict")
def test_response_model_model1_annotation_model2_return_invalid_model():
with pytest.raises(ValidationError):
client.get("/response_model_model1-annotation_model2-return_invalid_model")
def test_response_model_model1_annotation_model2_return_dict_with_extra_data():
response = client.get(
"/response_model_model1-annotation_model2-return_dict_with_extra_data"
)
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_model1_annotation_model2_return_submodel_with_extra_data():
response = client.get(
"/response_model_model1-annotation_model2-return_submodel_with_extra_data"
)
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_filtering_model_annotation_submodel_return_submodel():
response = client.get(
"/response_model_filtering_model-annotation_submodel-return_submodel"
)
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_list_of_model_no_annotation():
response = client.get("/response_model_list_of_model-no_annotation")
assert response.status_code == 200, response.text
assert response.json() == [
{"name": "John", "surname": "Doe"},
{"name": "Jane", "surname": "Does"},
]
def test_no_response_model_annotation_list_of_model():
response = client.get("/no_response_model-annotation_list_of_model")
assert response.status_code == 200, response.text
assert response.json() == [
{"name": "John", "surname": "Doe"},
{"name": "Jane", "surname": "Does"},
]
def test_no_response_model_annotation_forward_ref_list_of_model():
response = client.get("/no_response_model-annotation_forward_ref_list_of_model")
assert response.status_code == 200, response.text
assert response.json() == [
{"name": "John", "surname": "Doe"},
{"name": "Jane", "surname": "Does"},
]
def test_response_model_union_no_annotation_return_model1():
response = client.get("/response_model_union-no_annotation-return_model1")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_response_model_union_no_annotation_return_model2():
response = client.get("/response_model_union-no_annotation-return_model2")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo", "price": 42.0}
def test_no_response_model_annotation_union_return_model1():
response = client.get("/no_response_model-annotation_union-return_model1")
assert response.status_code == 200, response.text
assert response.json() == {"name": "John", "surname": "Doe"}
def test_no_response_model_annotation_union_return_model2():
response = client.get("/no_response_model-annotation_union-return_model2")
assert response.status_code == 200, response.text
assert response.json() == {"name": "Foo", "price": 42.0}
def test_no_response_model_annotation_return_class():
response = client.get("/no_response_model-annotation_response_class")
assert response.status_code == 200, response.text
assert response.text == "Foo"
def test_no_response_model_annotation_json_response_class():
response = client.get("/no_response_model-annotation_json_response_class")
assert response.status_code == 200, response.text
assert response.json() == {"foo": "bar"}
def test_invalid_response_model_field():
app = FastAPI()
with pytest.raises(FastAPIError) as e:
@app.get("/")
def read_root() -> Union[Response, None]:
return Response(content="Foo") # pragma: no cover
assert "valid Pydantic field type" in e.value.args[0]
assert "parameter response_model=None" in e.value.args[0]
},
}
},
}
},
"/response_model_union-no_annotation-return_model2": {
"get": {
"summary": "Response Model Union No Annotation Return Model2",
"operationId": "response_model_union_no_annotation_return_model2_response_model_union_no_annotation_return_model2_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"title": "Response Response Model Union No Annotation Return Model2 Response Model Union No Annotation Return Model2 Get",
"anyOf": [
{"$ref": "#/components/schemas/User"},
{"$ref": "#/components/schemas/Item"},
],
}
}
},
}
},
}
},
"/no_response_model-annotation_union-return_model1": {
"get": {
"summary": "No Response Model Annotation Union Return Model1",
"operationId": "no_response_model_annotation_union_return_model1_no_response_model_annotation_union_return_model1_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"title": "Response No Response Model Annotation Union Return Model1 No Response Model Annotation Union Return Model1 Get",
"anyOf": [
{"$ref": "#/components/schemas/User"},
{"$ref": "#/components/schemas/Item"},
],
}
}
},
}
},
}
},
"/no_response_model-annotation_union-return_model2": {
"get": {
"summary": "No Response Model Annotation Union Return Model2",
"operationId": "no_response_model_annotation_union_return_model2_no_response_model_annotation_union_return_model2_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"title": "Response No Response Model Annotation Union Return Model2 No Response Model Annotation Union Return Model2 Get",
"anyOf": [
{"$ref": "#/components/schemas/User"},
{"$ref": "#/components/schemas/Item"},
],
}
}
},
}
},
}
},
"/no_response_model-annotation_response_class": {
"get": {
"summary": "No Response Model Annotation Response Class",
"operationId": "no_response_model_annotation_response_class_no_response_model_annotation_response_class_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
}
},
"/no_response_model-annotation_json_response_class": {
"get": {
"summary": "No Response Model Annotation Json Response Class",
"operationId": "no_response_model_annotation_json_response_class_no_response_model_annotation_json_response_class_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
}
},
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
},
},
"User": {
"title": "User",
"required": ["name", "surname"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"surname": {"title": "Surname", "type": "string"},
},
},
}
},
}

38
tests/test_response_model_sub_types.py

@ -32,7 +32,24 @@ def valid4():
pass
openapi_schema = {
client = TestClient(app)
def test_path_operations():
response = client.get("/valid1")
assert response.status_code == 200, response.text
response = client.get("/valid2")
assert response.status_code == 200, response.text
response = client.get("/valid3")
assert response.status_code == 200, response.text
response = client.get("/valid4")
assert response.status_code == 200, response.text
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -139,22 +156,3 @@ openapi_schema = {
}
},
}
client = TestClient(app)
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_path_operations():
response = client.get("/valid1")
assert response.status_code == 200, response.text
response = client.get("/valid2")
assert response.status_code == 200, response.text
response = client.get("/valid3")
assert response.status_code == 200, response.text
response = client.get("/valid4")
assert response.status_code == 200, response.text

103
tests/test_schema_extra_examples.py

@ -234,7 +234,52 @@ def cookie_example_examples(
client = TestClient(app)
openapi_schema = {
def test_call_api():
response = client.post("/schema_extra/", json={"data": "Foo"})
assert response.status_code == 200, response.text
response = client.post("/example/", json={"data": "Foo"})
assert response.status_code == 200, response.text
response = client.post("/examples/", json={"data": "Foo"})
assert response.status_code == 200, response.text
response = client.post("/example_examples/", json={"data": "Foo"})
assert response.status_code == 200, response.text
response = client.get("/path_example/foo")
assert response.status_code == 200, response.text
response = client.get("/path_examples/foo")
assert response.status_code == 200, response.text
response = client.get("/path_example_examples/foo")
assert response.status_code == 200, response.text
response = client.get("/query_example/")
assert response.status_code == 200, response.text
response = client.get("/query_examples/")
assert response.status_code == 200, response.text
response = client.get("/query_example_examples/")
assert response.status_code == 200, response.text
response = client.get("/header_example/")
assert response.status_code == 200, response.text
response = client.get("/header_examples/")
assert response.status_code == 200, response.text
response = client.get("/header_example_examples/")
assert response.status_code == 200, response.text
response = client.get("/cookie_example/")
assert response.status_code == 200, response.text
response = client.get("/cookie_examples/")
assert response.status_code == 200, response.text
response = client.get("/cookie_example_examples/")
assert response.status_code == 200, response.text
def test_openapi_schema():
"""
Test that example overrides work:
* pydantic model schema_extra is included
* Body(example={}) overrides schema_extra in pydantic model
* Body(examples{}) overrides Body(example={}) and schema_extra in pydantic model
"""
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -315,7 +360,9 @@ openapi_schema = {
},
},
"example2": {
"value": {"data": "Data in Body examples, example2"}
"value": {
"data": "Data in Body examples, example2"
}
},
},
}
@ -827,7 +874,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -836,51 +885,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
"""
Test that example overrides work:
* pydantic model schema_extra is included
* Body(example={}) overrides schema_extra in pydantic model
* Body(examples{}) overrides Body(example={}) and schema_extra in pydantic model
"""
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_call_api():
response = client.post("/schema_extra/", json={"data": "Foo"})
assert response.status_code == 200, response.text
response = client.post("/example/", json={"data": "Foo"})
assert response.status_code == 200, response.text
response = client.post("/examples/", json={"data": "Foo"})
assert response.status_code == 200, response.text
response = client.post("/example_examples/", json={"data": "Foo"})
assert response.status_code == 200, response.text
response = client.get("/path_example/foo")
assert response.status_code == 200, response.text
response = client.get("/path_examples/foo")
assert response.status_code == 200, response.text
response = client.get("/path_example_examples/foo")
assert response.status_code == 200, response.text
response = client.get("/query_example/")
assert response.status_code == 200, response.text
response = client.get("/query_examples/")
assert response.status_code == 200, response.text
response = client.get("/query_example_examples/")
assert response.status_code == 200, response.text
response = client.get("/header_example/")
assert response.status_code == 200, response.text
response = client.get("/header_examples/")
assert response.status_code == 200, response.text
response = client.get("/header_example_examples/")
assert response.status_code == 200, response.text
response = client.get("/cookie_example/")
assert response.status_code == 200, response.text
response = client.get("/cookie_examples/")
assert response.status_code == 200, response.text
response = client.get("/cookie_example_examples/")
assert response.status_code == 200, response.text

41
tests/test_security_api_key_cookie.py

@ -22,7 +22,25 @@ def read_current_user(current_user: User = Depends(get_current_user)):
return current_user
openapi_schema = {
def test_security_api_key():
client = TestClient(app, cookies={"key": "secret"})
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
client = TestClient(app)
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_openapi_schema():
client = TestClient(app)
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -46,24 +64,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
client = TestClient(app)
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_api_key():
client = TestClient(app, cookies={"key": "secret"})
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
client = TestClient(app)
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}

41
tests/test_security_api_key_cookie_description.py

@ -22,7 +22,25 @@ def read_current_user(current_user: User = Depends(get_current_user)):
return current_user
openapi_schema = {
def test_security_api_key():
client = TestClient(app, cookies={"key": "secret"})
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
client = TestClient(app)
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_openapi_schema():
client = TestClient(app)
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -51,24 +69,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
client = TestClient(app)
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_api_key():
client = TestClient(app, cookies={"key": "secret"})
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
client = TestClient(app)
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}

41
tests/test_security_api_key_cookie_optional.py

@ -29,7 +29,25 @@ def read_current_user(current_user: User = Depends(get_current_user)):
return current_user
openapi_schema = {
def test_security_api_key():
client = TestClient(app, cookies={"key": "secret"})
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
client = TestClient(app)
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_openapi_schema():
client = TestClient(app)
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -53,24 +71,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
client = TestClient(app)
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_api_key():
client = TestClient(app, cookies={"key": "secret"})
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
client = TestClient(app)
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}

36
tests/test_security_api_key_header.py

@ -24,7 +24,23 @@ def read_current_user(current_user: User = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_api_key():
response = client.get("/users/me", headers={"key": "secret"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -48,21 +64,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_api_key():
response = client.get("/users/me", headers={"key": "secret"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}

36
tests/test_security_api_key_header_description.py

@ -24,7 +24,23 @@ def read_current_user(current_user: User = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_api_key():
response = client.get("/users/me", headers={"key": "secret"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -53,21 +69,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_api_key():
response = client.get("/users/me", headers={"key": "secret"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}

36
tests/test_security_api_key_header_optional.py

@ -30,7 +30,23 @@ def read_current_user(current_user: Optional[User] = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_api_key():
response = client.get("/users/me", headers={"key": "secret"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -54,21 +70,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_api_key():
response = client.get("/users/me", headers={"key": "secret"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}

36
tests/test_security_api_key_query.py

@ -24,7 +24,23 @@ def read_current_user(current_user: User = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_api_key():
response = client.get("/users/me?key=secret")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -48,21 +64,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_api_key():
response = client.get("/users/me?key=secret")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}

36
tests/test_security_api_key_query_description.py

@ -24,7 +24,23 @@ def read_current_user(current_user: User = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_api_key():
response = client.get("/users/me?key=secret")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -53,21 +69,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_api_key():
response = client.get("/users/me?key=secret")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}

36
tests/test_security_api_key_query_optional.py

@ -30,7 +30,23 @@ def read_current_user(current_user: Optional[User] = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_api_key():
response = client.get("/users/me?key=secret")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -54,21 +70,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_api_key():
response = client.get("/users/me?key=secret")
assert response.status_code == 200, response.text
assert response.json() == {"username": "secret"}
def test_security_api_key_no_key():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}

36
tests/test_security_http_base.py

@ -14,7 +14,23 @@ def read_current_user(credentials: HTTPAuthorizationCredentials = Security(secur
client = TestClient(app)
openapi_schema = {
def test_security_http_base():
response = client.get("/users/me", headers={"Authorization": "Other foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Other", "credentials": "foobar"}
def test_security_http_base_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -36,21 +52,3 @@ openapi_schema = {
"securitySchemes": {"HTTPBase": {"type": "http", "scheme": "Other"}}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_base():
response = client.get("/users/me", headers={"Authorization": "Other foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Other", "credentials": "foobar"}
def test_security_http_base_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}

36
tests/test_security_http_base_description.py

@ -14,7 +14,23 @@ def read_current_user(credentials: HTTPAuthorizationCredentials = Security(secur
client = TestClient(app)
openapi_schema = {
def test_security_http_base():
response = client.get("/users/me", headers={"Authorization": "Other foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Other", "credentials": "foobar"}
def test_security_http_base_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -42,21 +58,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_base():
response = client.get("/users/me", headers={"Authorization": "Other foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Other", "credentials": "foobar"}
def test_security_http_base_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}

36
tests/test_security_http_base_optional.py

@ -20,7 +20,23 @@ def read_current_user(
client = TestClient(app)
openapi_schema = {
def test_security_http_base():
response = client.get("/users/me", headers={"Authorization": "Other foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Other", "credentials": "foobar"}
def test_security_http_base_no_credentials():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -42,21 +58,3 @@ openapi_schema = {
"securitySchemes": {"HTTPBase": {"type": "http", "scheme": "Other"}}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_base():
response = client.get("/users/me", headers={"Authorization": "Other foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Other", "credentials": "foobar"}
def test_security_http_base_no_credentials():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}

56
tests/test_security_http_basic_optional.py

@ -19,35 +19,6 @@ def read_current_user(credentials: Optional[HTTPBasicCredentials] = Security(sec
client = TestClient(app)
openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/users/me": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read Current User",
"operationId": "read_current_user_users_me_get",
"security": [{"HTTPBasic": []}],
}
}
},
"components": {
"securitySchemes": {"HTTPBasic": {"type": "http", "scheme": "basic"}}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_basic():
response = client.get("/users/me", auth=("john", "secret"))
@ -77,3 +48,30 @@ def test_security_http_basic_non_basic_credentials():
assert response.status_code == 401, response.text
assert response.headers["WWW-Authenticate"] == "Basic"
assert response.json() == {"detail": "Invalid authentication credentials"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/users/me": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read Current User",
"operationId": "read_current_user_users_me_get",
"security": [{"HTTPBasic": []}],
}
}
},
"components": {
"securitySchemes": {"HTTPBasic": {"type": "http", "scheme": "basic"}}
},
}

56
tests/test_security_http_basic_realm.py

@ -16,35 +16,6 @@ def read_current_user(credentials: HTTPBasicCredentials = Security(security)):
client = TestClient(app)
openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/users/me": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read Current User",
"operationId": "read_current_user_users_me_get",
"security": [{"HTTPBasic": []}],
}
}
},
"components": {
"securitySchemes": {"HTTPBasic": {"type": "http", "scheme": "basic"}}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_basic():
response = client.get("/users/me", auth=("john", "secret"))
@ -75,3 +46,30 @@ def test_security_http_basic_non_basic_credentials():
assert response.status_code == 401, response.text
assert response.headers["WWW-Authenticate"] == 'Basic realm="simple"'
assert response.json() == {"detail": "Invalid authentication credentials"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/users/me": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read Current User",
"operationId": "read_current_user_users_me_get",
"security": [{"HTTPBasic": []}],
}
}
},
"components": {
"securitySchemes": {"HTTPBasic": {"type": "http", "scheme": "basic"}}
},
}

68
tests/test_security_http_basic_realm_description.py

@ -16,41 +16,6 @@ def read_current_user(credentials: HTTPBasicCredentials = Security(security)):
client = TestClient(app)
openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/users/me": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read Current User",
"operationId": "read_current_user_users_me_get",
"security": [{"HTTPBasic": []}],
}
}
},
"components": {
"securitySchemes": {
"HTTPBasic": {
"type": "http",
"scheme": "basic",
"description": "HTTPBasic scheme",
}
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_basic():
response = client.get("/users/me", auth=("john", "secret"))
@ -81,3 +46,36 @@ def test_security_http_basic_non_basic_credentials():
assert response.status_code == 401, response.text
assert response.headers["WWW-Authenticate"] == 'Basic realm="simple"'
assert response.json() == {"detail": "Invalid authentication credentials"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/users/me": {
"get": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
}
},
"summary": "Read Current User",
"operationId": "read_current_user_users_me_get",
"security": [{"HTTPBasic": []}],
}
}
},
"components": {
"securitySchemes": {
"HTTPBasic": {
"type": "http",
"scheme": "basic",
"description": "HTTPBasic scheme",
}
}
},
}

48
tests/test_security_http_bearer.py

@ -14,7 +14,29 @@ def read_current_user(credentials: HTTPAuthorizationCredentials = Security(secur
client = TestClient(app)
openapi_schema = {
def test_security_http_bearer():
response = client.get("/users/me", headers={"Authorization": "Bearer foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Bearer", "credentials": "foobar"}
def test_security_http_bearer_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_security_http_bearer_incorrect_scheme_credentials():
response = client.get("/users/me", headers={"Authorization": "Basic notreally"})
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -36,27 +58,3 @@ openapi_schema = {
"securitySchemes": {"HTTPBearer": {"type": "http", "scheme": "bearer"}}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_bearer():
response = client.get("/users/me", headers={"Authorization": "Bearer foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Bearer", "credentials": "foobar"}
def test_security_http_bearer_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_security_http_bearer_incorrect_scheme_credentials():
response = client.get("/users/me", headers={"Authorization": "Basic notreally"})
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}

48
tests/test_security_http_bearer_description.py

@ -14,7 +14,29 @@ def read_current_user(credentials: HTTPAuthorizationCredentials = Security(secur
client = TestClient(app)
openapi_schema = {
def test_security_http_bearer():
response = client.get("/users/me", headers={"Authorization": "Bearer foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Bearer", "credentials": "foobar"}
def test_security_http_bearer_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_security_http_bearer_incorrect_scheme_credentials():
response = client.get("/users/me", headers={"Authorization": "Basic notreally"})
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -42,27 +64,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_bearer():
response = client.get("/users/me", headers={"Authorization": "Bearer foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Bearer", "credentials": "foobar"}
def test_security_http_bearer_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_security_http_bearer_incorrect_scheme_credentials():
response = client.get("/users/me", headers={"Authorization": "Basic notreally"})
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}

48
tests/test_security_http_bearer_optional.py

@ -20,7 +20,29 @@ def read_current_user(
client = TestClient(app)
openapi_schema = {
def test_security_http_bearer():
response = client.get("/users/me", headers={"Authorization": "Bearer foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Bearer", "credentials": "foobar"}
def test_security_http_bearer_no_credentials():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_security_http_bearer_incorrect_scheme_credentials():
response = client.get("/users/me", headers={"Authorization": "Basic notreally"})
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -42,27 +64,3 @@ openapi_schema = {
"securitySchemes": {"HTTPBearer": {"type": "http", "scheme": "bearer"}}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_bearer():
response = client.get("/users/me", headers={"Authorization": "Bearer foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Bearer", "credentials": "foobar"}
def test_security_http_bearer_no_credentials():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_security_http_bearer_incorrect_scheme_credentials():
response = client.get("/users/me", headers={"Authorization": "Basic notreally"})
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}

52
tests/test_security_http_digest.py

@ -14,7 +14,31 @@ def read_current_user(credentials: HTTPAuthorizationCredentials = Security(secur
client = TestClient(app)
openapi_schema = {
def test_security_http_digest():
response = client.get("/users/me", headers={"Authorization": "Digest foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Digest", "credentials": "foobar"}
def test_security_http_digest_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_security_http_digest_incorrect_scheme_credentials():
response = client.get(
"/users/me", headers={"Authorization": "Other invalidauthorization"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -36,29 +60,3 @@ openapi_schema = {
"securitySchemes": {"HTTPDigest": {"type": "http", "scheme": "digest"}}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_digest():
response = client.get("/users/me", headers={"Authorization": "Digest foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Digest", "credentials": "foobar"}
def test_security_http_digest_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_security_http_digest_incorrect_scheme_credentials():
response = client.get(
"/users/me", headers={"Authorization": "Other invalidauthorization"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}

52
tests/test_security_http_digest_description.py

@ -14,7 +14,31 @@ def read_current_user(credentials: HTTPAuthorizationCredentials = Security(secur
client = TestClient(app)
openapi_schema = {
def test_security_http_digest():
response = client.get("/users/me", headers={"Authorization": "Digest foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Digest", "credentials": "foobar"}
def test_security_http_digest_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_security_http_digest_incorrect_scheme_credentials():
response = client.get(
"/users/me", headers={"Authorization": "Other invalidauthorization"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -42,29 +66,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_digest():
response = client.get("/users/me", headers={"Authorization": "Digest foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Digest", "credentials": "foobar"}
def test_security_http_digest_no_credentials():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_security_http_digest_incorrect_scheme_credentials():
response = client.get(
"/users/me", headers={"Authorization": "Other invalidauthorization"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}

52
tests/test_security_http_digest_optional.py

@ -20,7 +20,31 @@ def read_current_user(
client = TestClient(app)
openapi_schema = {
def test_security_http_digest():
response = client.get("/users/me", headers={"Authorization": "Digest foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Digest", "credentials": "foobar"}
def test_security_http_digest_no_credentials():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_security_http_digest_incorrect_scheme_credentials():
response = client.get(
"/users/me", headers={"Authorization": "Other invalidauthorization"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -42,29 +66,3 @@ openapi_schema = {
"securitySchemes": {"HTTPDigest": {"type": "http", "scheme": "digest"}}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_http_digest():
response = client.get("/users/me", headers={"Authorization": "Digest foobar"})
assert response.status_code == 200, response.text
assert response.json() == {"scheme": "Digest", "credentials": "foobar"}
def test_security_http_digest_no_credentials():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_security_http_digest_incorrect_scheme_credentials():
response = client.get(
"/users/me", headers={"Authorization": "Other invalidauthorization"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Invalid authentication credentials"}

196
tests/test_security_oauth2.py

@ -40,7 +40,101 @@ def read_current_user(current_user: "User" = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
required_params = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
grant_type_required = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
grant_type_incorrect = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": 'string does not match regex "password"',
"type": "value_error.str.regex",
"ctx": {"pattern": "password"},
}
]
}
@pytest.mark.parametrize(
"data,expected_status,expected_response",
[
(None, 422, required_params),
({"username": "johndoe", "password": "secret"}, 422, grant_type_required),
(
{"username": "johndoe", "password": "secret", "grant_type": "incorrect"},
422,
grant_type_incorrect,
),
(
{"username": "johndoe", "password": "secret", "grant_type": "password"},
200,
{
"grant_type": "password",
"username": "johndoe",
"password": "secret",
"scopes": [],
"client_id": None,
"client_secret": None,
},
),
],
)
def test_strict_login(data, expected_status, expected_response):
response = client.post("/login", data=data)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -117,7 +211,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -151,99 +247,3 @@ openapi_schema = {
},
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
required_params = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
grant_type_required = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
grant_type_incorrect = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": 'string does not match regex "password"',
"type": "value_error.str.regex",
"ctx": {"pattern": "password"},
}
]
}
@pytest.mark.parametrize(
"data,expected_status,expected_response",
[
(None, 422, required_params),
({"username": "johndoe", "password": "secret"}, 422, grant_type_required),
(
{"username": "johndoe", "password": "secret", "grant_type": "incorrect"},
422,
grant_type_incorrect,
),
(
{"username": "johndoe", "password": "secret", "grant_type": "password"},
200,
{
"grant_type": "password",
"username": "johndoe",
"password": "secret",
"scopes": [],
"client_id": None,
"client_secret": None,
},
),
],
)
def test_strict_login(data, expected_status, expected_response):
response = client.post("/login", data=data)
assert response.status_code == expected_status
assert response.json() == expected_response

48
tests/test_security_oauth2_authorization_code_bearer.py

@ -18,7 +18,29 @@ async def read_items(token: Optional[str] = Security(oauth2_scheme)):
client = TestClient(app)
openapi_schema = {
def test_no_token():
response = client.get("/items")
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_incorrect_token():
response = client.get("/items", headers={"Authorization": "Non-existent testtoken"})
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_token():
response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"token": "testtoken"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -51,27 +73,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_no_token():
response = client.get("/items")
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_incorrect_token():
response = client.get("/items", headers={"Authorization": "Non-existent testtoken"})
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_token():
response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"token": "testtoken"}

48
tests/test_security_oauth2_authorization_code_bearer_description.py

@ -21,7 +21,29 @@ async def read_items(token: Optional[str] = Security(oauth2_scheme)):
client = TestClient(app)
openapi_schema = {
def test_no_token():
response = client.get("/items")
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_incorrect_token():
response = client.get("/items", headers={"Authorization": "Non-existent testtoken"})
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_token():
response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"token": "testtoken"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -55,27 +77,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_no_token():
response = client.get("/items")
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_incorrect_token():
response = client.get("/items", headers={"Authorization": "Non-existent testtoken"})
assert response.status_code == 401, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_token():
response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"token": "testtoken"}

196
tests/test_security_oauth2_optional.py

@ -44,7 +44,101 @@ def read_users_me(current_user: Optional[User] = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
required_params = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
grant_type_required = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
grant_type_incorrect = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": 'string does not match regex "password"',
"type": "value_error.str.regex",
"ctx": {"pattern": "password"},
}
]
}
@pytest.mark.parametrize(
"data,expected_status,expected_response",
[
(None, 422, required_params),
({"username": "johndoe", "password": "secret"}, 422, grant_type_required),
(
{"username": "johndoe", "password": "secret", "grant_type": "incorrect"},
422,
grant_type_incorrect,
),
(
{"username": "johndoe", "password": "secret", "grant_type": "password"},
200,
{
"grant_type": "password",
"username": "johndoe",
"password": "secret",
"scopes": [],
"client_id": None,
"client_secret": None,
},
),
],
)
def test_strict_login(data, expected_status, expected_response):
response = client.post("/login", data=data)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -121,7 +215,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -155,99 +251,3 @@ openapi_schema = {
},
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
required_params = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
grant_type_required = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
grant_type_incorrect = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": 'string does not match regex "password"',
"type": "value_error.str.regex",
"ctx": {"pattern": "password"},
}
]
}
@pytest.mark.parametrize(
"data,expected_status,expected_response",
[
(None, 422, required_params),
({"username": "johndoe", "password": "secret"}, 422, grant_type_required),
(
{"username": "johndoe", "password": "secret", "grant_type": "incorrect"},
422,
grant_type_incorrect,
),
(
{"username": "johndoe", "password": "secret", "grant_type": "password"},
200,
{
"grant_type": "password",
"username": "johndoe",
"password": "secret",
"scopes": [],
"client_id": None,
"client_secret": None,
},
),
],
)
def test_strict_login(data, expected_status, expected_response):
response = client.post("/login", data=data)
assert response.status_code == expected_status
assert response.json() == expected_response

196
tests/test_security_oauth2_optional_description.py

@ -45,7 +45,101 @@ def read_users_me(current_user: Optional[User] = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
required_params = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
grant_type_required = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
grant_type_incorrect = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": 'string does not match regex "password"',
"type": "value_error.str.regex",
"ctx": {"pattern": "password"},
}
]
}
@pytest.mark.parametrize(
"data,expected_status,expected_response",
[
(None, 422, required_params),
({"username": "johndoe", "password": "secret"}, 422, grant_type_required),
(
{"username": "johndoe", "password": "secret", "grant_type": "incorrect"},
422,
grant_type_incorrect,
),
(
{"username": "johndoe", "password": "secret", "grant_type": "password"},
200,
{
"grant_type": "password",
"username": "johndoe",
"password": "secret",
"scopes": [],
"client_id": None,
"client_secret": None,
},
),
],
)
def test_strict_login(data, expected_status, expected_response):
response = client.post("/login", data=data)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -122,7 +216,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -157,99 +253,3 @@ openapi_schema = {
},
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
required_params = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "username"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "password"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
grant_type_required = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": "field required",
"type": "value_error.missing",
}
]
}
grant_type_incorrect = {
"detail": [
{
"loc": ["body", "grant_type"],
"msg": 'string does not match regex "password"',
"type": "value_error.str.regex",
"ctx": {"pattern": "password"},
}
]
}
@pytest.mark.parametrize(
"data,expected_status,expected_response",
[
(None, 422, required_params),
({"username": "johndoe", "password": "secret"}, 422, grant_type_required),
(
{"username": "johndoe", "password": "secret", "grant_type": "incorrect"},
422,
grant_type_incorrect,
),
(
{"username": "johndoe", "password": "secret", "grant_type": "password"},
200,
{
"grant_type": "password",
"username": "johndoe",
"password": "secret",
"scopes": [],
"client_id": None,
"client_secret": None,
},
),
],
)
def test_strict_login(data, expected_status, expected_response):
response = client.post("/login", data=data)
assert response.status_code == expected_status
assert response.json() == expected_response

48
tests/test_security_oauth2_password_bearer_optional.py

@ -18,7 +18,29 @@ async def read_items(token: Optional[str] = Security(oauth2_scheme)):
client = TestClient(app)
openapi_schema = {
def test_no_token():
response = client.get("/items")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_token():
response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"token": "testtoken"}
def test_incorrect_token():
response = client.get("/items", headers={"Authorization": "Notexistent testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -45,27 +67,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_no_token():
response = client.get("/items")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_token():
response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"token": "testtoken"}
def test_incorrect_token():
response = client.get("/items", headers={"Authorization": "Notexistent testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}

48
tests/test_security_oauth2_password_bearer_optional_description.py

@ -22,7 +22,29 @@ async def read_items(token: Optional[str] = Security(oauth2_scheme)):
client = TestClient(app)
openapi_schema = {
def test_no_token():
response = client.get("/items")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_token():
response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"token": "testtoken"}
def test_incorrect_token():
response = client.get("/items", headers={"Authorization": "Notexistent testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -50,27 +72,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_no_token():
response = client.get("/items")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_token():
response = client.get("/items", headers={"Authorization": "Bearer testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"token": "testtoken"}
def test_incorrect_token():
response = client.get("/items", headers={"Authorization": "Notexistent testtoken"})
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}

53
tests/test_security_openid_connect.py

@ -24,7 +24,29 @@ def read_current_user(current_user: User = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -44,31 +66,10 @@ openapi_schema = {
},
"components": {
"securitySchemes": {
"OpenIdConnect": {"type": "openIdConnect", "openIdConnectUrl": "/openid"}
"OpenIdConnect": {
"type": "openIdConnect",
"openIdConnectUrl": "/openid",
}
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}

48
tests/test_security_openid_connect_description.py

@ -26,7 +26,29 @@ def read_current_user(current_user: User = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -54,27 +76,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 403, response.text
assert response.json() == {"detail": "Not authenticated"}

53
tests/test_security_openid_connect_optional.py

@ -30,7 +30,29 @@ def read_current_user(current_user: Optional[User] = Depends(get_current_user)):
client = TestClient(app)
openapi_schema = {
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -50,31 +72,10 @@ openapi_schema = {
},
"components": {
"securitySchemes": {
"OpenIdConnect": {"type": "openIdConnect", "openIdConnectUrl": "/openid"}
"OpenIdConnect": {
"type": "openIdConnect",
"openIdConnectUrl": "/openid",
}
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_security_oauth2():
response = client.get("/users/me", headers={"Authorization": "Bearer footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Bearer footokenbar"}
def test_security_oauth2_password_other_header():
response = client.get("/users/me", headers={"Authorization": "Other footokenbar"})
assert response.status_code == 200, response.text
assert response.json() == {"username": "Other footokenbar"}
def test_security_oauth2_password_bearer_no_header():
response = client.get("/users/me")
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Create an account first"}

92
tests/test_starlette_exception.py

@ -37,7 +37,49 @@ async def read_starlette_item(item_id: str):
client = TestClient(app)
openapi_schema = {
def test_get_item():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"item": "The Foo Wrestlers"}
def test_get_item_not_found():
response = client.get("/items/bar")
assert response.status_code == 404, response.text
assert response.headers.get("x-error") == "Some custom header"
assert response.json() == {"detail": "Item not found"}
def test_get_starlette_item():
response = client.get("/starlette-items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"item": "The Foo Wrestlers"}
def test_get_starlette_item_not_found():
response = client.get("/starlette-items/bar")
assert response.status_code == 404, response.text
assert response.headers.get("x-error") is None
assert response.json() == {"detail": "Item not found"}
def test_no_body_status_code_exception_handlers():
response = client.get("/http-no-body-statuscode-exception")
assert response.status_code == 204
assert not response.content
def test_no_body_status_code_with_detail_exception_handlers():
response = client.get("/http-no-body-statuscode-with-detail-exception")
assert response.status_code == 204
assert not response.content
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -136,7 +178,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -156,47 +200,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_get_item():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"item": "The Foo Wrestlers"}
def test_get_item_not_found():
response = client.get("/items/bar")
assert response.status_code == 404, response.text
assert response.headers.get("x-error") == "Some custom header"
assert response.json() == {"detail": "Item not found"}
def test_get_starlette_item():
response = client.get("/starlette-items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"item": "The Foo Wrestlers"}
def test_get_starlette_item_not_found():
response = client.get("/starlette-items/bar")
assert response.status_code == 404, response.text
assert response.headers.get("x-error") is None
assert response.json() == {"detail": "Item not found"}
def test_no_body_status_code_exception_handlers():
response = client.get("/http-no-body-statuscode-exception")
assert response.status_code == 204
assert not response.content
def test_no_body_status_code_with_detail_exception_handlers():
response = client.get("/http-no-body-statuscode-with-detail-exception")
assert response.status_code == 204
assert not response.content

41
tests/test_sub_callbacks.py

@ -74,7 +74,19 @@ app.include_router(subrouter, callbacks=events_callback_router.routes)
client = TestClient(app)
openapi_schema = {
def test_get():
response = client.post(
"/invoices/", json={"id": "fooinvoice", "customer": "John", "total": 5.3}
)
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Invoice received"}
def test_openapi_schema():
with client:
response = client.get("/openapi.json")
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -140,7 +152,9 @@ openapi_schema = {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
"content": {
"application/json": {"schema": {}}
},
},
"422": {
"description": "Validation Error",
@ -218,7 +232,9 @@ openapi_schema = {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
},
@ -256,7 +272,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -265,18 +283,3 @@ openapi_schema = {
}
},
}
def test_openapi():
with client:
response = client.get("/openapi.json")
assert response.json() == openapi_schema
def test_get():
response = client.post(
"/invoices/", json={"id": "fooinvoice", "customer": "John", "total": 5.3}
)
assert response.status_code == 200, response.text
assert response.json() == {"msg": "Invoice received"}

112
tests/test_tuples.py

@ -33,7 +33,59 @@ def hello(values: Tuple[int, int] = Form()):
client = TestClient(app)
openapi_schema = {
def test_model_with_tuple_valid():
data = {"items": [["foo", "bar"], ["baz", "whatelse"]]}
response = client.post("/model-with-tuple/", json=data)
assert response.status_code == 200, response.text
assert response.json() == data
def test_model_with_tuple_invalid():
data = {"items": [["foo", "bar"], ["baz", "whatelse", "too", "much"]]}
response = client.post("/model-with-tuple/", json=data)
assert response.status_code == 422, response.text
data = {"items": [["foo", "bar"], ["baz"]]}
response = client.post("/model-with-tuple/", json=data)
assert response.status_code == 422, response.text
def test_tuple_with_model_valid():
data = [{"x": 1, "y": 2}, {"x": 3, "y": 4}]
response = client.post("/tuple-of-models/", json=data)
assert response.status_code == 200, response.text
assert response.json() == data
def test_tuple_with_model_invalid():
data = [{"x": 1, "y": 2}, {"x": 3, "y": 4}, {"x": 5, "y": 6}]
response = client.post("/tuple-of-models/", json=data)
assert response.status_code == 422, response.text
data = [{"x": 1, "y": 2}]
response = client.post("/tuple-of-models/", json=data)
assert response.status_code == 422, response.text
def test_tuple_form_valid():
response = client.post("/tuple-form/", data={"values": ("1", "2")})
assert response.status_code == 200, response.text
assert response.json() == [1, 2]
def test_tuple_form_invalid():
response = client.post("/tuple-form/", data={"values": ("1", "2", "3")})
assert response.status_code == 422, response.text
response = client.post("/tuple-form/", data={"values": ("1")})
assert response.status_code == 422, response.text
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -200,7 +252,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -209,57 +263,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_model_with_tuple_valid():
data = {"items": [["foo", "bar"], ["baz", "whatelse"]]}
response = client.post("/model-with-tuple/", json=data)
assert response.status_code == 200, response.text
assert response.json() == data
def test_model_with_tuple_invalid():
data = {"items": [["foo", "bar"], ["baz", "whatelse", "too", "much"]]}
response = client.post("/model-with-tuple/", json=data)
assert response.status_code == 422, response.text
data = {"items": [["foo", "bar"], ["baz"]]}
response = client.post("/model-with-tuple/", json=data)
assert response.status_code == 422, response.text
def test_tuple_with_model_valid():
data = [{"x": 1, "y": 2}, {"x": 3, "y": 4}]
response = client.post("/tuple-of-models/", json=data)
assert response.status_code == 200, response.text
assert response.json() == data
def test_tuple_with_model_invalid():
data = [{"x": 1, "y": 2}, {"x": 3, "y": 4}, {"x": 5, "y": 6}]
response = client.post("/tuple-of-models/", json=data)
assert response.status_code == 422, response.text
data = [{"x": 1, "y": 2}]
response = client.post("/tuple-of-models/", json=data)
assert response.status_code == 422, response.text
def test_tuple_form_valid():
response = client.post("/tuple-form/", data={"values": ("1", "2")})
assert response.status_code == 200, response.text
assert response.json() == [1, 2]
def test_tuple_form_invalid():
response = client.post("/tuple-form/", data={"values": ("1", "2", "3")})
assert response.status_code == 422, response.text
response = client.post("/tuple-form/", data={"values": ("1")})
assert response.status_code == 422, response.text

40
tests/test_tutorial/test_additional_responses/test_tutorial001.py

@ -4,7 +4,23 @@ from docs_src.additional_responses.tutorial001 import app
client = TestClient(app)
openapi_schema = {
def test_path_operation():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"id": "foo", "value": "there goes my hero"}
def test_path_operation_not_found():
response = client.get("/items/bar")
assert response.status_code == 404, response.text
assert response.json() == {"message": "Item not found"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -76,7 +92,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -96,21 +114,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_path_operation():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"id": "foo", "value": "there goes my hero"}
def test_path_operation_not_found():
response = client.get("/items/bar")
assert response.status_code == 404, response.text
assert response.json() == {"message": "Item not found"}

46
tests/test_tutorial/test_additional_responses/test_tutorial002.py

@ -7,7 +7,26 @@ from docs_src.additional_responses.tutorial002 import app
client = TestClient(app)
openapi_schema = {
def test_path_operation():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"id": "foo", "value": "there goes my hero"}
def test_path_operation_img():
shutil.copy("./docs/en/docs/img/favicon.png", "./image.png")
response = client.get("/items/foo?img=1")
assert response.status_code == 200, response.text
assert response.headers["Content-Type"] == "image/png"
assert len(response.content)
os.remove("./image.png")
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -72,7 +91,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -92,24 +113,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_path_operation():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"id": "foo", "value": "there goes my hero"}
def test_path_operation_img():
shutil.copy("./docs/en/docs/img/favicon.png", "./image.png")
response = client.get("/items/foo?img=1")
assert response.status_code == 200, response.text
assert response.headers["Content-Type"] == "image/png"
assert len(response.content)
os.remove("./image.png")

45
tests/test_tutorial/test_additional_responses/test_tutorial003.py

@ -4,7 +4,23 @@ from docs_src.additional_responses.tutorial003 import app
client = TestClient(app)
openapi_schema = {
def test_path_operation():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"id": "foo", "value": "there goes my hero"}
def test_path_operation_not_found():
response = client.get("/items/bar")
assert response.status_code == 404, response.text
assert response.json() == {"message": "Item not found"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -24,7 +40,10 @@ openapi_schema = {
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"},
"example": {"id": "bar", "value": "The bar tenders"},
"example": {
"id": "bar",
"value": "The bar tenders",
},
}
},
},
@ -77,7 +96,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -97,21 +118,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_path_operation():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"id": "foo", "value": "there goes my hero"}
def test_path_operation_not_found():
response = client.get("/items/bar")
assert response.status_code == 404, response.text
assert response.json() == {"message": "Item not found"}

46
tests/test_tutorial/test_additional_responses/test_tutorial004.py

@ -7,7 +7,26 @@ from docs_src.additional_responses.tutorial004 import app
client = TestClient(app)
openapi_schema = {
def test_path_operation():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"id": "foo", "value": "there goes my hero"}
def test_path_operation_img():
shutil.copy("./docs/en/docs/img/favicon.png", "./image.png")
response = client.get("/items/foo?img=1")
assert response.status_code == 200, response.text
assert response.headers["Content-Type"] == "image/png"
assert len(response.content)
os.remove("./image.png")
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -75,7 +94,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -95,24 +116,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_path_operation():
response = client.get("/items/foo")
assert response.status_code == 200, response.text
assert response.json() == {"id": "foo", "value": "there goes my hero"}
def test_path_operation_img():
shutil.copy("./docs/en/docs/img/favicon.png", "./image.png")
response = client.get("/items/foo?img=1")
assert response.status_code == 200, response.text
assert response.headers["Content-Type"] == "image/png"
assert len(response.content)
os.remove("./image.png")

54
tests/test_tutorial/test_async_sql_databases/test_tutorial001.py

@ -2,7 +2,26 @@ from fastapi.testclient import TestClient
from docs_src.async_sql_databases.tutorial001 import app
openapi_schema = {
def test_create_read():
with TestClient(app) as client:
note = {"text": "Foo bar", "completed": False}
response = client.post("/notes/", json=note)
assert response.status_code == 200, response.text
data = response.json()
assert data["text"] == note["text"]
assert data["completed"] == note["completed"]
assert "id" in data
response = client.get("/notes/")
assert response.status_code == 200, response.text
assert data in response.json()
def test_openapi_schema():
with TestClient(app) as client:
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -16,7 +35,9 @@ openapi_schema = {
"schema": {
"title": "Response Read Notes Notes Get",
"type": "array",
"items": {"$ref": "#/components/schemas/Note"},
"items": {
"$ref": "#/components/schemas/Note"
},
}
}
},
@ -88,7 +109,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -101,31 +124,12 @@ openapi_schema = {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
"items": {
"$ref": "#/components/schemas/ValidationError"
},
}
},
},
}
},
}
def test_openapi_schema():
with TestClient(app) as client:
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_create_read():
with TestClient(app) as client:
note = {"text": "Foo bar", "completed": False}
response = client.post("/notes/", json=note)
assert response.status_code == 200, response.text
data = response.json()
assert data["text"] == note["text"]
assert data["completed"] == note["completed"]
assert "id" in data
response = client.get("/notes/")
assert response.status_code == 200, response.text
assert data in response.json()

24
tests/test_tutorial/test_behind_a_proxy/test_tutorial001.py

@ -4,7 +4,17 @@ from docs_src.behind_a_proxy.tutorial001 import app
client = TestClient(app, root_path="/api/v1")
openapi_schema = {
def test_main():
response = client.get("/app")
assert response.status_code == 200
assert response.json() == {"message": "Hello World", "root_path": "/api/v1"}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -23,15 +33,3 @@ openapi_schema = {
},
"servers": [{"url": "/api/v1"}],
}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == openapi_schema
def test_main():
response = client.get("/app")
assert response.status_code == 200
assert response.json() == {"message": "Hello World", "root_path": "/api/v1"}

24
tests/test_tutorial/test_behind_a_proxy/test_tutorial002.py

@ -4,7 +4,17 @@ from docs_src.behind_a_proxy.tutorial002 import app
client = TestClient(app)
openapi_schema = {
def test_main():
response = client.get("/app")
assert response.status_code == 200
assert response.json() == {"message": "Hello World", "root_path": "/api/v1"}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -23,15 +33,3 @@ openapi_schema = {
},
"servers": [{"url": "/api/v1"}],
}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == openapi_schema
def test_main():
response = client.get("/app")
assert response.status_code == 200
assert response.json() == {"message": "Hello World", "root_path": "/api/v1"}

29
tests/test_tutorial/test_behind_a_proxy/test_tutorial003.py

@ -4,13 +4,26 @@ from docs_src.behind_a_proxy.tutorial003 import app
client = TestClient(app)
openapi_schema = {
def test_main():
response = client.get("/app")
assert response.status_code == 200
assert response.json() == {"message": "Hello World", "root_path": "/api/v1"}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"servers": [
{"url": "/api/v1"},
{"url": "https://stag.example.com", "description": "Staging environment"},
{"url": "https://prod.example.com", "description": "Production environment"},
{
"url": "https://prod.example.com",
"description": "Production environment",
},
],
"paths": {
"/app": {
@ -27,15 +40,3 @@ openapi_schema = {
}
},
}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == openapi_schema
def test_main():
response = client.get("/app")
assert response.status_code == 200
assert response.json() == {"message": "Hello World", "root_path": "/api/v1"}

29
tests/test_tutorial/test_behind_a_proxy/test_tutorial004.py

@ -4,12 +4,25 @@ from docs_src.behind_a_proxy.tutorial004 import app
client = TestClient(app)
openapi_schema = {
def test_main():
response = client.get("/app")
assert response.status_code == 200
assert response.json() == {"message": "Hello World", "root_path": "/api/v1"}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"servers": [
{"url": "https://stag.example.com", "description": "Staging environment"},
{"url": "https://prod.example.com", "description": "Production environment"},
{
"url": "https://prod.example.com",
"description": "Production environment",
},
],
"paths": {
"/app": {
@ -26,15 +39,3 @@ openapi_schema = {
}
},
}
def test_openapi():
response = client.get("/openapi.json")
assert response.status_code == 200
assert response.json() == openapi_schema
def test_main():
response = client.get("/app")
assert response.status_code == 200
assert response.json() == {"message": "Hello World", "root_path": "/api/v1"}

323
tests/test_tutorial/test_bigger_applications/test_main.py

@ -5,7 +5,167 @@ from docs_src.bigger_applications.app.main import app
client = TestClient(app)
openapi_schema = {
no_jessica = {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
@pytest.mark.parametrize(
"path,expected_status,expected_response,headers",
[
(
"/users?token=jessica",
200,
[{"username": "Rick"}, {"username": "Morty"}],
{},
),
("/users", 422, no_jessica, {}),
("/users/foo?token=jessica", 200, {"username": "foo"}, {}),
("/users/foo", 422, no_jessica, {}),
("/users/me?token=jessica", 200, {"username": "fakecurrentuser"}, {}),
("/users/me", 422, no_jessica, {}),
(
"/users?token=monica",
400,
{"detail": "No Jessica token provided"},
{},
),
(
"/items?token=jessica",
200,
{"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}},
{"X-Token": "fake-super-secret-token"},
),
("/items", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items/plumbus?token=jessica",
200,
{"name": "Plumbus", "item_id": "plumbus"},
{"X-Token": "fake-super-secret-token"},
),
(
"/items/bar?token=jessica",
404,
{"detail": "Item not found"},
{"X-Token": "fake-super-secret-token"},
),
("/items/plumbus", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items/bar?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
(
"/items/plumbus?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
("/?token=jessica", 200, {"message": "Hello Bigger Applications!"}, {}),
("/", 422, no_jessica, {}),
],
)
def test_get_path(path, expected_status, expected_response, headers):
response = client.get(path, headers=headers)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_put_no_header():
response = client.put("/items/foo")
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
def test_put_invalid_header():
response = client.put("/items/foo", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}
def test_put():
response = client.put(
"/items/plumbus?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "plumbus", "name": "The great Plumbus"}
def test_put_forbidden():
response = client.put(
"/items/bar?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "You can only update the item: plumbus"}
def test_admin():
response = client.post(
"/admin/?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"message": "Admin getting schwifty"}
def test_admin_invalid_header():
response = client.post("/admin/", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -323,7 +483,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -332,160 +494,3 @@ openapi_schema = {
}
},
}
no_jessica = {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
@pytest.mark.parametrize(
"path,expected_status,expected_response,headers",
[
(
"/users?token=jessica",
200,
[{"username": "Rick"}, {"username": "Morty"}],
{},
),
("/users", 422, no_jessica, {}),
("/users/foo?token=jessica", 200, {"username": "foo"}, {}),
("/users/foo", 422, no_jessica, {}),
("/users/me?token=jessica", 200, {"username": "fakecurrentuser"}, {}),
("/users/me", 422, no_jessica, {}),
(
"/users?token=monica",
400,
{"detail": "No Jessica token provided"},
{},
),
(
"/items?token=jessica",
200,
{"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}},
{"X-Token": "fake-super-secret-token"},
),
("/items", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items/plumbus?token=jessica",
200,
{"name": "Plumbus", "item_id": "plumbus"},
{"X-Token": "fake-super-secret-token"},
),
(
"/items/bar?token=jessica",
404,
{"detail": "Item not found"},
{"X-Token": "fake-super-secret-token"},
),
("/items/plumbus", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items/bar?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
(
"/items/plumbus?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
("/?token=jessica", 200, {"message": "Hello Bigger Applications!"}, {}),
("/", 422, no_jessica, {}),
("/openapi.json", 200, openapi_schema, {}),
],
)
def test_get_path(path, expected_status, expected_response, headers):
response = client.get(path, headers=headers)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_put_no_header():
response = client.put("/items/foo")
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
def test_put_invalid_header():
response = client.put("/items/foo", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}
def test_put():
response = client.put(
"/items/plumbus?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "plumbus", "name": "The great Plumbus"}
def test_put_forbidden():
response = client.put(
"/items/bar?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "You can only update the item: plumbus"}
def test_admin():
response = client.post(
"/admin/?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"message": "Admin getting schwifty"}
def test_admin_invalid_header():
response = client.post("/admin/", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}

323
tests/test_tutorial/test_bigger_applications/test_main_an.py

@ -5,7 +5,167 @@ from docs_src.bigger_applications.app_an.main import app
client = TestClient(app)
openapi_schema = {
no_jessica = {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
@pytest.mark.parametrize(
"path,expected_status,expected_response,headers",
[
(
"/users?token=jessica",
200,
[{"username": "Rick"}, {"username": "Morty"}],
{},
),
("/users", 422, no_jessica, {}),
("/users/foo?token=jessica", 200, {"username": "foo"}, {}),
("/users/foo", 422, no_jessica, {}),
("/users/me?token=jessica", 200, {"username": "fakecurrentuser"}, {}),
("/users/me", 422, no_jessica, {}),
(
"/users?token=monica",
400,
{"detail": "No Jessica token provided"},
{},
),
(
"/items?token=jessica",
200,
{"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}},
{"X-Token": "fake-super-secret-token"},
),
("/items", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items/plumbus?token=jessica",
200,
{"name": "Plumbus", "item_id": "plumbus"},
{"X-Token": "fake-super-secret-token"},
),
(
"/items/bar?token=jessica",
404,
{"detail": "Item not found"},
{"X-Token": "fake-super-secret-token"},
),
("/items/plumbus", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items/bar?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
(
"/items/plumbus?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
("/?token=jessica", 200, {"message": "Hello Bigger Applications!"}, {}),
("/", 422, no_jessica, {}),
],
)
def test_get_path(path, expected_status, expected_response, headers):
response = client.get(path, headers=headers)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_put_no_header():
response = client.put("/items/foo")
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
def test_put_invalid_header():
response = client.put("/items/foo", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}
def test_put():
response = client.put(
"/items/plumbus?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "plumbus", "name": "The great Plumbus"}
def test_put_forbidden():
response = client.put(
"/items/bar?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "You can only update the item: plumbus"}
def test_admin():
response = client.post(
"/admin/?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"message": "Admin getting schwifty"}
def test_admin_invalid_header():
response = client.post("/admin/", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -323,7 +483,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -332,160 +494,3 @@ openapi_schema = {
}
},
}
no_jessica = {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
@pytest.mark.parametrize(
"path,expected_status,expected_response,headers",
[
(
"/users?token=jessica",
200,
[{"username": "Rick"}, {"username": "Morty"}],
{},
),
("/users", 422, no_jessica, {}),
("/users/foo?token=jessica", 200, {"username": "foo"}, {}),
("/users/foo", 422, no_jessica, {}),
("/users/me?token=jessica", 200, {"username": "fakecurrentuser"}, {}),
("/users/me", 422, no_jessica, {}),
(
"/users?token=monica",
400,
{"detail": "No Jessica token provided"},
{},
),
(
"/items?token=jessica",
200,
{"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}},
{"X-Token": "fake-super-secret-token"},
),
("/items", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items/plumbus?token=jessica",
200,
{"name": "Plumbus", "item_id": "plumbus"},
{"X-Token": "fake-super-secret-token"},
),
(
"/items/bar?token=jessica",
404,
{"detail": "Item not found"},
{"X-Token": "fake-super-secret-token"},
),
("/items/plumbus", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items/bar?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
(
"/items/plumbus?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
("/?token=jessica", 200, {"message": "Hello Bigger Applications!"}, {}),
("/", 422, no_jessica, {}),
("/openapi.json", 200, openapi_schema, {}),
],
)
def test_get_path(path, expected_status, expected_response, headers):
response = client.get(path, headers=headers)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_put_no_header():
response = client.put("/items/foo")
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
def test_put_invalid_header():
response = client.put("/items/foo", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}
def test_put():
response = client.put(
"/items/plumbus?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "plumbus", "name": "The great Plumbus"}
def test_put_forbidden():
response = client.put(
"/items/bar?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "You can only update the item: plumbus"}
def test_admin():
response = client.post(
"/admin/?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"message": "Admin getting schwifty"}
def test_admin_invalid_header():
response = client.post("/admin/", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}

357
tests/test_tutorial/test_bigger_applications/test_main_an_py39.py

@ -3,7 +3,184 @@ from fastapi.testclient import TestClient
from ...utils import needs_py39
openapi_schema = {
no_jessica = {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
@pytest.fixture(name="client")
def get_client():
from docs_src.bigger_applications.app_an_py39.main import app
client = TestClient(app)
return client
@needs_py39
@pytest.mark.parametrize(
"path,expected_status,expected_response,headers",
[
(
"/users?token=jessica",
200,
[{"username": "Rick"}, {"username": "Morty"}],
{},
),
("/users", 422, no_jessica, {}),
("/users/foo?token=jessica", 200, {"username": "foo"}, {}),
("/users/foo", 422, no_jessica, {}),
("/users/me?token=jessica", 200, {"username": "fakecurrentuser"}, {}),
("/users/me", 422, no_jessica, {}),
(
"/users?token=monica",
400,
{"detail": "No Jessica token provided"},
{},
),
(
"/items?token=jessica",
200,
{"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}},
{"X-Token": "fake-super-secret-token"},
),
("/items", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items/plumbus?token=jessica",
200,
{"name": "Plumbus", "item_id": "plumbus"},
{"X-Token": "fake-super-secret-token"},
),
(
"/items/bar?token=jessica",
404,
{"detail": "Item not found"},
{"X-Token": "fake-super-secret-token"},
),
("/items/plumbus", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items/bar?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
(
"/items/plumbus?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
("/?token=jessica", 200, {"message": "Hello Bigger Applications!"}, {}),
("/", 422, no_jessica, {}),
],
)
def test_get_path(
path, expected_status, expected_response, headers, client: TestClient
):
response = client.get(path, headers=headers)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py39
def test_put_no_header(client: TestClient):
response = client.put("/items/foo")
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
@needs_py39
def test_put_invalid_header(client: TestClient):
response = client.put("/items/foo", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}
@needs_py39
def test_put(client: TestClient):
response = client.put(
"/items/plumbus?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "plumbus", "name": "The great Plumbus"}
@needs_py39
def test_put_forbidden(client: TestClient):
response = client.put(
"/items/bar?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "You can only update the item: plumbus"}
@needs_py39
def test_admin(client: TestClient):
response = client.post(
"/admin/?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"message": "Admin getting schwifty"}
@needs_py39
def test_admin_invalid_header(client: TestClient):
response = client.post("/admin/", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}
@needs_py39
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -321,7 +498,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -330,177 +509,3 @@ openapi_schema = {
}
},
}
no_jessica = {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
@pytest.fixture(name="client")
def get_client():
from docs_src.bigger_applications.app_an_py39.main import app
client = TestClient(app)
return client
@needs_py39
@pytest.mark.parametrize(
"path,expected_status,expected_response,headers",
[
(
"/users?token=jessica",
200,
[{"username": "Rick"}, {"username": "Morty"}],
{},
),
("/users", 422, no_jessica, {}),
("/users/foo?token=jessica", 200, {"username": "foo"}, {}),
("/users/foo", 422, no_jessica, {}),
("/users/me?token=jessica", 200, {"username": "fakecurrentuser"}, {}),
("/users/me", 422, no_jessica, {}),
(
"/users?token=monica",
400,
{"detail": "No Jessica token provided"},
{},
),
(
"/items?token=jessica",
200,
{"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}},
{"X-Token": "fake-super-secret-token"},
),
("/items", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items/plumbus?token=jessica",
200,
{"name": "Plumbus", "item_id": "plumbus"},
{"X-Token": "fake-super-secret-token"},
),
(
"/items/bar?token=jessica",
404,
{"detail": "Item not found"},
{"X-Token": "fake-super-secret-token"},
),
("/items/plumbus", 422, no_jessica, {"X-Token": "fake-super-secret-token"}),
(
"/items?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items/bar?token=jessica",
400,
{"detail": "X-Token header invalid"},
{"X-Token": "invalid"},
),
(
"/items?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
(
"/items/plumbus?token=jessica",
422,
{
"detail": [
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
}
]
},
{},
),
("/?token=jessica", 200, {"message": "Hello Bigger Applications!"}, {}),
("/", 422, no_jessica, {}),
("/openapi.json", 200, openapi_schema, {}),
],
)
def test_get_path(
path, expected_status, expected_response, headers, client: TestClient
):
response = client.get(path, headers=headers)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py39
def test_put_no_header(client: TestClient):
response = client.put("/items/foo")
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["query", "token"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["header", "x-token"],
"msg": "field required",
"type": "value_error.missing",
},
]
}
@needs_py39
def test_put_invalid_header(client: TestClient):
response = client.put("/items/foo", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}
@needs_py39
def test_put(client: TestClient):
response = client.put(
"/items/plumbus?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"item_id": "plumbus", "name": "The great Plumbus"}
@needs_py39
def test_put_forbidden(client: TestClient):
response = client.put(
"/items/bar?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 403, response.text
assert response.json() == {"detail": "You can only update the item: plumbus"}
@needs_py39
def test_admin(client: TestClient):
response = client.post(
"/admin/?token=jessica", headers={"X-Token": "fake-super-secret-token"}
)
assert response.status_code == 200, response.text
assert response.json() == {"message": "Admin getting schwifty"}
@needs_py39
def test_admin_invalid_header(client: TestClient):
response = client.post("/admin/", headers={"X-Token": "invalid"})
assert response.status_code == 400, response.text
assert response.json() == {"detail": "X-Token header invalid"}

166
tests/test_tutorial/test_body/test_tutorial001.py

@ -7,89 +7,6 @@ from docs_src.body.tutorial001 import app
client = TestClient(app)
openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/": {
"post": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"summary": "Create Item",
"operationId": "create_item_items__post",
"requestBody": {
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
},
}
}
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": {"title": "Description", "type": "string"},
"tax": {"title": "Tax", "type": "number"},
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
price_missing = {
"detail": [
@ -277,3 +194,86 @@ def test_other_exceptions():
with patch("json.loads", side_effect=Exception):
response = client.post("/items/", json={"test": "test2"})
assert response.status_code == 400, response.text
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/": {
"post": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"summary": "Create Item",
"operationId": "create_item_items__post",
"requestBody": {
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
},
}
}
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": {"title": "Description", "type": "string"},
"tax": {"title": "Tax", "type": "number"},
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
}
},
}

168
tests/test_tutorial/test_body/test_tutorial001_py310.py

@ -5,83 +5,6 @@ from fastapi.testclient import TestClient
from ...utils import needs_py310
openapi_schema = {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/": {
"post": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"summary": "Create Item",
"operationId": "create_item_items__post",
"requestBody": {
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
},
}
}
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": {"title": "Description", "type": "string"},
"tax": {"title": "Tax", "type": "number"},
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
}
},
}
@pytest.fixture
def client():
@ -91,13 +14,6 @@ def client():
return client
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
price_missing = {
"detail": [
{
@ -292,3 +208,87 @@ def test_other_exceptions(client: TestClient):
with patch("json.loads", side_effect=Exception):
response = client.post("/items/", json={"test": "test2"})
assert response.status_code == 400, response.text
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/items/": {
"post": {
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
"summary": "Create Item",
"operationId": "create_item_items__post",
"requestBody": {
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/Item"}
}
},
"required": True,
},
}
}
},
"components": {
"schemas": {
"Item": {
"title": "Item",
"required": ["name", "price"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"price": {"title": "Price", "type": "number"},
"description": {"title": "Description", "type": "string"},
"tax": {"title": "Tax", "type": "number"},
},
},
"ValidationError": {
"title": "ValidationError",
"required": ["loc", "msg", "type"],
"type": "object",
"properties": {
"loc": {
"title": "Location",
"type": "array",
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
},
},
"HTTPValidationError": {
"title": "HTTPValidationError",
"type": "object",
"properties": {
"detail": {
"title": "Detail",
"type": "array",
"items": {"$ref": "#/components/schemas/ValidationError"},
}
},
},
}
},
}

123
tests/test_tutorial/test_body_fields/test_tutorial001.py

@ -6,7 +6,64 @@ from docs_src.body_fields.tutorial001 import app
client = TestClient(app)
openapi_schema = {
price_not_greater = {
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{"item": {"name": "Foo", "price": 3.0}},
200,
{
"item_id": 5,
"item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
},
),
(
"/items/6",
{
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": "5.4",
}
},
200,
{
"item_id": 6,
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": 5.4,
},
},
),
("/items/5", {"item": {"name": "Foo", "price": -3.0}}, 422, price_not_greater),
],
)
def test(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -87,7 +144,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -107,63 +166,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
price_not_greater = {
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{"item": {"name": "Foo", "price": 3.0}},
200,
{
"item_id": 5,
"item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
},
),
(
"/items/6",
{
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": "5.4",
}
},
200,
{
"item_id": 6,
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": 5.4,
},
},
),
("/items/5", {"item": {"name": "Foo", "price": -3.0}}, 422, price_not_greater),
],
)
def test(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

123
tests/test_tutorial/test_body_fields/test_tutorial001_an.py

@ -6,7 +6,64 @@ from docs_src.body_fields.tutorial001_an import app
client = TestClient(app)
openapi_schema = {
price_not_greater = {
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{"item": {"name": "Foo", "price": 3.0}},
200,
{
"item_id": 5,
"item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
},
),
(
"/items/6",
{
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": "5.4",
}
},
200,
{
"item_id": 6,
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": 5.4,
},
},
),
("/items/5", {"item": {"name": "Foo", "price": -3.0}}, 422, price_not_greater),
],
)
def test(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -87,7 +144,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -107,63 +166,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
price_not_greater = {
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{"item": {"name": "Foo", "price": 3.0}},
200,
{
"item_id": 5,
"item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
},
),
(
"/items/6",
{
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": "5.4",
}
},
200,
{
"item_id": 6,
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": 5.4,
},
},
),
("/items/5", {"item": {"name": "Foo", "price": -3.0}}, 422, price_not_greater),
],
)
def test(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

144
tests/test_tutorial/test_body_fields/test_tutorial001_an_py310.py

@ -3,7 +3,75 @@ from fastapi.testclient import TestClient
from ...utils import needs_py310
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_fields.tutorial001_an_py310 import app
client = TestClient(app)
return client
price_not_greater = {
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{"item": {"name": "Foo", "price": 3.0}},
200,
{
"item_id": 5,
"item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
},
),
(
"/items/6",
{
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": "5.4",
}
},
200,
{
"item_id": 6,
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": 5.4,
},
},
),
("/items/5", {"item": {"name": "Foo", "price": -3.0}}, 422, price_not_greater),
],
)
def test(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -84,7 +152,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -104,73 +174,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_fields.tutorial001_an_py310 import app
client = TestClient(app)
return client
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
price_not_greater = {
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{"item": {"name": "Foo", "price": 3.0}},
200,
{
"item_id": 5,
"item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
},
),
(
"/items/6",
{
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": "5.4",
}
},
200,
{
"item_id": 6,
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": 5.4,
},
},
),
("/items/5", {"item": {"name": "Foo", "price": -3.0}}, 422, price_not_greater),
],
)
def test(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

144
tests/test_tutorial/test_body_fields/test_tutorial001_an_py39.py

@ -3,7 +3,75 @@ from fastapi.testclient import TestClient
from ...utils import needs_py39
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_fields.tutorial001_an_py39 import app
client = TestClient(app)
return client
price_not_greater = {
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
@needs_py39
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{"item": {"name": "Foo", "price": 3.0}},
200,
{
"item_id": 5,
"item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
},
),
(
"/items/6",
{
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": "5.4",
}
},
200,
{
"item_id": 6,
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": 5.4,
},
},
),
("/items/5", {"item": {"name": "Foo", "price": -3.0}}, 422, price_not_greater),
],
)
def test(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py39
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -84,7 +152,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -104,73 +174,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_fields.tutorial001_an_py39 import app
client = TestClient(app)
return client
@needs_py39
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
price_not_greater = {
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
@needs_py39
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{"item": {"name": "Foo", "price": 3.0}},
200,
{
"item_id": 5,
"item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
},
),
(
"/items/6",
{
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": "5.4",
}
},
200,
{
"item_id": 6,
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": 5.4,
},
},
),
("/items/5", {"item": {"name": "Foo", "price": -3.0}}, 422, price_not_greater),
],
)
def test(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

144
tests/test_tutorial/test_body_fields/test_tutorial001_py310.py

@ -3,7 +3,75 @@ from fastapi.testclient import TestClient
from ...utils import needs_py310
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_fields.tutorial001_py310 import app
client = TestClient(app)
return client
price_not_greater = {
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{"item": {"name": "Foo", "price": 3.0}},
200,
{
"item_id": 5,
"item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
},
),
(
"/items/6",
{
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": "5.4",
}
},
200,
{
"item_id": 6,
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": 5.4,
},
},
),
("/items/5", {"item": {"name": "Foo", "price": -3.0}}, 422, price_not_greater),
],
)
def test(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -84,7 +152,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -104,73 +174,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_fields.tutorial001_py310 import app
client = TestClient(app)
return client
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
price_not_greater = {
"detail": [
{
"ctx": {"limit_value": 0},
"loc": ["body", "item", "price"],
"msg": "ensure this value is greater than 0",
"type": "value_error.number.not_gt",
}
]
}
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{"item": {"name": "Foo", "price": 3.0}},
200,
{
"item_id": 5,
"item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
},
),
(
"/items/6",
{
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": "5.4",
}
},
200,
{
"item_id": 6,
"item": {
"name": "Bar",
"price": 0.2,
"description": "Some bar",
"tax": 5.4,
},
},
),
("/items/5", {"item": {"name": "Foo", "price": -3.0}}, 422, price_not_greater),
],
)
def test(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

96
tests/test_tutorial/test_body_multiple_params/test_tutorial001.py

@ -5,7 +5,51 @@ from docs_src.body_multiple_params.tutorial001 import app
client = TestClient(app)
openapi_schema = {
item_id_not_int = {
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5?q=bar",
{"name": "Foo", "price": 50.5},
200,
{
"item_id": 5,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"q": "bar",
},
),
("/items/5?q=bar", None, 200, {"item_id": 5, "q": "bar"}),
("/items/5", None, 200, {"item_id": 5}),
("/items/foo", None, 422, item_id_not_int),
],
)
def test_post_body(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -79,7 +123,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -99,49 +145,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
item_id_not_int = {
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5?q=bar",
{"name": "Foo", "price": 50.5},
200,
{
"item_id": 5,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"q": "bar",
},
),
("/items/5?q=bar", None, 200, {"item_id": 5, "q": "bar"}),
("/items/5", None, 200, {"item_id": 5}),
("/items/foo", None, 422, item_id_not_int),
],
)
def test_post_body(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

96
tests/test_tutorial/test_body_multiple_params/test_tutorial001_an.py

@ -5,7 +5,51 @@ from docs_src.body_multiple_params.tutorial001_an import app
client = TestClient(app)
openapi_schema = {
item_id_not_int = {
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5?q=bar",
{"name": "Foo", "price": 50.5},
200,
{
"item_id": 5,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"q": "bar",
},
),
("/items/5?q=bar", None, 200, {"item_id": 5, "q": "bar"}),
("/items/5", None, 200, {"item_id": 5}),
("/items/foo", None, 422, item_id_not_int),
],
)
def test_post_body(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -79,7 +123,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -99,49 +145,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
item_id_not_int = {
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5?q=bar",
{"name": "Foo", "price": 50.5},
200,
{
"item_id": 5,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"q": "bar",
},
),
("/items/5?q=bar", None, 200, {"item_id": 5, "q": "bar"}),
("/items/5", None, 200, {"item_id": 5}),
("/items/foo", None, 422, item_id_not_int),
],
)
def test_post_body(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

116
tests/test_tutorial/test_body_multiple_params/test_tutorial001_an_py310.py

@ -3,7 +3,61 @@ from fastapi.testclient import TestClient
from ...utils import needs_py310
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial001_an_py310 import app
client = TestClient(app)
return client
item_id_not_int = {
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5?q=bar",
{"name": "Foo", "price": 50.5},
200,
{
"item_id": 5,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"q": "bar",
},
),
("/items/5?q=bar", None, 200, {"item_id": 5, "q": "bar"}),
("/items/5", None, 200, {"item_id": 5}),
("/items/foo", None, 422, item_id_not_int),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -77,7 +131,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -97,59 +153,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial001_an_py310 import app
client = TestClient(app)
return client
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
item_id_not_int = {
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5?q=bar",
{"name": "Foo", "price": 50.5},
200,
{
"item_id": 5,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"q": "bar",
},
),
("/items/5?q=bar", None, 200, {"item_id": 5, "q": "bar"}),
("/items/5", None, 200, {"item_id": 5}),
("/items/foo", None, 422, item_id_not_int),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

116
tests/test_tutorial/test_body_multiple_params/test_tutorial001_an_py39.py

@ -3,7 +3,61 @@ from fastapi.testclient import TestClient
from ...utils import needs_py39
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial001_an_py39 import app
client = TestClient(app)
return client
item_id_not_int = {
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@needs_py39
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5?q=bar",
{"name": "Foo", "price": 50.5},
200,
{
"item_id": 5,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"q": "bar",
},
),
("/items/5?q=bar", None, 200, {"item_id": 5, "q": "bar"}),
("/items/5", None, 200, {"item_id": 5}),
("/items/foo", None, 422, item_id_not_int),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py39
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -77,7 +131,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -97,59 +153,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial001_an_py39 import app
client = TestClient(app)
return client
@needs_py39
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
item_id_not_int = {
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@needs_py39
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5?q=bar",
{"name": "Foo", "price": 50.5},
200,
{
"item_id": 5,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"q": "bar",
},
),
("/items/5?q=bar", None, 200, {"item_id": 5, "q": "bar"}),
("/items/5", None, 200, {"item_id": 5}),
("/items/foo", None, 422, item_id_not_int),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

116
tests/test_tutorial/test_body_multiple_params/test_tutorial001_py310.py

@ -3,7 +3,61 @@ from fastapi.testclient import TestClient
from ...utils import needs_py310
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial001_py310 import app
client = TestClient(app)
return client
item_id_not_int = {
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5?q=bar",
{"name": "Foo", "price": 50.5},
200,
{
"item_id": 5,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"q": "bar",
},
),
("/items/5?q=bar", None, 200, {"item_id": 5, "q": "bar"}),
("/items/5", None, 200, {"item_id": 5}),
("/items/foo", None, 422, item_id_not_int),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -77,7 +131,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -97,59 +153,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial001_py310 import app
client = TestClient(app)
return client
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
item_id_not_int = {
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5?q=bar",
{"name": "Foo", "price": 50.5},
200,
{
"item_id": 5,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"q": "bar",
},
),
("/items/5?q=bar", None, 200, {"item_id": 5, "q": "bar"}),
("/items/5", None, 200, {"item_id": 5}),
("/items/foo", None, 422, item_id_not_int),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

176
tests/test_tutorial/test_body_multiple_params/test_tutorial003.py

@ -5,7 +5,91 @@ from docs_src.body_multiple_params.tutorial003 import app
client = TestClient(app)
openapi_schema = {
# Test required and embedded body parameters with no bodies sent
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{
"importance": 2,
"item": {"name": "Foo", "price": 50.5},
"user": {"username": "Dave"},
},
200,
{
"item_id": 5,
"importance": 2,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"user": {"username": "Dave", "full_name": None},
},
),
(
"/items/5",
None,
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
(
"/items/5",
[],
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
],
)
def test_post_body(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -90,7 +174,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -110,89 +196,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
# Test required and embedded body parameters with no bodies sent
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{
"importance": 2,
"item": {"name": "Foo", "price": 50.5},
"user": {"username": "Dave"},
},
200,
{
"item_id": 5,
"importance": 2,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"user": {"username": "Dave", "full_name": None},
},
),
(
"/items/5",
None,
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
(
"/items/5",
[],
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
],
)
def test_post_body(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

176
tests/test_tutorial/test_body_multiple_params/test_tutorial003_an.py

@ -5,7 +5,91 @@ from docs_src.body_multiple_params.tutorial003_an import app
client = TestClient(app)
openapi_schema = {
# Test required and embedded body parameters with no bodies sent
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{
"importance": 2,
"item": {"name": "Foo", "price": 50.5},
"user": {"username": "Dave"},
},
200,
{
"item_id": 5,
"importance": 2,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"user": {"username": "Dave", "full_name": None},
},
),
(
"/items/5",
None,
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
(
"/items/5",
[],
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
],
)
def test_post_body(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -90,7 +174,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -110,89 +196,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
# Test required and embedded body parameters with no bodies sent
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{
"importance": 2,
"item": {"name": "Foo", "price": 50.5},
"user": {"username": "Dave"},
},
200,
{
"item_id": 5,
"importance": 2,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"user": {"username": "Dave", "full_name": None},
},
),
(
"/items/5",
None,
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
(
"/items/5",
[],
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
],
)
def test_post_body(path, body, expected_status, expected_response):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

196
tests/test_tutorial/test_body_multiple_params/test_tutorial003_an_py310.py

@ -3,7 +3,101 @@ from fastapi.testclient import TestClient
from ...utils import needs_py310
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial003_an_py310 import app
client = TestClient(app)
return client
# Test required and embedded body parameters with no bodies sent
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{
"importance": 2,
"item": {"name": "Foo", "price": 50.5},
"user": {"username": "Dave"},
},
200,
{
"item_id": 5,
"importance": 2,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"user": {"username": "Dave", "full_name": None},
},
),
(
"/items/5",
None,
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
(
"/items/5",
[],
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -88,7 +182,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -108,99 +204,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial003_an_py310 import app
client = TestClient(app)
return client
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
# Test required and embedded body parameters with no bodies sent
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{
"importance": 2,
"item": {"name": "Foo", "price": 50.5},
"user": {"username": "Dave"},
},
200,
{
"item_id": 5,
"importance": 2,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"user": {"username": "Dave", "full_name": None},
},
),
(
"/items/5",
None,
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
(
"/items/5",
[],
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

196
tests/test_tutorial/test_body_multiple_params/test_tutorial003_an_py39.py

@ -3,7 +3,101 @@ from fastapi.testclient import TestClient
from ...utils import needs_py39
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial003_an_py39 import app
client = TestClient(app)
return client
# Test required and embedded body parameters with no bodies sent
@needs_py39
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{
"importance": 2,
"item": {"name": "Foo", "price": 50.5},
"user": {"username": "Dave"},
},
200,
{
"item_id": 5,
"importance": 2,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"user": {"username": "Dave", "full_name": None},
},
),
(
"/items/5",
None,
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
(
"/items/5",
[],
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py39
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -88,7 +182,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -108,99 +204,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial003_an_py39 import app
client = TestClient(app)
return client
@needs_py39
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
# Test required and embedded body parameters with no bodies sent
@needs_py39
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{
"importance": 2,
"item": {"name": "Foo", "price": 50.5},
"user": {"username": "Dave"},
},
200,
{
"item_id": 5,
"importance": 2,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"user": {"username": "Dave", "full_name": None},
},
),
(
"/items/5",
None,
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
(
"/items/5",
[],
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

196
tests/test_tutorial/test_body_multiple_params/test_tutorial003_py310.py

@ -3,7 +3,101 @@ from fastapi.testclient import TestClient
from ...utils import needs_py310
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial003_py310 import app
client = TestClient(app)
return client
# Test required and embedded body parameters with no bodies sent
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{
"importance": 2,
"item": {"name": "Foo", "price": 50.5},
"user": {"username": "Dave"},
},
200,
{
"item_id": 5,
"importance": 2,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"user": {"username": "Dave", "full_name": None},
},
),
(
"/items/5",
None,
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
(
"/items/5",
[],
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -88,7 +182,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -108,99 +204,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_multiple_params.tutorial003_py310 import app
client = TestClient(app)
return client
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
# Test required and embedded body parameters with no bodies sent
@needs_py310
@pytest.mark.parametrize(
"path,body,expected_status,expected_response",
[
(
"/items/5",
{
"importance": 2,
"item": {"name": "Foo", "price": 50.5},
"user": {"username": "Dave"},
},
200,
{
"item_id": 5,
"importance": 2,
"item": {
"name": "Foo",
"price": 50.5,
"description": None,
"tax": None,
},
"user": {"username": "Dave", "full_name": None},
},
),
(
"/items/5",
None,
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
(
"/items/5",
[],
422,
{
"detail": [
{
"loc": ["body", "item"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "user"],
"msg": "field required",
"type": "value_error.missing",
},
{
"loc": ["body", "importance"],
"msg": "field required",
"type": "value_error.missing",
},
]
},
),
],
)
def test_post_body(path, body, expected_status, expected_response, client: TestClient):
response = client.put(path, json=body)
assert response.status_code == expected_status
assert response.json() == expected_response

60
tests/test_tutorial/test_body_nested_models/test_tutorial009.py

@ -4,7 +4,33 @@ from docs_src.body_nested_models.tutorial009 import app
client = TestClient(app)
openapi_schema = {
def test_post_body():
data = {"2": 2.2, "3": 3.3}
response = client.post("/index-weights/", json=data)
assert response.status_code == 200, response.text
assert response.json() == data
def test_post_invalid_body():
data = {"foo": 2.2, "3": 3.3}
response = client.post("/index-weights/", json=data)
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["body", "__key__"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -53,7 +79,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -73,31 +101,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_post_body():
data = {"2": 2.2, "3": 3.3}
response = client.post("/index-weights/", json=data)
assert response.status_code == 200, response.text
assert response.json() == data
def test_post_invalid_body():
data = {"foo": 2.2, "3": 3.3}
response = client.post("/index-weights/", json=data)
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["body", "__key__"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}

82
tests/test_tutorial/test_body_nested_models/test_tutorial009_py39.py

@ -3,7 +3,44 @@ from fastapi.testclient import TestClient
from ...utils import needs_py39
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_nested_models.tutorial009_py39 import app
client = TestClient(app)
return client
@needs_py39
def test_post_body(client: TestClient):
data = {"2": 2.2, "3": 3.3}
response = client.post("/index-weights/", json=data)
assert response.status_code == 200, response.text
assert response.json() == data
@needs_py39
def test_post_invalid_body(client: TestClient):
data = {"foo": 2.2, "3": 3.3}
response = client.post("/index-weights/", json=data)
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["body", "__key__"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}
@needs_py39
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -52,7 +89,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -72,42 +111,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_nested_models.tutorial009_py39 import app
client = TestClient(app)
return client
@needs_py39
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
@needs_py39
def test_post_body(client: TestClient):
data = {"2": 2.2, "3": 3.3}
response = client.post("/index-weights/", json=data)
assert response.status_code == 200, response.text
assert response.json() == data
@needs_py39
def test_post_invalid_body(client: TestClient):
data = {"foo": 2.2, "3": 3.3}
response = client.post("/index-weights/", json=data)
assert response.status_code == 422, response.text
assert response.json() == {
"detail": [
{
"loc": ["body", "__key__"],
"msg": "value is not a valid integer",
"type": "type_error.integer",
}
]
}

66
tests/test_tutorial/test_body_updates/test_tutorial001.py

@ -4,7 +4,36 @@ from docs_src.body_updates.tutorial001 import app
client = TestClient(app)
openapi_schema = {
def test_get():
response = client.get("/items/baz")
assert response.status_code == 200, response.text
assert response.json() == {
"name": "Baz",
"description": None,
"price": 50.2,
"tax": 10.5,
"tags": [],
}
def test_put():
response = client.put(
"/items/bar", json={"name": "Barz", "price": 3, "description": None}
)
assert response.json() == {
"name": "Barz",
"description": None,
"price": 3,
"tax": 10.5,
"tags": [],
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -109,7 +138,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -129,34 +160,3 @@ openapi_schema = {
}
},
}
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
def test_get():
response = client.get("/items/baz")
assert response.status_code == 200, response.text
assert response.json() == {
"name": "Baz",
"description": None,
"price": 50.2,
"tax": 10.5,
"tags": [],
}
def test_put():
response = client.put(
"/items/bar", json={"name": "Barz", "price": 3, "description": None}
)
assert response.json() == {
"name": "Barz",
"description": None,
"price": 3,
"tax": 10.5,
"tags": [],
}

88
tests/test_tutorial/test_body_updates/test_tutorial001_py310.py

@ -3,7 +3,47 @@ from fastapi.testclient import TestClient
from ...utils import needs_py310
openapi_schema = {
@pytest.fixture(name="client")
def get_client():
from docs_src.body_updates.tutorial001_py310 import app
client = TestClient(app)
return client
@needs_py310
def test_get(client: TestClient):
response = client.get("/items/baz")
assert response.status_code == 200, response.text
assert response.json() == {
"name": "Baz",
"description": None,
"price": 50.2,
"tax": 10.5,
"tags": [],
}
@needs_py310
def test_put(client: TestClient):
response = client.put(
"/items/bar", json={"name": "Barz", "price": 3, "description": None}
)
assert response.json() == {
"name": "Barz",
"description": None,
"price": 3,
"tax": 10.5,
"tags": [],
}
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"openapi": "3.0.2",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
@ -108,7 +148,9 @@ openapi_schema = {
"loc": {
"title": "Location",
"type": "array",
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"items": {
"anyOf": [{"type": "string"}, {"type": "integer"}]
},
},
"msg": {"title": "Message", "type": "string"},
"type": {"title": "Error Type", "type": "string"},
@ -128,45 +170,3 @@ openapi_schema = {
}
},
}
@pytest.fixture(name="client")
def get_client():
from docs_src.body_updates.tutorial001_py310 import app
client = TestClient(app)
return client
@needs_py310
def test_openapi_schema(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == openapi_schema
@needs_py310
def test_get(client: TestClient):
response = client.get("/items/baz")
assert response.status_code == 200, response.text
assert response.json() == {
"name": "Baz",
"description": None,
"price": 50.2,
"tax": 10.5,
"tags": [],
}
@needs_py310
def test_put(client: TestClient):
response = client.put(
"/items/bar", json={"name": "Barz", "price": 3, "description": None}
)
assert response.json() == {
"name": "Barz",
"description": None,
"price": 3,
"tax": 10.5,
"tags": [],
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save