mirror of https://github.com/tiangolo/fastapi.git
⬆ Upgrade Starlette to `0.21.0`, including the new [`TestClient` based on HTTPX](https://github.com/encode/starlette/releases/tag/0.21.0) (#5471)
Co-authored-by: Paweł Rubin <pawel.rubin@ocado.com> Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
This commit is contained in:
parent
5f67ac6fd6
commit
fdbd48be5f
|
|
@ -54,7 +54,7 @@ class APIKeyHeader(APIKeyBase):
|
||||||
self.auto_error = auto_error
|
self.auto_error = auto_error
|
||||||
|
|
||||||
async def __call__(self, request: Request) -> Optional[str]:
|
async def __call__(self, request: Request) -> Optional[str]:
|
||||||
api_key: str = request.headers.get(self.model.name)
|
api_key = request.headers.get(self.model.name)
|
||||||
if not api_key:
|
if not api_key:
|
||||||
if self.auto_error:
|
if self.auto_error:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class HTTPBase(SecurityBase):
|
||||||
async def __call__(
|
async def __call__(
|
||||||
self, request: Request
|
self, request: Request
|
||||||
) -> Optional[HTTPAuthorizationCredentials]:
|
) -> Optional[HTTPAuthorizationCredentials]:
|
||||||
authorization: str = request.headers.get("Authorization")
|
authorization = request.headers.get("Authorization")
|
||||||
scheme, credentials = get_authorization_scheme_param(authorization)
|
scheme, credentials = get_authorization_scheme_param(authorization)
|
||||||
if not (authorization and scheme and credentials):
|
if not (authorization and scheme and credentials):
|
||||||
if self.auto_error:
|
if self.auto_error:
|
||||||
|
|
@ -67,7 +67,7 @@ class HTTPBasic(HTTPBase):
|
||||||
async def __call__( # type: ignore
|
async def __call__( # type: ignore
|
||||||
self, request: Request
|
self, request: Request
|
||||||
) -> Optional[HTTPBasicCredentials]:
|
) -> Optional[HTTPBasicCredentials]:
|
||||||
authorization: str = request.headers.get("Authorization")
|
authorization = request.headers.get("Authorization")
|
||||||
scheme, param = get_authorization_scheme_param(authorization)
|
scheme, param = get_authorization_scheme_param(authorization)
|
||||||
if self.realm:
|
if self.realm:
|
||||||
unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'}
|
unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'}
|
||||||
|
|
@ -113,7 +113,7 @@ class HTTPBearer(HTTPBase):
|
||||||
async def __call__(
|
async def __call__(
|
||||||
self, request: Request
|
self, request: Request
|
||||||
) -> Optional[HTTPAuthorizationCredentials]:
|
) -> Optional[HTTPAuthorizationCredentials]:
|
||||||
authorization: str = request.headers.get("Authorization")
|
authorization = request.headers.get("Authorization")
|
||||||
scheme, credentials = get_authorization_scheme_param(authorization)
|
scheme, credentials = get_authorization_scheme_param(authorization)
|
||||||
if not (authorization and scheme and credentials):
|
if not (authorization and scheme and credentials):
|
||||||
if self.auto_error:
|
if self.auto_error:
|
||||||
|
|
@ -148,7 +148,7 @@ class HTTPDigest(HTTPBase):
|
||||||
async def __call__(
|
async def __call__(
|
||||||
self, request: Request
|
self, request: Request
|
||||||
) -> Optional[HTTPAuthorizationCredentials]:
|
) -> Optional[HTTPAuthorizationCredentials]:
|
||||||
authorization: str = request.headers.get("Authorization")
|
authorization = request.headers.get("Authorization")
|
||||||
scheme, credentials = get_authorization_scheme_param(authorization)
|
scheme, credentials = get_authorization_scheme_param(authorization)
|
||||||
if not (authorization and scheme and credentials):
|
if not (authorization and scheme and credentials):
|
||||||
if self.auto_error:
|
if self.auto_error:
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ class OAuth2(SecurityBase):
|
||||||
self.auto_error = auto_error
|
self.auto_error = auto_error
|
||||||
|
|
||||||
async def __call__(self, request: Request) -> Optional[str]:
|
async def __call__(self, request: Request) -> Optional[str]:
|
||||||
authorization: str = request.headers.get("Authorization")
|
authorization = request.headers.get("Authorization")
|
||||||
if not authorization:
|
if not authorization:
|
||||||
if self.auto_error:
|
if self.auto_error:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
@ -157,7 +157,7 @@ class OAuth2PasswordBearer(OAuth2):
|
||||||
)
|
)
|
||||||
|
|
||||||
async def __call__(self, request: Request) -> Optional[str]:
|
async def __call__(self, request: Request) -> Optional[str]:
|
||||||
authorization: str = request.headers.get("Authorization")
|
authorization = request.headers.get("Authorization")
|
||||||
scheme, param = get_authorization_scheme_param(authorization)
|
scheme, param = get_authorization_scheme_param(authorization)
|
||||||
if not authorization or scheme.lower() != "bearer":
|
if not authorization or scheme.lower() != "bearer":
|
||||||
if self.auto_error:
|
if self.auto_error:
|
||||||
|
|
@ -200,7 +200,7 @@ class OAuth2AuthorizationCodeBearer(OAuth2):
|
||||||
)
|
)
|
||||||
|
|
||||||
async def __call__(self, request: Request) -> Optional[str]:
|
async def __call__(self, request: Request) -> Optional[str]:
|
||||||
authorization: str = request.headers.get("Authorization")
|
authorization = request.headers.get("Authorization")
|
||||||
scheme, param = get_authorization_scheme_param(authorization)
|
scheme, param = get_authorization_scheme_param(authorization)
|
||||||
if not authorization or scheme.lower() != "bearer":
|
if not authorization or scheme.lower() != "bearer":
|
||||||
if self.auto_error:
|
if self.auto_error:
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class OpenIdConnect(SecurityBase):
|
||||||
self.auto_error = auto_error
|
self.auto_error = auto_error
|
||||||
|
|
||||||
async def __call__(self, request: Request) -> Optional[str]:
|
async def __call__(self, request: Request) -> Optional[str]:
|
||||||
authorization: str = request.headers.get("Authorization")
|
authorization = request.headers.get("Authorization")
|
||||||
if not authorization:
|
if not authorization:
|
||||||
if self.auto_error:
|
if self.auto_error:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
from typing import Tuple
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
|
|
||||||
def get_authorization_scheme_param(authorization_header_value: str) -> Tuple[str, str]:
|
def get_authorization_scheme_param(
|
||||||
|
authorization_header_value: Optional[str],
|
||||||
|
) -> Tuple[str, str]:
|
||||||
if not authorization_header_value:
|
if not authorization_header_value:
|
||||||
return "", ""
|
return "", ""
|
||||||
scheme, _, param = authorization_header_value.partition(" ")
|
scheme, _, param = authorization_header_value.partition(" ")
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ classifiers = [
|
||||||
"Topic :: Internet :: WWW/HTTP",
|
"Topic :: Internet :: WWW/HTTP",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"starlette==0.20.4",
|
"starlette==0.21.0",
|
||||||
"pydantic >=1.6.2,!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<2.0.0",
|
"pydantic >=1.6.2,!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<2.0.0",
|
||||||
]
|
]
|
||||||
dynamic = ["version"]
|
dynamic = ["version"]
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ def test_schema():
|
||||||
|
|
||||||
|
|
||||||
def test_get_invalid():
|
def test_get_invalid():
|
||||||
response = client.get("/foo", params={"client_id": None})
|
response = client.get("/foo")
|
||||||
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
|
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ def test_get_api_route_not_decorated():
|
||||||
|
|
||||||
|
|
||||||
def test_delete():
|
def test_delete():
|
||||||
response = client.delete("/items/foo", json={"name": "Foo"})
|
response = client.request("DELETE", "/items/foo", json={"name": "Foo"})
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == {"item_id": "foo", "item": {"name": "Foo", "price": None}}
|
assert response.json() == {"item_id": "foo", "item": {"name": "Foo", "price": None}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,5 +104,5 @@ def test_openapi_schema():
|
||||||
|
|
||||||
def test_get_with_body():
|
def test_get_with_body():
|
||||||
body = {"name": "Foo", "description": "Some description", "price": 5.5}
|
body = {"name": "Foo", "description": "Some description", "price": 5.5}
|
||||||
response = client.get("/product", json=body)
|
response = client.request("GET", "/product", json=body)
|
||||||
assert response.json() == body
|
assert response.json() == body
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,6 @@ async def hidden_query(
|
||||||
return {"hidden_query": hidden_query}
|
return {"hidden_query": hidden_query}
|
||||||
|
|
||||||
|
|
||||||
client = TestClient(app)
|
|
||||||
|
|
||||||
openapi_shema = {
|
openapi_shema = {
|
||||||
"openapi": "3.0.2",
|
"openapi": "3.0.2",
|
||||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||||
|
|
@ -161,6 +159,7 @@ openapi_shema = {
|
||||||
|
|
||||||
|
|
||||||
def test_openapi_schema():
|
def test_openapi_schema():
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get("/openapi.json")
|
response = client.get("/openapi.json")
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json() == openapi_shema
|
assert response.json() == openapi_shema
|
||||||
|
|
@ -184,7 +183,8 @@ def test_openapi_schema():
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_hidden_cookie(path, cookies, expected_status, expected_response):
|
def test_hidden_cookie(path, cookies, expected_status, expected_response):
|
||||||
response = client.get(path, cookies=cookies)
|
client = TestClient(app, cookies=cookies)
|
||||||
|
response = client.get(path)
|
||||||
assert response.status_code == expected_status
|
assert response.status_code == expected_status
|
||||||
assert response.json() == expected_response
|
assert response.json() == expected_response
|
||||||
|
|
||||||
|
|
@ -207,12 +207,14 @@ def test_hidden_cookie(path, cookies, expected_status, expected_response):
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_hidden_header(path, headers, expected_status, expected_response):
|
def test_hidden_header(path, headers, expected_status, expected_response):
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get(path, headers=headers)
|
response = client.get(path, headers=headers)
|
||||||
assert response.status_code == expected_status
|
assert response.status_code == expected_status
|
||||||
assert response.json() == expected_response
|
assert response.json() == expected_response
|
||||||
|
|
||||||
|
|
||||||
def test_hidden_path():
|
def test_hidden_path():
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get("/hidden_path/hidden_path")
|
response = client.get("/hidden_path/hidden_path")
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json() == {"hidden_path": "hidden_path"}
|
assert response.json() == {"hidden_path": "hidden_path"}
|
||||||
|
|
@ -234,6 +236,7 @@ def test_hidden_path():
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_hidden_query(path, expected_status, expected_response):
|
def test_hidden_query(path, expected_status, expected_response):
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get(path)
|
response = client.get(path)
|
||||||
assert response.status_code == expected_status
|
assert response.status_code == expected_status
|
||||||
assert response.json() == expected_response
|
assert response.json() == expected_response
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,6 @@ def read_current_user(current_user: User = Depends(get_current_user)):
|
||||||
return current_user
|
return current_user
|
||||||
|
|
||||||
|
|
||||||
client = TestClient(app)
|
|
||||||
|
|
||||||
openapi_schema = {
|
openapi_schema = {
|
||||||
"openapi": "3.0.2",
|
"openapi": "3.0.2",
|
||||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||||
|
|
@ -51,18 +49,21 @@ openapi_schema = {
|
||||||
|
|
||||||
|
|
||||||
def test_openapi_schema():
|
def test_openapi_schema():
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get("/openapi.json")
|
response = client.get("/openapi.json")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == openapi_schema
|
assert response.json() == openapi_schema
|
||||||
|
|
||||||
|
|
||||||
def test_security_api_key():
|
def test_security_api_key():
|
||||||
response = client.get("/users/me", cookies={"key": "secret"})
|
client = TestClient(app, cookies={"key": "secret"})
|
||||||
|
response = client.get("/users/me")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == {"username": "secret"}
|
assert response.json() == {"username": "secret"}
|
||||||
|
|
||||||
|
|
||||||
def test_security_api_key_no_key():
|
def test_security_api_key_no_key():
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get("/users/me")
|
response = client.get("/users/me")
|
||||||
assert response.status_code == 403, response.text
|
assert response.status_code == 403, response.text
|
||||||
assert response.json() == {"detail": "Not authenticated"}
|
assert response.json() == {"detail": "Not authenticated"}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,6 @@ def read_current_user(current_user: User = Depends(get_current_user)):
|
||||||
return current_user
|
return current_user
|
||||||
|
|
||||||
|
|
||||||
client = TestClient(app)
|
|
||||||
|
|
||||||
openapi_schema = {
|
openapi_schema = {
|
||||||
"openapi": "3.0.2",
|
"openapi": "3.0.2",
|
||||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||||
|
|
@ -56,18 +54,21 @@ openapi_schema = {
|
||||||
|
|
||||||
|
|
||||||
def test_openapi_schema():
|
def test_openapi_schema():
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get("/openapi.json")
|
response = client.get("/openapi.json")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == openapi_schema
|
assert response.json() == openapi_schema
|
||||||
|
|
||||||
|
|
||||||
def test_security_api_key():
|
def test_security_api_key():
|
||||||
response = client.get("/users/me", cookies={"key": "secret"})
|
client = TestClient(app, cookies={"key": "secret"})
|
||||||
|
response = client.get("/users/me")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == {"username": "secret"}
|
assert response.json() == {"username": "secret"}
|
||||||
|
|
||||||
|
|
||||||
def test_security_api_key_no_key():
|
def test_security_api_key_no_key():
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get("/users/me")
|
response = client.get("/users/me")
|
||||||
assert response.status_code == 403, response.text
|
assert response.status_code == 403, response.text
|
||||||
assert response.json() == {"detail": "Not authenticated"}
|
assert response.json() == {"detail": "Not authenticated"}
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@ def read_current_user(current_user: User = Depends(get_current_user)):
|
||||||
return current_user
|
return current_user
|
||||||
|
|
||||||
|
|
||||||
client = TestClient(app)
|
|
||||||
|
|
||||||
openapi_schema = {
|
openapi_schema = {
|
||||||
"openapi": "3.0.2",
|
"openapi": "3.0.2",
|
||||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||||
|
|
@ -58,18 +56,21 @@ openapi_schema = {
|
||||||
|
|
||||||
|
|
||||||
def test_openapi_schema():
|
def test_openapi_schema():
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get("/openapi.json")
|
response = client.get("/openapi.json")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == openapi_schema
|
assert response.json() == openapi_schema
|
||||||
|
|
||||||
|
|
||||||
def test_security_api_key():
|
def test_security_api_key():
|
||||||
response = client.get("/users/me", cookies={"key": "secret"})
|
client = TestClient(app, cookies={"key": "secret"})
|
||||||
|
response = client.get("/users/me")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == {"username": "secret"}
|
assert response.json() == {"username": "secret"}
|
||||||
|
|
||||||
|
|
||||||
def test_security_api_key_no_key():
|
def test_security_api_key_no_key():
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get("/users/me")
|
response = client.get("/users/me")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == {"msg": "Create an account first"}
|
assert response.json() == {"msg": "Create an account first"}
|
||||||
|
|
|
||||||
|
|
@ -252,16 +252,14 @@ def test_tuple_with_model_invalid():
|
||||||
|
|
||||||
|
|
||||||
def test_tuple_form_valid():
|
def test_tuple_form_valid():
|
||||||
response = client.post("/tuple-form/", data=[("values", "1"), ("values", "2")])
|
response = client.post("/tuple-form/", data={"values": ("1", "2")})
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == [1, 2]
|
assert response.json() == [1, 2]
|
||||||
|
|
||||||
|
|
||||||
def test_tuple_form_invalid():
|
def test_tuple_form_invalid():
|
||||||
response = client.post(
|
response = client.post("/tuple-form/", data={"values": ("1", "2", "3")})
|
||||||
"/tuple-form/", data=[("values", "1"), ("values", "2"), ("values", "3")]
|
|
||||||
)
|
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
|
|
||||||
response = client.post("/tuple-form/", data=[("values", "1")])
|
response = client.post("/tuple-form/", data={"values": ("1")})
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@ def test_middleware():
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
|
|
||||||
client = TestClient(app)
|
client = TestClient(app)
|
||||||
response = client.get("/", allow_redirects=False)
|
response = client.get("/", follow_redirects=False)
|
||||||
assert response.status_code == 307, response.text
|
assert response.status_code == 307, response.text
|
||||||
assert response.headers["location"] == "https://testserver/"
|
assert response.headers["location"] == "https://testserver/"
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ def test_post_broken_body():
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/",
|
"/items/",
|
||||||
headers={"content-type": "application/json"},
|
headers={"content-type": "application/json"},
|
||||||
data="{some broken json}",
|
content="{some broken json}",
|
||||||
)
|
)
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
|
|
@ -214,7 +214,7 @@ def test_post_form_for_json():
|
||||||
def test_explicit_content_type():
|
def test_explicit_content_type():
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/",
|
"/items/",
|
||||||
data='{"name": "Foo", "price": 50.5}',
|
content='{"name": "Foo", "price": 50.5}',
|
||||||
headers={"Content-Type": "application/json"},
|
headers={"Content-Type": "application/json"},
|
||||||
)
|
)
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
|
|
@ -223,7 +223,7 @@ def test_explicit_content_type():
|
||||||
def test_geo_json():
|
def test_geo_json():
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/",
|
"/items/",
|
||||||
data='{"name": "Foo", "price": 50.5}',
|
content='{"name": "Foo", "price": 50.5}',
|
||||||
headers={"Content-Type": "application/geo+json"},
|
headers={"Content-Type": "application/geo+json"},
|
||||||
)
|
)
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
|
|
@ -232,7 +232,7 @@ def test_geo_json():
|
||||||
def test_no_content_type_is_json():
|
def test_no_content_type_is_json():
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/",
|
"/items/",
|
||||||
data='{"name": "Foo", "price": 50.5}',
|
content='{"name": "Foo", "price": 50.5}',
|
||||||
)
|
)
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
|
|
@ -255,17 +255,19 @@ def test_wrong_headers():
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
response = client.post("/items/", data=data, headers={"Content-Type": "text/plain"})
|
response = client.post(
|
||||||
|
"/items/", content=data, headers={"Content-Type": "text/plain"}
|
||||||
|
)
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
assert response.json() == invalid_dict
|
assert response.json() == invalid_dict
|
||||||
|
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/", data=data, headers={"Content-Type": "application/geo+json-seq"}
|
"/items/", content=data, headers={"Content-Type": "application/geo+json-seq"}
|
||||||
)
|
)
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
assert response.json() == invalid_dict
|
assert response.json() == invalid_dict
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/", data=data, headers={"Content-Type": "application/not-really-json"}
|
"/items/", content=data, headers={"Content-Type": "application/not-really-json"}
|
||||||
)
|
)
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
assert response.json() == invalid_dict
|
assert response.json() == invalid_dict
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ def test_post_broken_body(client: TestClient):
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/",
|
"/items/",
|
||||||
headers={"content-type": "application/json"},
|
headers={"content-type": "application/json"},
|
||||||
data="{some broken json}",
|
content="{some broken json}",
|
||||||
)
|
)
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
|
|
@ -225,7 +225,7 @@ def test_post_form_for_json(client: TestClient):
|
||||||
def test_explicit_content_type(client: TestClient):
|
def test_explicit_content_type(client: TestClient):
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/",
|
"/items/",
|
||||||
data='{"name": "Foo", "price": 50.5}',
|
content='{"name": "Foo", "price": 50.5}',
|
||||||
headers={"Content-Type": "application/json"},
|
headers={"Content-Type": "application/json"},
|
||||||
)
|
)
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
|
|
@ -235,7 +235,7 @@ def test_explicit_content_type(client: TestClient):
|
||||||
def test_geo_json(client: TestClient):
|
def test_geo_json(client: TestClient):
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/",
|
"/items/",
|
||||||
data='{"name": "Foo", "price": 50.5}',
|
content='{"name": "Foo", "price": 50.5}',
|
||||||
headers={"Content-Type": "application/geo+json"},
|
headers={"Content-Type": "application/geo+json"},
|
||||||
)
|
)
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
|
|
@ -245,7 +245,7 @@ def test_geo_json(client: TestClient):
|
||||||
def test_no_content_type_is_json(client: TestClient):
|
def test_no_content_type_is_json(client: TestClient):
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/",
|
"/items/",
|
||||||
data='{"name": "Foo", "price": 50.5}',
|
content='{"name": "Foo", "price": 50.5}',
|
||||||
)
|
)
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
|
|
@ -269,17 +269,19 @@ def test_wrong_headers(client: TestClient):
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
response = client.post("/items/", data=data, headers={"Content-Type": "text/plain"})
|
response = client.post(
|
||||||
|
"/items/", content=data, headers={"Content-Type": "text/plain"}
|
||||||
|
)
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
assert response.json() == invalid_dict
|
assert response.json() == invalid_dict
|
||||||
|
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/", data=data, headers={"Content-Type": "application/geo+json-seq"}
|
"/items/", content=data, headers={"Content-Type": "application/geo+json-seq"}
|
||||||
)
|
)
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
assert response.json() == invalid_dict
|
assert response.json() == invalid_dict
|
||||||
response = client.post(
|
response = client.post(
|
||||||
"/items/", data=data, headers={"Content-Type": "application/not-really-json"}
|
"/items/", content=data, headers={"Content-Type": "application/not-really-json"}
|
||||||
)
|
)
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
assert response.json() == invalid_dict
|
assert response.json() == invalid_dict
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ from fastapi.testclient import TestClient
|
||||||
|
|
||||||
from docs_src.cookie_params.tutorial001 import app
|
from docs_src.cookie_params.tutorial001 import app
|
||||||
|
|
||||||
client = TestClient(app)
|
|
||||||
|
|
||||||
openapi_schema = {
|
openapi_schema = {
|
||||||
"openapi": "3.0.2",
|
"openapi": "3.0.2",
|
||||||
"info": {"title": "FastAPI", "version": "0.1.0"},
|
"info": {"title": "FastAPI", "version": "0.1.0"},
|
||||||
|
|
@ -88,6 +86,7 @@ openapi_schema = {
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test(path, cookies, expected_status, expected_response):
|
def test(path, cookies, expected_status, expected_response):
|
||||||
response = client.get(path, cookies=cookies)
|
client = TestClient(app, cookies=cookies)
|
||||||
|
response = client.get(path)
|
||||||
assert response.status_code == expected_status
|
assert response.status_code == expected_status
|
||||||
assert response.json() == expected_response
|
assert response.json() == expected_response
|
||||||
|
|
|
||||||
|
|
@ -70,14 +70,6 @@ openapi_schema = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="client")
|
|
||||||
def get_client():
|
|
||||||
from docs_src.cookie_params.tutorial001_py310 import app
|
|
||||||
|
|
||||||
client = TestClient(app)
|
|
||||||
return client
|
|
||||||
|
|
||||||
|
|
||||||
@needs_py310
|
@needs_py310
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"path,cookies,expected_status,expected_response",
|
"path,cookies,expected_status,expected_response",
|
||||||
|
|
@ -94,7 +86,10 @@ def get_client():
|
||||||
("/items", {"session": "cookiesession"}, 200, {"ads_id": None}),
|
("/items", {"session": "cookiesession"}, 200, {"ads_id": None}),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test(path, cookies, expected_status, expected_response, client: TestClient):
|
def test(path, cookies, expected_status, expected_response):
|
||||||
response = client.get(path, cookies=cookies)
|
from docs_src.cookie_params.tutorial001_py310 import app
|
||||||
|
|
||||||
|
client = TestClient(app, cookies=cookies)
|
||||||
|
response = client.get(path)
|
||||||
assert response.status_code == expected_status
|
assert response.status_code == expected_status
|
||||||
assert response.json() == expected_response
|
assert response.json() == expected_response
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ def test_gzip_request(compress):
|
||||||
data = gzip.compress(data)
|
data = gzip.compress(data)
|
||||||
headers["Content-Encoding"] = "gzip"
|
headers["Content-Encoding"] = "gzip"
|
||||||
headers["Content-Type"] = "application/json"
|
headers["Content-Type"] = "application/json"
|
||||||
response = client.post("/sum", data=data, headers=headers)
|
response = client.post("/sum", content=data, headers=headers)
|
||||||
assert response.json() == {"sum": n}
|
assert response.json() == {"sum": n}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,6 @@ def test_openapi_schema():
|
||||||
|
|
||||||
|
|
||||||
def test_get():
|
def test_get():
|
||||||
response = client.get("/typer", allow_redirects=False)
|
response = client.get("/typer", follow_redirects=False)
|
||||||
assert response.status_code == 307, response.text
|
assert response.status_code == 307, response.text
|
||||||
assert response.headers["location"] == "https://typer.tiangolo.com"
|
assert response.headers["location"] == "https://typer.tiangolo.com"
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,6 @@ def test_openapi_schema():
|
||||||
|
|
||||||
|
|
||||||
def test_redirect_response_class():
|
def test_redirect_response_class():
|
||||||
response = client.get("/fastapi", allow_redirects=False)
|
response = client.get("/fastapi", follow_redirects=False)
|
||||||
assert response.status_code == 307
|
assert response.status_code == 307
|
||||||
assert response.headers["location"] == "https://fastapi.tiangolo.com"
|
assert response.headers["location"] == "https://fastapi.tiangolo.com"
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,6 @@ def test_openapi_schema():
|
||||||
|
|
||||||
|
|
||||||
def test_redirect_status_code():
|
def test_redirect_status_code():
|
||||||
response = client.get("/pydantic", allow_redirects=False)
|
response = client.get("/pydantic", follow_redirects=False)
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
assert response.headers["location"] == "https://pydantic-docs.helpmanual.io/"
|
assert response.headers["location"] == "https://pydantic-docs.helpmanual.io/"
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ def test_openapi_schema():
|
||||||
|
|
||||||
|
|
||||||
def test_post():
|
def test_post():
|
||||||
response = client.post("/items/", data=b"this is actually not validated")
|
response = client.post("/items/", content=b"this is actually not validated")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
"size": 30,
|
"size": 30,
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ def test_post():
|
||||||
- x-men
|
- x-men
|
||||||
- x-avengers
|
- x-avengers
|
||||||
"""
|
"""
|
||||||
response = client.post("/items/", data=yaml_data)
|
response = client.post("/items/", content=yaml_data)
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
"name": "Deadpoolio",
|
"name": "Deadpoolio",
|
||||||
|
|
@ -74,7 +74,7 @@ def test_post_broken_yaml():
|
||||||
x - x-men
|
x - x-men
|
||||||
x - x-avengers
|
x - x-avengers
|
||||||
"""
|
"""
|
||||||
response = client.post("/items/", data=yaml_data)
|
response = client.post("/items/", content=yaml_data)
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
assert response.json() == {"detail": "Invalid YAML"}
|
assert response.json() == {"detail": "Invalid YAML"}
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ def test_post_invalid():
|
||||||
- x-avengers
|
- x-avengers
|
||||||
- sneaky: object
|
- sneaky: object
|
||||||
"""
|
"""
|
||||||
response = client.post("/items/", data=yaml_data)
|
response = client.post("/items/", content=yaml_data)
|
||||||
assert response.status_code == 422, response.text
|
assert response.status_code == 422, response.text
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
"detail": [
|
"detail": [
|
||||||
|
|
|
||||||
|
|
@ -4,20 +4,18 @@ from fastapi.websockets import WebSocketDisconnect
|
||||||
|
|
||||||
from docs_src.websockets.tutorial002 import app
|
from docs_src.websockets.tutorial002 import app
|
||||||
|
|
||||||
client = TestClient(app)
|
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
|
client = TestClient(app)
|
||||||
response = client.get("/")
|
response = client.get("/")
|
||||||
assert response.status_code == 200, response.text
|
assert response.status_code == 200, response.text
|
||||||
assert b"<!DOCTYPE html>" in response.content
|
assert b"<!DOCTYPE html>" in response.content
|
||||||
|
|
||||||
|
|
||||||
def test_websocket_with_cookie():
|
def test_websocket_with_cookie():
|
||||||
|
client = TestClient(app, cookies={"session": "fakesession"})
|
||||||
with pytest.raises(WebSocketDisconnect):
|
with pytest.raises(WebSocketDisconnect):
|
||||||
with client.websocket_connect(
|
with client.websocket_connect("/items/foo/ws") as websocket:
|
||||||
"/items/foo/ws", cookies={"session": "fakesession"}
|
|
||||||
) as websocket:
|
|
||||||
message = "Message one"
|
message = "Message one"
|
||||||
websocket.send_text(message)
|
websocket.send_text(message)
|
||||||
data = websocket.receive_text()
|
data = websocket.receive_text()
|
||||||
|
|
@ -33,6 +31,7 @@ def test_websocket_with_cookie():
|
||||||
|
|
||||||
|
|
||||||
def test_websocket_with_header():
|
def test_websocket_with_header():
|
||||||
|
client = TestClient(app)
|
||||||
with pytest.raises(WebSocketDisconnect):
|
with pytest.raises(WebSocketDisconnect):
|
||||||
with client.websocket_connect("/items/bar/ws?token=some-token") as websocket:
|
with client.websocket_connect("/items/bar/ws?token=some-token") as websocket:
|
||||||
message = "Message one"
|
message = "Message one"
|
||||||
|
|
@ -50,6 +49,7 @@ def test_websocket_with_header():
|
||||||
|
|
||||||
|
|
||||||
def test_websocket_with_header_and_query():
|
def test_websocket_with_header_and_query():
|
||||||
|
client = TestClient(app)
|
||||||
with pytest.raises(WebSocketDisconnect):
|
with pytest.raises(WebSocketDisconnect):
|
||||||
with client.websocket_connect("/items/2/ws?q=3&token=some-token") as websocket:
|
with client.websocket_connect("/items/2/ws?q=3&token=some-token") as websocket:
|
||||||
message = "Message one"
|
message = "Message one"
|
||||||
|
|
@ -71,6 +71,7 @@ def test_websocket_with_header_and_query():
|
||||||
|
|
||||||
|
|
||||||
def test_websocket_no_credentials():
|
def test_websocket_no_credentials():
|
||||||
|
client = TestClient(app)
|
||||||
with pytest.raises(WebSocketDisconnect):
|
with pytest.raises(WebSocketDisconnect):
|
||||||
with client.websocket_connect("/items/foo/ws"):
|
with client.websocket_connect("/items/foo/ws"):
|
||||||
pytest.fail(
|
pytest.fail(
|
||||||
|
|
@ -79,6 +80,7 @@ def test_websocket_no_credentials():
|
||||||
|
|
||||||
|
|
||||||
def test_websocket_invalid_data():
|
def test_websocket_invalid_data():
|
||||||
|
client = TestClient(app)
|
||||||
with pytest.raises(WebSocketDisconnect):
|
with pytest.raises(WebSocketDisconnect):
|
||||||
with client.websocket_connect("/items/foo/ws?q=bar&token=some-token"):
|
with client.websocket_connect("/items/foo/ws?q=bar&token=some-token"):
|
||||||
pytest.fail(
|
pytest.fail(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue