[Django] #32159: AsyncTestClient does not allow setting request headers as documented for TestClient via HTTP_* kwargs

19 views
Skip to first unread message

Django

unread,
Oct 30, 2020, 5:34:52 PM10/30/20
to django-...@googlegroups.com
#32159: AsyncTestClient does not allow setting request headers as documented for
TestClient via HTTP_* kwargs
-------------------------------------+-------------------------------------
Reporter: Ryan | Owner: nobody
Vinzent |
Type: Bug | Status: new
Component: Testing | Version: 3.1
framework | Keywords: AsyncTestClient,
Severity: Normal | AsyncRequestFactory
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
In the test client documentation, it states
>CGI specification
>
>The headers sent via `**extra` should follow CGI specification. For
example, emulating a different “Host” header as sent in the HTTP request
from the browser to the server should be passed as `HTTP_HOST`.

This simply does not work for `AsyncTestClient`, even though the
documentation states the async client should behave the same as the
regular test client.

This somehow works to assign a request header:

{{{
client = AsyncTestClient(HTTP_AUTHORIZATION="Bearer faketoken")
await client.get("/api/my-endpoint")
}}}

but this does not work:

{{{
client = AsyncTestClient()
await client.get("/api/my-endpoint", HTTP_AUTHORIZATION="Bearer
faketoken")
}}}

Both of these examples work with the normal `Client` so they should also
work with the `AsyncClient` as is documented.

--
Ticket URL: <https://code.djangoproject.com/ticket/32159>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 2, 2020, 6:56:27 AM11/2/20
to django-...@googlegroups.com
#32159: AsyncTestClient does not respect extra headers.
-------------------------------------+-------------------------------------
Reporter: Ryan Vinzent | Owner: nobody
Type: Bug | Status: new
Component: Testing framework | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: AsyncTestClient, | Triage Stage: Accepted
AsyncRequestFactory |
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* cc: Andrew Godwin, Carlton Gibson (added)
* severity: Normal => Release blocker
* stage: Unreviewed => Accepted


Comment:

Thanks for this report. It looks that we should update the
[https://asgi.readthedocs.io/en/latest/specs/www.html#http-connection-
scope scope headers] not the main scope with `extra`, see
[https://github.com/django/django/blob/d1791539a7d86739cd44c909fa8239cae7f85874/django/test/client.py#L534-L547
AsyncRequestFactory.generic()]. Andrew, Can you confirm?

--
Ticket URL: <https://code.djangoproject.com/ticket/32159#comment:1>

Django

unread,
Nov 3, 2020, 6:19:13 AM11/3/20
to django-...@googlegroups.com
#32159: AsyncTestClient does not respect extra headers.
-------------------------------------+-------------------------------------
Reporter: Ryan Vinzent | Owner: Carlton
| Gibson
Type: Bug | Status: assigned

Component: Testing framework | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: AsyncTestClient, | Triage Stage: Accepted
AsyncRequestFactory |
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Carlton Gibson):

* owner: nobody => Carlton Gibson
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/32159#comment:2>

Django

unread,
Nov 3, 2020, 6:37:56 AM11/3/20
to django-...@googlegroups.com
#32159: AsyncTestClient does not respect extra headers.
-------------------------------------+-------------------------------------
Reporter: Ryan Vinzent | Owner: Carlton
| Gibson
Type: Bug | Status: assigned
Component: Testing framework | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: AsyncTestClient, | Triage Stage: Accepted
AsyncRequestFactory |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Carlton Gibson):

* has_patch: 0 => 1


Comment:

[https://github.com/django/django/pull/13635 PR]

--
Ticket URL: <https://code.djangoproject.com/ticket/32159#comment:3>

Django

unread,
Nov 4, 2020, 3:48:47 AM11/4/20
to django-...@googlegroups.com
#32159: AsyncTestClient does not respect extra headers.
-------------------------------------+-------------------------------------
Reporter: Ryan Vinzent | Owner: Carlton
| Gibson
Type: Bug | Status: assigned
Component: Testing framework | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: AsyncTestClient, | Triage Stage: Accepted
AsyncRequestFactory |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Carlton Gibson):

So the PR adds corrects the `extra` handling to set the header, according
to the ASGI spec, in `scope['headers']`, and `ASGIRequest` then populates
`request.headers` and `request.META` as normal.

The one difference, that I don't think is worth trying to make the same,
is that you don't use the `HTTP_` prefix when passing the headers. So the
example from the description would be:

{{{
client = AsyncTestClient()
await client.get("/api/my-endpoint", AUTHORIZATION="Bearer faketoken")
}}}

I've updated the
[https://docs.djangoproject.com/en/dev/topics/testing/tools/#testing-
asynchronous-code Testing asynchronous code] docs (in the PR) to draw out
this difference.

> ...I don't think is worth trying to make the same...

Due to the fact that the `HTTP_` into `request.META` mapping is inside
`ASGIRequest` we'd need to map from `HTTP_` to lowercased format as
expected in the ASGI `scope` to map back again in `ASGIRequest`. (Contrast
this with `Client` which just provides the WSGI `environ`…) — It would be
a lot of complexity, for a worse API, just to be consistent with a
hangover from CGI...

In that case, simply saying ''Don't use the `HTTP_` prefix with
`AsyncClient'' seems a much cleaner approach.

--
Ticket URL: <https://code.djangoproject.com/ticket/32159#comment:4>

Django

unread,
Nov 4, 2020, 4:43:48 AM11/4/20
to django-...@googlegroups.com
#32159: AsyncTestClient does not respect extra headers.
-------------------------------------+-------------------------------------
Reporter: Ryan Vinzent | Owner: Carlton
| Gibson
Type: Bug | Status: assigned
Component: Testing framework | Version: 3.1
Severity: Release blocker | Resolution:
Keywords: AsyncTestClient, | Triage Stage: Ready for
AsyncRequestFactory | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/32159#comment:5>

Django

unread,
Nov 4, 2020, 5:07:33 AM11/4/20
to django-...@googlegroups.com
#32159: AsyncTestClient does not respect extra headers.
-------------------------------------+-------------------------------------
Reporter: Ryan Vinzent | Owner: Carlton
| Gibson
Type: Bug | Status: closed

Component: Testing framework | Version: 3.1
Severity: Release blocker | Resolution: fixed

Keywords: AsyncTestClient, | Triage Stage: Ready for
AsyncRequestFactory | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by GitHub <noreply@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"ebb08d19424c314c75908bc6048ff57c2f872269" ebb08d19]:
{{{
#!CommitTicketReference repository=""
revision="ebb08d19424c314c75908bc6048ff57c2f872269"
Fixed #32159 -- Ensured AsyncRequestFactory correctly sets headers.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/32159#comment:6>

Django

unread,
Nov 4, 2020, 5:10:50 AM11/4/20
to django-...@googlegroups.com
#32159: AsyncTestClient does not respect extra headers.
-------------------------------------+-------------------------------------
Reporter: Ryan Vinzent | Owner: Carlton
| Gibson
Type: Bug | Status: closed
Component: Testing framework | Version: 3.1
Severity: Release blocker | Resolution: fixed
Keywords: AsyncTestClient, | Triage Stage: Ready for
AsyncRequestFactory | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Carlton Gibson <carlton.gibson@…>):

In [changeset:"8b3010a2983bf298d416e66a8c8974513dd4d73f" 8b3010a2]:
{{{
#!CommitTicketReference repository=""
revision="8b3010a2983bf298d416e66a8c8974513dd4d73f"
[3.1.x] Fixed #32159 -- Ensured AsyncRequestFactory correctly sets
headers.

Backport of ebb08d19424c314c75908bc6048ff57c2f872269 from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/32159#comment:7>

Django

unread,
Nov 12, 2020, 1:45:57 AM11/12/20
to django-...@googlegroups.com
#32159: AsyncTestClient does not respect extra headers.
-------------------------------------+-------------------------------------
Reporter: Ryan Vinzent | Owner: Carlton
| Gibson
Type: Bug | Status: closed
Component: Testing framework | Version: 3.1
Severity: Release blocker | Resolution: fixed
Keywords: AsyncTestClient, | Triage Stage: Ready for
AsyncRequestFactory | checkin
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by perryjrandall):

I assigned a new related ticket here to improve on this
https://code.djangoproject.com/ticket/32189#ticket

--
Ticket URL: <https://code.djangoproject.com/ticket/32159#comment:8>

Reply all
Reply to author
Forward
0 new messages