embed jsonresponse into the package (#10283)
This commit is contained in:
parent
6791aaeb22
commit
9ba00c7024
9
README
9
README
|
@ -89,3 +89,12 @@ icon-concerto.svg license:
|
|||
Creative Commons – Attribution (CC BY 3.0) http://creativecommons.org/licenses/by/3.0/us/
|
||||
"Family" designed by Ahmed Elzahra http://www.thenounproject.com/trochilidae/
|
||||
from the Noun Project http://www.thenounproject.com/
|
||||
|
||||
|
||||
Copyright
|
||||
---------
|
||||
|
||||
django-jsonresponse (https://github.com/jjay/django-jsonresponse)
|
||||
# Files: passerelle/utils/jsonresponse.py
|
||||
# Copyright (c) 2012 Yasha Borevich <j.borevich@gmail.com>
|
||||
# Licensed under the BSD license
|
||||
|
|
|
@ -16,7 +16,6 @@ Depends: ${python:Depends},
|
|||
${misc:Depends},
|
||||
python-django (>= 1.7),
|
||||
python-gadjo,
|
||||
python-django-jsonresponse,
|
||||
python-django-model-utils,
|
||||
python-requests,
|
||||
python-setuptools,
|
||||
|
|
|
@ -6,8 +6,6 @@ from django.views.generic.base import View
|
|||
from django.views.generic.detail import SingleObjectMixin, DetailView
|
||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
||||
|
||||
from jsonresponse import to_json
|
||||
|
||||
from passerelle import utils
|
||||
|
||||
from .models import Bdp
|
||||
|
@ -21,7 +19,7 @@ class ResourcesView(View, SingleObjectMixin):
|
|||
model = Bdp
|
||||
|
||||
@utils.protected_api('can_access')
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
def get(self, request, *args, **kwargs):
|
||||
text_key = request.GET.get('text_key')
|
||||
id_key = request.GET.get('id_key')
|
||||
|
@ -44,7 +42,7 @@ class PostAdherentView(View, SingleObjectMixin):
|
|||
raise Http404
|
||||
|
||||
@utils.protected_api('can_access')
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
def post(self, request, *args, **kwargs):
|
||||
data = json.loads(request.body) # JSON w.c.s. formdata
|
||||
date_de_naissance = data['fields'].get('date_de_naissance')
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
import json
|
||||
|
||||
from jsonresponse import to_json
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView, View
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
from django.utils.decorators import method_decorator
|
||||
|
@ -79,14 +76,14 @@ class ChoositRegisterView(View, SingleObjectMixin):
|
|||
def dispatch(self, request, *args, **kwargs):
|
||||
return super(ChoositRegisterView, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
@method_decorator(csrf_exempt)
|
||||
def get(self, request, *args, **kwargs):
|
||||
user = request.GET.get('user')
|
||||
assert user, 'missing user parameter'
|
||||
return self.get_object().get_list(user)
|
||||
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
def post(self, request, *args, **kwargs):
|
||||
user = request.GET.get('user')
|
||||
assert user, 'missing user parameter'
|
||||
|
|
|
@ -7,8 +7,6 @@ from django.views.generic.base import View, RedirectView
|
|||
from django.views.generic.detail import SingleObjectMixin, DetailView
|
||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
||||
|
||||
from jsonresponse import to_json
|
||||
|
||||
from passerelle import utils
|
||||
from passerelle.base.views import ResourceView
|
||||
|
||||
|
@ -51,7 +49,7 @@ class InterventionSetsView(View, SingleObjectMixin):
|
|||
|
||||
model = ClicRdv
|
||||
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
def get(self, request, *args, **kwargs):
|
||||
return self.get_object().get_interventionsets()
|
||||
|
||||
|
@ -66,7 +64,7 @@ class InterventionsView(View, SingleObjectMixin):
|
|||
"""
|
||||
model = ClicRdv
|
||||
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
def get(self, request, set_id, *args, **kwargs):
|
||||
return self.get_object().get_interventions(set_id)
|
||||
|
||||
|
@ -78,7 +76,7 @@ class DateTimesView(View, SingleObjectMixin):
|
|||
"""
|
||||
model = ClicRdv
|
||||
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
def get(self, request, intervention_id, *args, **kwargs):
|
||||
return self.get_object().get_datetimes(intervention_id)
|
||||
|
||||
|
@ -93,7 +91,7 @@ class DatesView(View, SingleObjectMixin):
|
|||
"""
|
||||
model = ClicRdv
|
||||
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
def get(self, request, intervention_id, *args, **kwargs):
|
||||
return self.get_object().get_dates(intervention_id)
|
||||
|
||||
|
@ -108,7 +106,7 @@ class TimesView(View, SingleObjectMixin):
|
|||
"""
|
||||
model = ClicRdv
|
||||
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
def get(self, request, intervention_id, date, *args, **kwargs):
|
||||
return self.get_object().get_times(intervention_id, date)
|
||||
|
||||
|
@ -140,7 +138,7 @@ class CreateAppointmentView(View, SingleObjectMixin):
|
|||
model = ClicRdv
|
||||
|
||||
@utils.protected_api('can_manage_appointment')
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
def post(self, request, intervention_id=None, *args, **kwargs):
|
||||
if intervention_id is None:
|
||||
intervention_id = self.request.GET.get('intervention')
|
||||
|
@ -161,6 +159,6 @@ class CancelAppointmentView(View, SingleObjectMixin):
|
|||
model = ClicRdv
|
||||
|
||||
@utils.protected_api('can_manage_appointment')
|
||||
@to_json('api')
|
||||
@utils.to_json('api')
|
||||
def get(self, request, appointment_id, *args, **kwargs):
|
||||
return self.get_object().cancel(appointment_id)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import json
|
||||
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from jsonresponse import to_json
|
||||
|
||||
from models import BaseDataSource
|
||||
from passerelle.utils import to_json
|
||||
|
||||
|
||||
def get_data(request, slug, id=None):
|
||||
|
|
|
@ -13,50 +13,13 @@ from django.http import HttpRequest, HttpResponse, HttpResponseBadRequest
|
|||
from django.template import Template, Context
|
||||
from django.utils.decorators import available_attrs
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from .base.context_processors import template_vars
|
||||
from .base.models import ApiUser, AccessRight
|
||||
from .base.signature import check_query
|
||||
|
||||
class to_json(jsonresponse_to_json):
|
||||
def __init__(self, serializer_type, error_code=500, **kwargs):
|
||||
super(to_json, self).__init__(serializer_type, error_code, **kwargs)
|
||||
if 'cls' not in self.kwargs:
|
||||
self.kwargs['cls'] = DjangoJSONEncoder
|
||||
|
||||
def api(self, func, req, *args, **kwargs):
|
||||
"""
|
||||
Raises the exceptions provided by "raises" argument, else wraps the
|
||||
error message in json. Exceptions can define the error code returned in
|
||||
JSON, and HTTP status:
|
||||
|
||||
class BlockedAccount(Exception):
|
||||
err_code = 100
|
||||
http_status = 403
|
||||
"""
|
||||
if req.GET.get('raise'):
|
||||
return super(to_json, self).api(func, req, *args, **kwargs)
|
||||
# force raise=1 to handle exceptions here
|
||||
req.GET = req.GET.copy()
|
||||
req.GET.update({'raise': 1})
|
||||
try:
|
||||
return super(to_json, self).api(func, req, *args, **kwargs)
|
||||
except Exception as e:
|
||||
data = self.err_to_response(e)
|
||||
if getattr(e, 'err_code', None):
|
||||
data['err'] = e.err_code
|
||||
if getattr(e, 'http_status', None):
|
||||
status = e.http_status
|
||||
elif isinstance(e, ObjectDoesNotExist):
|
||||
status = 404
|
||||
elif isinstance(e, PermissionDenied):
|
||||
status = 403
|
||||
else:
|
||||
status = self.error_code
|
||||
return self.render_data(req, data, status)
|
||||
from passerelle.base.context_processors import template_vars
|
||||
from passerelle.base.models import ApiUser, AccessRight
|
||||
from passerelle.base.signature import check_query
|
||||
|
||||
from .jsonresponse import to_json
|
||||
|
||||
def get_template_vars():
|
||||
"""
|
||||
|
@ -179,5 +142,3 @@ class LoggedRequest(RequestSession):
|
|||
extra={'requests_response_content': content})
|
||||
|
||||
return response
|
||||
|
||||
|
|
@ -0,0 +1,384 @@
|
|||
# This module is a modified copy of code of Yasha's Borevich library
|
||||
# django-jsonresponse (https://github.com/jjay/django-jsonresponse) distributed
|
||||
# under BSD license
|
||||
|
||||
import json
|
||||
import functools
|
||||
import logging
|
||||
from collections import Iterable
|
||||
|
||||
from django.http import HttpResponse
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
|
||||
DEFAULT_DEBUG = getattr(settings, 'JSONRESPONSE_DEFAULT_DEBUG', False)
|
||||
CALLBACK_NAME = getattr(settings, 'JSONRESPONSE_CALLBACK_NAME', 'callback')
|
||||
|
||||
|
||||
class to_json(object):
|
||||
"""
|
||||
Wrap view functions to render python native and custom
|
||||
objects to json
|
||||
|
||||
>>> from django.test.client import RequestFactory
|
||||
>>> requests = RequestFactory()
|
||||
|
||||
Simple wrap returning data into json
|
||||
|
||||
>>> @to_json('plain')
|
||||
... def hello(request):
|
||||
... return dict(hello='world')
|
||||
|
||||
>>> resp = hello(requests.get('/hello/'))
|
||||
>>> print resp.status_code
|
||||
200
|
||||
>>> print resp.content
|
||||
{"hello": "world"}
|
||||
|
||||
Result can be wraped in some api manier
|
||||
|
||||
>>> @to_json('api')
|
||||
... def goodbye(request):
|
||||
... return dict(good='bye')
|
||||
>>> resp = goodbye(requests.get('/goodbye', {'debug': 1}))
|
||||
>>> print resp.status_code
|
||||
200
|
||||
>>> print resp.content
|
||||
{
|
||||
"data": {
|
||||
"good": "bye"
|
||||
},
|
||||
"err": 0
|
||||
}
|
||||
|
||||
Automaticaly error handling
|
||||
|
||||
>>> @to_json('api')
|
||||
... def error(request):
|
||||
... raise Exception('Wooot!??')
|
||||
|
||||
>>> resp = error(requests.get('/error', {'debug': 1}))
|
||||
>>> print resp.status_code
|
||||
500
|
||||
>>> print resp.content # doctest: +NORMALIZE_WHITESPACE
|
||||
{
|
||||
"err_class": "Exception",
|
||||
"err_desc": "Wooot!??",
|
||||
"data": null,
|
||||
"err": 1
|
||||
}
|
||||
|
||||
>>> from django.core.exceptions import ObjectDoesNotExist
|
||||
>>> @to_json('api')
|
||||
... def error_404(request):
|
||||
... raise ObjectDoesNotExist('Not found')
|
||||
|
||||
>>> resp = error_404(requests.get('/error', {'debug': 1}))
|
||||
>>> print resp.status_code
|
||||
404
|
||||
>>> print resp.content # doctest: +NORMALIZE_WHITESPACE
|
||||
{
|
||||
"err_class": "django.core.exceptions.ObjectDoesNotExist",
|
||||
"err_desc": "Not found",
|
||||
"data": null,
|
||||
"err": 1
|
||||
}
|
||||
|
||||
|
||||
You can serialize not only pure python data types.
|
||||
Implement `serialize` method on toplevel object or
|
||||
each element of toplevel array.
|
||||
|
||||
>>> class User(object):
|
||||
... def __init__(self, name, age):
|
||||
... self.name = name
|
||||
... self.age = age
|
||||
...
|
||||
... def serialize(self, request):
|
||||
... if request.GET.get('with_age', False):
|
||||
... return dict(name=self.name, age=self.age)
|
||||
... else:
|
||||
... return dict(name=self.name)
|
||||
|
||||
>>> @to_json('objects')
|
||||
... def users(request):
|
||||
... return [User('Bob', 10), User('Anna', 12)]
|
||||
|
||||
>>> resp = users(requests.get('users', { 'debug': 1 }))
|
||||
>>> print resp.status_code
|
||||
200
|
||||
>>> print resp.content # doctest: +NORMALIZE_WHITESPACE
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"name": "Bob"
|
||||
},
|
||||
{
|
||||
"name": "Anna"
|
||||
}
|
||||
],
|
||||
"err": 0
|
||||
}
|
||||
|
||||
You can pass extra args for serialization:
|
||||
|
||||
>>> resp = users(requests.get('users',
|
||||
... { 'debug':1, 'with_age':1 }))
|
||||
>>> print resp.status_code
|
||||
200
|
||||
>>> print resp.content # doctest: +NORMALIZE_WHITESPACE
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"age": 10,
|
||||
"name": "Bob"
|
||||
},
|
||||
{
|
||||
"age": 12,
|
||||
"name": "Anna"
|
||||
}
|
||||
],
|
||||
"err": 0
|
||||
}
|
||||
|
||||
It is easy to use jsonp, just pass format=jsonp
|
||||
|
||||
>>> resp = users(requests.get('users',
|
||||
... { 'debug':1, 'format': 'jsonp' }))
|
||||
>>> print resp.status_code
|
||||
200
|
||||
>>> print resp.content # doctest: +NORMALIZE_WHITESPACE
|
||||
callback({
|
||||
"data": [
|
||||
{
|
||||
"name": "Bob"
|
||||
},
|
||||
{
|
||||
"name": "Anna"
|
||||
}
|
||||
],
|
||||
"err": 0
|
||||
});
|
||||
|
||||
You can override the name of callback method using
|
||||
JSONRESPONSE_CALLBACK_NAME option or query arg callback=another_callback
|
||||
|
||||
>>> resp = users(requests.get('users',
|
||||
... { 'debug':1, 'format': 'jsonp', 'callback': 'my_callback' }))
|
||||
>>> print resp.status_code
|
||||
200
|
||||
>>> print resp.content # doctest: +NORMALIZE_WHITESPACE
|
||||
my_callback({
|
||||
"data": [
|
||||
{
|
||||
"name": "Bob"
|
||||
},
|
||||
{
|
||||
"name": "Anna"
|
||||
}
|
||||
],
|
||||
"err": 0
|
||||
});
|
||||
|
||||
You can pass raise=1 to raise exceptions in debug purposes
|
||||
instead of passing info to json response
|
||||
|
||||
>>> @to_json('api')
|
||||
... def error(request):
|
||||
... raise Exception('Wooot!??')
|
||||
|
||||
>>> resp = error(requests.get('/error',
|
||||
... {'debug': 1, 'raise': 1}))
|
||||
Traceback (most recent call last):
|
||||
Exception: Wooot!??
|
||||
|
||||
You can wraps both methods and functions
|
||||
|
||||
>>> class View(object):
|
||||
... @to_json('plain')
|
||||
... def render(self, request):
|
||||
... return dict(data='ok')
|
||||
... @to_json('api')
|
||||
... def render_api(self, request):
|
||||
... return dict(data='ok')
|
||||
|
||||
|
||||
>>> view = View()
|
||||
>>> resp = view.render(requests.get('/render'))
|
||||
>>> print resp.status_code
|
||||
200
|
||||
>>> print resp.content # doctest: +NORMALIZE_WHITESPACE
|
||||
{"data": "ok"}
|
||||
|
||||
Try it one more
|
||||
|
||||
>>> resp = view.render(requests.get('/render'))
|
||||
>>> print resp.status_code
|
||||
200
|
||||
>>> print resp.content # doctest: +NORMALIZE_WHITESPACE
|
||||
{"data": "ok"}
|
||||
|
||||
Try it one more with api
|
||||
|
||||
>>> resp = view.render_api(requests.get('/render'))
|
||||
>>> print resp.status_code
|
||||
200
|
||||
>>> print resp.content # doctest: +NORMALIZE_WHITESPACE
|
||||
{"data": {"data": "ok"}, "err": 0}
|
||||
|
||||
|
||||
You can pass custom kwargs to json.dumps,
|
||||
just give them to constructor
|
||||
|
||||
>>> @to_json('plain', separators=(', ', ': '))
|
||||
... def custom_kwargs(request):
|
||||
... return ['a', { 'b': 1 }]
|
||||
>>> resp = custom_kwargs(requests.get('/render'))
|
||||
>>> print resp.status_code
|
||||
200
|
||||
>>> print resp.content
|
||||
["a", {"b": 1}]
|
||||
"""
|
||||
def __init__(self, serializer_type, error_code=500, **kwargs):
|
||||
"""
|
||||
serializer_types:
|
||||
* api - serialize buildin objects (dict, list, etc) in strict api
|
||||
* objects - serialize list of region in strict api
|
||||
* plain - just serialize result of function, do not wrap response and do not handle exceptions
|
||||
"""
|
||||
self.serializer_type = serializer_type
|
||||
self.method = None
|
||||
self.error_code=error_code
|
||||
self.kwargs = kwargs
|
||||
if 'cls' not in self.kwargs:
|
||||
self.kwargs['cls'] = DjangoJSONEncoder
|
||||
|
||||
def __call__(self, f):
|
||||
@functools.wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
if self.method:
|
||||
return self.method(f, *args, **kwargs)
|
||||
|
||||
if not args:
|
||||
if self.serializer_type == 'plain':
|
||||
self.method = self.plain_func
|
||||
else:
|
||||
self.method = self.api_func
|
||||
|
||||
if getattr(getattr(args[0], f.__name__, None), "im_self", False):
|
||||
if self.serializer_type == 'plain':
|
||||
self.method = self.plain_method
|
||||
else:
|
||||
self.method = self.api_method
|
||||
else:
|
||||
if self.serializer_type == 'plain':
|
||||
self.method = self.plain_func
|
||||
else:
|
||||
self.method = self.api_func
|
||||
|
||||
return self.method(f, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
def obj_to_response(self, req, obj):
|
||||
if self.serializer_type == 'objects':
|
||||
if isinstance(obj, Iterable):
|
||||
obj = [o.serialize(req) if obj else None for o in obj]
|
||||
elif obj:
|
||||
obj = obj.serialize(req)
|
||||
else:
|
||||
obj = None
|
||||
|
||||
return { "err": 0, "data": obj }
|
||||
|
||||
def err_to_response(self, err):
|
||||
if hasattr(err, "__module__"):
|
||||
err_module = err.__module__ + "."
|
||||
else:
|
||||
err_module = ""
|
||||
|
||||
if hasattr(err, "owner"):
|
||||
err_module += err.owner.__name__ + "."
|
||||
|
||||
err_class = err_module + err.__class__.__name__
|
||||
|
||||
err_desc = str(err)
|
||||
|
||||
return {
|
||||
"err": 1,
|
||||
"err_class": err_class,
|
||||
"err_desc": err_desc,
|
||||
"data": None
|
||||
}
|
||||
|
||||
def render_data(self, req, data, status=200):
|
||||
debug = DEFAULT_DEBUG
|
||||
debug = debug or req.GET.get('debug', 'false').lower() in ('true', 't', '1', 'on')
|
||||
debug = debug or req.GET.get('decode', '0').lower() in ('true', 't', '1', 'on')
|
||||
format = req.GET.get('format', 'json')
|
||||
jsonp_cb = req.GET.get('callback', CALLBACK_NAME)
|
||||
content_type = "application/json"
|
||||
|
||||
kwargs = dict(self.kwargs)
|
||||
if debug:
|
||||
kwargs["indent"] = 4
|
||||
kwargs["ensure_ascii"] = False
|
||||
kwargs["encoding"] = "utf8"
|
||||
|
||||
plain = json.dumps(data, **kwargs)
|
||||
if format == 'jsonp':
|
||||
plain = "%s(%s);" % (jsonp_cb, plain)
|
||||
content_type = "application/javascript"
|
||||
|
||||
return HttpResponse(plain, content_type="%s; charset=UTF-8" % content_type, status=status)
|
||||
|
||||
def api_func(self, f, *args, **kwargs):
|
||||
return self.api(f, args[0], *args, **kwargs)
|
||||
|
||||
def api_method(self, f, *args, **kwargs):
|
||||
return self.api(f, args[1], *args, **kwargs)
|
||||
|
||||
def api(self, f, req, *args, **kwargs):
|
||||
logger = logging.getLogger('passerelle.jsonresponse')
|
||||
try:
|
||||
resp = f(*args, **kwargs)
|
||||
if isinstance(resp, HttpResponse):
|
||||
return resp
|
||||
|
||||
data = self.obj_to_response(req, resp)
|
||||
status = 200
|
||||
except Exception as e:
|
||||
extras = {'method': req.method}
|
||||
if req.method == 'POST':
|
||||
extras.update({'body': req.body})
|
||||
logger.exception("Error occurred while processing request", extra=extras)
|
||||
if int(req.GET.get('raise', 0)):
|
||||
raise
|
||||
|
||||
data = self.err_to_response(e)
|
||||
if getattr(e, 'err_code', None):
|
||||
data['err'] = e.err_code
|
||||
if getattr(e, 'http_status', None):
|
||||
status = e.http_status
|
||||
elif isinstance(e, ObjectDoesNotExist):
|
||||
status = 404
|
||||
elif isinstance(e, PermissionDenied):
|
||||
status = 403
|
||||
else:
|
||||
status = self.error_code
|
||||
return self.render_data(req, data, status)
|
||||
|
||||
def plain_method(self, f, *args, **kwargs):
|
||||
data = f(*args, **kwargs)
|
||||
if isinstance(data, HttpResponse):
|
||||
return data
|
||||
|
||||
return self.render_data(args[1], data)
|
||||
|
||||
def plain_func(self, f, *args, **kwargs):
|
||||
data = f(*args, **kwargs)
|
||||
if isinstance(data, HttpResponse):
|
||||
return data
|
||||
|
||||
return self.render_data(args[0], data)
|
1
setup.py
1
setup.py
|
@ -87,7 +87,6 @@ setup(name='passerelle',
|
|||
install_requires=[
|
||||
'django >= 1.7, <1.8',
|
||||
'django-model-utils',
|
||||
'django-jsonresponse==0.10',
|
||||
'django-jsonfield >= 0.9.3',
|
||||
'requests',
|
||||
'gadjo',
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import logging
|
||||
import pytest
|
||||
import json
|
||||
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
|
||||
from passerelle.utils import to_json
|
||||
|
||||
class WrappedException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@to_json('api')
|
||||
def wrapped_exception(req, *args, **kwargs):
|
||||
raise WrappedException
|
||||
|
||||
|
||||
def test_jsonresponselog_get(caplog):
|
||||
request = RequestFactory()
|
||||
wrapped_exception(request.get('/'))
|
||||
post_payload = {'data': 'plop'}
|
||||
with pytest.raises(WrappedException):
|
||||
wrapped_exception(request.post('/?raise=1', post_payload))
|
||||
|
||||
for record in caplog.records():
|
||||
assert record.name == 'passerelle.jsonresponse'
|
||||
assert record.levelno == logging.ERROR
|
||||
assert hasattr(record, 'method')
|
||||
if record.method == 'POST':
|
||||
assert hasattr(record, 'body')
|
||||
assert "Error occurred while processing request" in record.message
|
Loading…
Reference in New Issue