# -*- coding: utf-8 -*- """ tests.helpers ~~~~~~~~~~~~~~~~~~~~~~~ Various helpers. :copyright: (c) 2015 by Armin Ronacher. :license: BSD, see LICENSE for more details. """ import pytest import os import datetime import flask from logging import StreamHandler from werkzeug.http import parse_cache_control_header, parse_options_header from werkzeug.http import http_date from flask._compat import StringIO, text_type def has_encoding(name): try: import codecs codecs.lookup(name) return True except LookupError: return False class TestJSON(object): def test_jsonify_date_types(self): """Test jsonify with datetime.date and datetime.datetime types.""" test_dates = ( datetime.datetime(1973, 3, 11, 6, 30, 45), datetime.date(1975, 1, 5) ) app = flask.Flask(__name__) c = app.test_client() for i, d in enumerate(test_dates): url = '/datetest{0}'.format(i) app.add_url_rule(url, str(i), lambda val=d: flask.jsonify(x=val)) rv = c.get(url) assert rv.mimetype == 'application/json' assert flask.json.loads(rv.data)['x'] == http_date(d.timetuple()) def test_post_empty_json_adds_exception_to_response_content_in_debug(self): app = flask.Flask(__name__) app.config['DEBUG'] = True @app.route('/json', methods=['POST']) def post_json(): flask.request.get_json() return None c = app.test_client() rv = c.post('/json', data=None, content_type='application/json') assert rv.status_code == 400 assert b'Failed to decode JSON object' in rv.data def test_post_empty_json_wont_add_exception_to_response_if_no_debug(self): app = flask.Flask(__name__) app.config['DEBUG'] = False @app.route('/json', methods=['POST']) def post_json(): flask.request.get_json() return None c = app.test_client() rv = c.post('/json', data=None, content_type='application/json') assert rv.status_code == 400 assert b'Failed to decode JSON object' not in rv.data def test_json_bad_requests(self): app = flask.Flask(__name__) @app.route('/json', methods=['POST']) def return_json(): return flask.jsonify(foo=text_type(flask.request.get_json())) c = app.test_client() rv = c.post('/json', data='malformed', content_type='application/json') assert rv.status_code == 400 def test_json_custom_mimetypes(self): app = flask.Flask(__name__) @app.route('/json', methods=['POST']) def return_json(): return flask.request.get_json() c = app.test_client() rv = c.post('/json', data='"foo"', content_type='application/x+json') assert rv.data == b'foo' def test_json_body_encoding(self): app = flask.Flask(__name__) app.testing = True @app.route('/') def index(): return flask.request.get_json() c = app.test_client() resp = c.get('/', data=u'"Hällo Wörld"'.encode('iso-8859-15'), content_type='application/json; charset=iso-8859-15') assert resp.data == u'Hällo Wörld'.encode('utf-8') def test_jsonify(self): d = dict(a=23, b=42, c=[1, 2, 3]) app = flask.Flask(__name__) @app.route('/kw') def return_kwargs(): return flask.jsonify(**d) @app.route('/dict') def return_dict(): return flask.jsonify(d) c = app.test_client() for url in '/kw', '/dict': rv = c.get(url) assert rv.mimetype == 'application/json' assert flask.json.loads(rv.data) == d def test_json_as_unicode(self): app = flask.Flask(__name__) app.config['JSON_AS_ASCII'] = True with app.app_context(): rv = flask.json.dumps(u'\N{SNOWMAN}') assert rv == '"\\u2603"' app.config['JSON_AS_ASCII'] = False with app.app_context(): rv = flask.json.dumps(u'\N{SNOWMAN}') assert rv == u'"\u2603"' def test_json_attr(self): app = flask.Flask(__name__) @app.route('/add', methods=['POST']) def add(): json = flask.request.get_json() return text_type(json['a'] + json['b']) c = app.test_client() rv = c.post('/add', data=flask.json.dumps({'a': 1, 'b': 2}), content_type='application/json') assert rv.data == b'3' def test_template_escaping(self): app = flask.Flask(__name__) render = flask.render_template_string with app.test_request_context(): rv = flask.json.htmlsafe_dumps('') assert rv == u'"\\u003c/script\\u003e"' assert type(rv) == text_type rv = render('{{ ""|tojson }}') assert rv == '"\\u003c/script\\u003e"' rv = render('{{ "<\0/script>"|tojson }}') assert rv == '"\\u003c\\u0000/script\\u003e"' rv = render('{{ "