diff --git a/fastapi/security/oauth2.py b/fastapi/security/oauth2.py index 7ca7f6bc5..4f4bd3001 100644 --- a/fastapi/security/oauth2.py +++ b/fastapi/security/oauth2.py @@ -705,7 +705,7 @@ class OAuth2ClientCredentials(OAuth2): headers={"WWW-Authenticate": "Bearer"}, ) else: - return None # pragma: nocover + return None return param diff --git a/tests/test_security_oauth2_client_credentials_optional.py b/tests/test_security_oauth2_client_credentials_optional.py new file mode 100644 index 000000000..f281a61a3 --- /dev/null +++ b/tests/test_security_oauth2_client_credentials_optional.py @@ -0,0 +1,72 @@ +from typing import Optional + +from fastapi import FastAPI, Security +from fastapi.security import OAuth2ClientCredentials +from fastapi.testclient import TestClient + +app = FastAPI() + +oauth2_scheme = OAuth2ClientCredentials(tokenUrl="token", auto_error=False) + + +@app.get("/items/") +async def read_items(token: Optional[str] = Security(oauth2_scheme)): + return {"token": token} + + +client = TestClient(app) + + +def test_no_token(): + response = client.get("/items") + assert response.status_code == 200, response.text + assert response.json() == {"token": None} + + +def test_incorrect_token(): + response = client.get("/items", headers={"Authorization": "Non-existent testtoken"}) + assert response.status_code == 200, response.text + assert response.json() == {"token": None} + + +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.1.0", + "info": {"title": "FastAPI", "version": "0.1.0"}, + "paths": { + "/items/": { + "get": { + "responses": { + "200": { + "description": "Successful Response", + "content": {"application/json": {"schema": {}}}, + } + }, + "summary": "Read Items", + "operationId": "read_items_items__get", + "security": [{"OAuth2ClientCredentials": []}], + } + } + }, + "components": { + "securitySchemes": { + "OAuth2ClientCredentials": { + "type": "oauth2", + "flows": { + "clientCredentials": { + "tokenUrl": "token", + "scopes": {}, + } + }, + } + } + }, + }