Skip to content

Commit

Permalink
Allow "Required: False" on Response headers - Fix #1261 (#1293)
Browse files Browse the repository at this point in the history
* Add failing test for optional header

* Required: False headers don't give error if missing

* Use dict.get

* Required keys are when they are not present, or present with "True"

* Update connexion/decorators/response.py

Co-authored-by: Ruwann <ruwan.lambrichts@ml6.eu>

* Update tests for required and optional headers

Swagger2 response headers are optional, and have no 'required'
attribute. OpenAPI3 response headers are optional by default,
but can be specified to be required by setting 'required: true'.

* Make headers required for tests that rely on it

Co-authored-by: Ruwann <ruwan.lambrichts@ml6.eu>
  • Loading branch information
miguelgf and Ruwann committed Jul 16, 2021
1 parent 3195bec commit 005d046
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 20 deletions.
7 changes: 4 additions & 3 deletions connexion/decorators/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ def validate_response(self, data, status_code, headers, url):
raise NonConformingResponseBody(message=str(e))

if response_definition and response_definition.get("headers"):
response_definition_header_keys = response_definition.get("headers").keys()
header_keys = headers.keys()
missing_keys = response_definition_header_keys - header_keys
required_header_keys = {k for (k, v) in response_definition.get("headers").items()
if v.get("required", False)}
header_keys = set(headers.keys())
missing_keys = required_header_keys - header_keys
if missing_keys:
pretty_list = ', '.join(missing_keys)
msg = ("Keys in header don't match response specification. "
Expand Down
11 changes: 9 additions & 2 deletions tests/api/test_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def test_headers_produces(simple_app):
assert response.headers["Location"] == "http://localhost/my/uri"


def test_header_not_returned(simple_app):
app_client = simple_app.app.test_client()
def test_header_not_returned(simple_openapi_app):
app_client = simple_openapi_app.app.test_client()

response = app_client.post('/v1.0/goodday/noheader', data={}) # type: flask.Response
assert response.status_code == 500 # view_func has not returned what was promised in spec
Expand All @@ -42,3 +42,10 @@ def test_no_content_object_and_have_headers(simple_app):
resp = app_client.get('/v1.0/test-204-with-headers-nocontent-obj')
assert resp.status_code == 204
assert 'X-Something' in resp.headers


def test_optional_header(simple_openapi_app):
app_client = simple_openapi_app.app.test_client()
resp = app_client.get('/v1.0/test-optional-headers')
assert resp.status_code == 200
assert 'X-Optional-Header' not in resp.headers
4 changes: 4 additions & 0 deletions tests/fakeapi/hello/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,3 +601,7 @@ def get_date():

def get_uuid():
return {'value': uuid.UUID(hex='e7ff66d0-3ec2-4c4e-bed0-6e4723c24c51')}


def test_optional_headers():
return {}, 200
19 changes: 19 additions & 0 deletions tests/fixtures/simple/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,7 @@ paths:
description: The URI of the created resource
schema:
type: string
required: true
content:
'application/json':
schema:
Expand All @@ -714,6 +715,7 @@ paths:
description: The URI of the created resource
schema:
type: string
required: true
content:
'application/json':
schema:
Expand All @@ -731,6 +733,7 @@ paths:
description: The URI of the created resource
schema:
type: string
required: true
content:
text/plain:
schema:
Expand Down Expand Up @@ -1140,6 +1143,22 @@ paths:
application/json:
schema:
type: object
/test-optional-headers:
get:
operationId: fakeapi.hello.test_optional_headers
responses:
'200':
description: Some object response
content:
application/json:
schema:
type: object
headers:
X-Optional-Header:
description: Optional header
schema:
type: string
required: false

servers:
- url: http://localhost:{port}/{basePath}
Expand Down
15 changes: 0 additions & 15 deletions tests/fixtures/simple/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -556,21 +556,6 @@ paths:
required: true
type: string

/goodday/noheader:
post:
summary: Generate good day greeting
description: Generates a good day message.
operationId: fakeapi.hello.post_goodday_no_header
responses:
201:
description: gooday response
headers:
Location:
type: string
description: The URI of the created resource
schema:
type: object

/goodevening/{name}:
post:
summary: Generate good evening
Expand Down

0 comments on commit 005d046

Please sign in to comment.