Browse Source

JSON response tests and first draft of code that passes

reviewable/pr1984/r1
Adam Byrtek 10 years ago committed by Markus Unterwaditzer
parent
commit
ca547f0ec3
  1. 81
      flask/wrappers.py
  2. 19
      tests/test_testing.py

81
flask/wrappers.py

@ -25,6 +25,14 @@ def _get_data(req, cache):
return req.data
def _is_mimetype_json(mimetype):
if mimetype == 'application/json':
return True
if mimetype.startswith('application/') and mimetype.endswith('+json'):
return True
return False
class Request(RequestBase):
"""The request object used by default in Flask. Remembers the
matched endpoint and view arguments.
@ -115,12 +123,7 @@ class Request(RequestBase):
.. versionadded:: 0.11
"""
mt = self.mimetype
if mt == 'application/json':
return True
if mt.startswith('application/') and mt.endswith('+json'):
return True
return False
return _is_mimetype_json(self.mimetype)
def get_json(self, force=False, silent=False, cache=True):
"""Parses the incoming JSON request data and returns it. By default
@ -202,3 +205,69 @@ class Response(ResponseBase):
set :attr:`~flask.Flask.response_class` to your subclass.
"""
default_mimetype = 'text/html'
@property
def json(self):
"""If the mimetype is :mimetype:`application/json` this will contain the
parsed JSON data. Otherwise this will be ``None``.
The :meth:`get_json` method should be used instead.
.. versionadded:: 1.0
"""
from warnings import warn
warn(DeprecationWarning('json is deprecated. '
'Use get_json() instead.'), stacklevel=2)
return self.get_json()
@property
def is_json(self):
"""Indicates if this response is JSON or not. By default a response
is considered to include JSON data if the mimetype is
:mimetype:`application/json` or :mimetype:`application/*+json`.
.. versionadded:: 1.0
"""
return _is_mimetype_json(self.mimetype)
def get_json(self, force=False, silent=False, cache=True):
"""Parses the incoming JSON request data and returns it. If
parsing fails the :meth:`on_json_loading_failed` method on the
request object will be invoked. By default this function will
only load the json data if the mimetype is :mimetype:`application/json`
but this can be overridden by the `force` parameter.
:param force: if set to ``True`` the mimetype is ignored.
:param silent: if set to ``True`` this method will fail silently
and return ``None``.
:param cache: if set to ``True`` the parsed JSON data is remembered
on the request.
.. versionadded:: 1.0
"""
rv = getattr(self, '_cached_json', _missing)
if rv is not _missing:
return rv
if not (force or self.is_json):
return None
# We accept a request charset against the specification as
# certain clients have been using this in the past. This
# fits our general approach of being nice in what we accept
# and strict in what we send out.
request_charset = self.mimetype_params.get('charset')
try:
data = _get_data(self, cache)
if request_charset is not None:
rv = json.loads(data, encoding=request_charset)
else:
rv = json.loads(data)
except ValueError as e:
if silent:
rv = None
else:
rv = self.on_json_loading_failed(e)
if cache:
self._cached_json = rv
return rv

19
tests/test_testing.py

@ -13,6 +13,7 @@ import pytest
import flask
from flask._compat import text_type
from flask.json import jsonify
def test_environ_defaults_from_config():
@ -203,21 +204,27 @@ def test_full_url_request():
assert 'gin' in flask.request.form
assert 'vodka' in flask.request.args
def test_json_request():
def test_json_request_and_response():
app = flask.Flask(__name__)
app.testing = True
@app.route('/api', methods=['POST'])
def api():
return ''
@app.route('/echo', methods=['POST'])
def echo():
return jsonify(flask.request.json)
with app.test_client() as c:
json_data = {'drink': {'gin': 1, 'tonic': True}, 'price': 10}
rv = c.post('/api', json=json_data)
assert rv.status_code == 200
rv = c.post('/echo', json=json_data)
# Request should be in JSON
assert flask.request.is_json
assert flask.request.get_json() == json_data
# Response should be in JSON
assert rv.status_code == 200
assert rv.is_json
assert rv.get_json() == json_data
def test_subdomain():
app = flask.Flask(__name__)
app.config['SERVER_NAME'] = 'example.com'

Loading…
Cancel
Save