From ebb08d19424c314c75908bc6048ff57c2f872269 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Wed, 4 Nov 2020 11:07:15 +0100 Subject: [PATCH] Fixed #32159 -- Ensured AsyncRequestFactory correctly sets headers. --- django/test/client.py | 8 +++++++- docs/releases/3.1.4.txt | 3 +++ docs/topics/testing/tools.txt | 17 +++++++++++++++-- tests/test_client/tests.py | 11 +++++++++++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/django/test/client.py b/django/test/client.py index dfd443a83c..2d501e0da6 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -544,7 +544,13 @@ class AsyncRequestFactory(RequestFactory): (b'content-type', content_type.encode('ascii')), ]) s['_body_file'] = FakePayload(data) - s.update(extra) + follow = extra.pop('follow', None) + if follow is not None: + s['follow'] = follow + s['headers'] += [ + (key.lower().encode('ascii'), value.encode('latin1')) + for key, value in extra.items() + ] # If QUERY_STRING is absent or empty, we want to extract it from the # URL. if not s.get('query_string'): diff --git a/docs/releases/3.1.4.txt b/docs/releases/3.1.4.txt index f8d9752db7..6641b0aaf5 100644 --- a/docs/releases/3.1.4.txt +++ b/docs/releases/3.1.4.txt @@ -11,3 +11,6 @@ Bugfixes * Fixed setting the ``Content-Length`` HTTP header in ``AsyncRequestFactory`` (:ticket:`32162`). + +* Fixed passing extra HTTP headers to ``AsyncRequestFactory`` request methods + (:ticket:`32159`). diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt index d4bdb5157c..2d10873611 100644 --- a/docs/topics/testing/tools.txt +++ b/docs/topics/testing/tools.txt @@ -1810,9 +1810,22 @@ If you are testing from an asynchronous function, you must also use the asynchronous test client. This is available as ``django.test.AsyncClient``, or as ``self.async_client`` on any test. -With the exception of the ``follow`` parameter, which is not supported, ``AsyncClient`` has the same methods and signatures as the synchronous (normal) -test client, but any method that makes a request must be awaited:: +test client, with two exceptions: + +* The ``follow`` parameter is not supported. +* Headers passed as ``extra`` keyword arguments should not have the ``HTTP_`` + prefix required by the synchronous client (see :meth:`Client.get`). For + example, here is how to set an HTTP ``Accept`` header:: + + >>> c = AsyncClient() + >>> c.get( + ... '/customers/details/', + ... {'name': 'fred', 'age': 7}, + ... ACCEPT='application/json' + ... ) + +Using ``AsyncClient`` any method that makes a request must be awaited:: async def test_my_thing(self): response = await self.async_client.get('/some-url/') diff --git a/tests/test_client/tests.py b/tests/test_client/tests.py index 457c53852e..ef8312d1c0 100644 --- a/tests/test_client/tests.py +++ b/tests/test_client/tests.py @@ -1012,3 +1012,14 @@ class AsyncRequestFactoryTest(SimpleTestCase): response = await async_generic_view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.content, b'{"example": "data"}') + + def test_request_factory_sets_headers(self): + request = self.request_factory.get( + '/somewhere/', + AUTHORIZATION='Bearer faketoken', + X_ANOTHER_HEADER='some other value', + ) + self.assertEqual(request.headers['authorization'], 'Bearer faketoken') + self.assertIn('HTTP_AUTHORIZATION', request.META) + self.assertEqual(request.headers['x-another-header'], 'some other value') + self.assertIn('HTTP_X_ANOTHER_HEADER', request.META)