Background:
I have integration test which is working fine, but later on failed when I
added the customized middleware
def test_mobile_update_customer(self):
user = User.objects.create(username='warhead')
self.client.force_authenticate(user=user)
mommy.make(Customer, family_name='IBM', created_user=self.soken_staff, updated_user=self.soken_staff)
data = {
"family_name": "C0D1UM"
}
customer = Customer.objects.first()
res = self.client.patch(reverse('api:customer-detail', kwargs={'pk': customer.id}), data=data)
self.assertEqual(200, res.status_code)
customer.refresh_from_db()
self.assertEqual('C0D1UM', customer.family_name)
self.assertEqual('spearhead', customer.created_user.username)
self.assertEqual('warhead', customer.updated_user.username)
Problem:
The middleware break it with Exception
File "/Users/el/Code/norak-cutter/soken/soken-web/soken_web/middleware.py", line 47, in process_request
data['PATCH'] = json.loads(request.body)
File "/Users/el/.pyenv/versions/soken/lib/python3.6/site-packages/django/http/request.py", line 264, in body
raise RawPostDataException("You cannot access body after reading from request's data stream")
django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
The problem is data
has been read before the RESTful
api do the job.
Then the program raises an exception.
def process_request(self, request):
if request.path.startswith('/api/'):
data = collections.OrderedDict()
data["user"] = request.user.username
data["path"] = request.path
data["method"] = request.method
data["content-type"] = request.content_type
if request.method == 'GET':
data['GET'] = request.GET
elif request.method == 'POST':
data['POST'] = request.POST
# https://stackoverflow.com/questions/4994789/django-where-are-the-params-stored-on-a-put-delete-request
# elif request.method == 'PUT':
# data['PUT'] = json.loads(request.body)
# test_mobile_update_customer
# raise RawPostDataException("You cannot access body after reading from request's data stream")
# django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
# elif request.method == 'PATCH':
# data['PATCH'] = json.loads(request.body)
elif request.method == 'DELETE':
pass
self.__uuid = str(uuid.uuid4())
request_logger.info(f'{self.__uuid} {json.dumps(data)}')
Update2
Attempt:
I change client
constructor refer to https://github.com/encode/django-rest-framework/issues/2774
def test_mobile_update_customer(self):
user = User.objects.create(username='warhead')
# self.client.force_authenticate(user=user)
from django.test import Client
client = Client()
client.force_login(user)
mommy.make(Customer, family_name='IBM', created_user=self.soken_staff, updated_user=self.soken_staff)
data = {
"family_name": "C0D1UM"
}
customer = Customer.objects.first()
res = client.patch(reverse('api:customer-detail', kwargs={'pk': customer.id}), data=data, content_type='application/json')
self.assertEqual(200, res.status_code)
customer.refresh_from_db()
self.assertEqual('C0D1UM', customer.family_name)
self.assertEqual('spearhead', customer.created_user.username)
self.assertEqual('warhead', customer.updated_user.username)
It does not work. The Client
misinterpret the payload
>>> res.content
b'{"detail":"JSON parse error - Expecting property name enclosed in double quotes: line 1 column 2 (char 1)"}'
Workaround:
I don't know this is correct for all cases or not, but I workaround by this
test.py
https://gist.github.com/elcolie/88eb7c90cfca1c369a020ac232c7fbcc
middleware.py
https://gist.github.com/elcolie/5d9b1a2f890a0efcb46fdb95c0e90908
result.py
https://gist.github.com/elcolie/298e595b404c1a5839ed8dd584d2f07f
Question:
How do I do integration test of PATCH
with the same time that testcase will not break by my middleware?
Right now I have to choose either one of them.