浏览代码

Fixed #32159 -- Ensured AsyncRequestFactory correctly sets headers.

Carlton Gibson 4 年之前
父节点
当前提交
ebb08d1942
共有 4 个文件被更改,包括 36 次插入3 次删除
  1. 7 1
      django/test/client.py
  2. 3 0
      docs/releases/3.1.4.txt
  3. 15 2
      docs/topics/testing/tools.txt
  4. 11 0
      tests/test_client/tests.py

+ 7 - 1
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'):

+ 3 - 0
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`).

+ 15 - 2
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/')

+ 11 - 0
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)