Skip to content

Commit

Permalink
properly handle content_type callables returning a single internet me…
Browse files Browse the repository at this point in the history
…dia type as scalar, improves and resolves Cornices#343
  • Loading branch information
amotl committed Mar 3, 2016
1 parent 3975c49 commit 3a74866
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CHANGELOG
==================

- Nothing changed yet.
- Properly handle content_type callables returning a single internet media type as scalar (#343)


1.2.0 (2016-01-18)
Expand Down
19 changes: 18 additions & 1 deletion cornice/tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ def test_accept(self):
response = app.get('/service3', headers={'Accept': 'text/*'})
self.assertEqual(response.content_type, "text/json")

# test that using a callable to define what's accepted works as well
# now, the callable returns a scalar instead of a list
response = app.put('/service3', headers={'Accept': 'audio/*'},
status=406)
error_description = response.json['errors'][0]['description']
self.assertIn('text/json', error_description)

response = app.put('/service3', headers={'Accept': 'text/*'})
self.assertEqual(response.content_type, "text/json")

# if we are not asking for a particular content-type,
# we should get one of the two types that the service supports.
response = app.get('/service2')
Expand Down Expand Up @@ -243,7 +253,14 @@ def test_content_type_with_callable(self):
self.assertTrue('text/xml' in error_description)
self.assertTrue('application/json' in error_description)

app.post('/service6', headers={'Content-Type': 'text/xml'})
def test_content_type_with_callable_returning_scalar(self):
# test that using a callable for content_type works as well
# now, the callable returns a scalar instead of a list
app = TestApp(main({}))
response = app.put('/service6', headers={'Content-Type': 'audio/*'},
status=415)
error_description = response.json['errors'][0]['description']
self.assertIn('text/xml', error_description)

def test_accept_and_content_type(self):
# tests that giving both Accept and Content-Type
Expand Down
17 changes: 6 additions & 11 deletions cornice/tests/validationapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,8 @@ def get2(request):
service3 = Service(name="service3", path="/service3")


def _accept(request):
return ('application/json', 'text/json')


@service3.get(accept=_accept)
@service3.get(accept=lambda request: ('application/json', 'text/json'))
@service3.put(accept=lambda request: 'text/json')
def get3(request):
return {"body": "yay!"}

Expand Down Expand Up @@ -117,15 +114,13 @@ def get4(request):
def post5(request):
return "some response"

# test the "content_type" parameter (callable)
service6 = Service(name="service6", path="/service6")


def _content_type(request):
return ('text/xml', 'application/json')
# service for testing the "content_type" parameter (callable)
service6 = Service(name="service6", path="/service6")


@service6.post(content_type=_content_type)
@service6.post(content_type=lambda request: ('text/xml', 'application/json'))
@service6.put(content_type=lambda request: 'text/xml')
def post6(request):
return {"body": "yay!"}

Expand Down
4 changes: 2 additions & 2 deletions cornice/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,15 @@ def match_accept_header(func, context, request):
The callable returning the list of acceptable content-types,
given a request. It should accept a "request" argument.
"""
acceptable = func(request)
# attach the accepted egress content types to the request
acceptable = to_list(func(request))
request.info['acceptable'] = acceptable
return request.accept.best_match(acceptable) is not None


def match_content_type_header(func, context, request):
supported_contenttypes = func(request)
# attach the accepted ingress content types to the request
supported_contenttypes = to_list(func(request))
request.info['supported_contenttypes'] = supported_contenttypes
return content_type_matches(request, supported_contenttypes)

Expand Down

0 comments on commit 3a74866

Please sign in to comment.