Test Requests for Django Rest Framework aren't parsable by its own Request class
Question: I'm writing an endpoint to receive and parse [GitHub Webhook
payloads](https://developer.github.com/webhooks/#example-delivery) using
Django Rest Framework 3. In order to match the payload specification, I'm
writing a payload request factory and testing that it's generating valid
requests.

However, the problem comes when trying to test the request generated with
DRF's `Request` class. Here's the smallest failing test I could come up with -
the problem is that a request generated with DRF's `APIRequestFactory` seems
to not be parsable by DRF's `Request` class. Is that expected behaviour?

    
    
    from rest_framework.request import Request
    from rest_framework.parsers import JSONParser
    from rest_framework.test import APIRequestFactory, APITestCase
    
    
    class TestRoundtrip(APITestCase):
    
        def test_round_trip(self):
            """
            A DRF Request can be loaded into a DRF Request object
            """
            request_factory = APIRequestFactory()
            request = request_factory.post(
                '/',
                data={'hello': 'world'},
                format='json',
            )
    
            result = Request(request, parsers=(JSONParser,))
    
            self.assertEqual(result.data['hello'], 'world')
    

And the stack trace is:

    
    
    E
    ======================================================================
    ERROR: A DRF Request can be loaded into a DRF Request object
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/request.py", line 380, in __getattribute__
        return getattr(self._request, attr)
    AttributeError: 'WSGIRequest' object has no attribute 'data'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/home/james/active/prlint/prlint/github/tests/test_payload_factories/test_roundtrip.py", line 22, in test_round_trip
        self.assertEqual(result.data['hello'], 'world')
      File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/request.py", line 382, in __getattribute__
        six.reraise(info[0], info[1], info[2].tb_next)
      File "/home/james/active/prlint/venv/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise
        raise value.with_traceback(tb)
      File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/request.py", line 186, in data
        self._load_data_and_files()
      File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/request.py", line 246, in _load_data_and_files
        self._data, self._files = self._parse()
      File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/request.py", line 312, in _parse
        parsed = parser.parse(stream, media_type, self.parser_context)
      File "/home/james/active/prlint/venv/lib/python3.4/site-packages/rest_framework/parsers.py", line 64, in parse
        data = stream.read().decode(encoding)
    AttributeError: 'str' object has no attribute 'read'
    
    ----------------------------------------------------------------------
    

I'm obviously doing something stupid - I've messed around with encodings...
realised that I needed to pass the parsers list to the `Request` to avoid the
`UnsupportedMediaType` error, and now I'm stuck here.

Should I do something different? Maybe avoid using `APIRequestFactory`? Or
test my built GitHub requests a different way?

* * *

## More info

GitHub sends a request out to registered webhooks that has a `X-GitHub-Event`
header and therefore in order to test my webhook DRF code I need to be able to
emulate this header at test time.

My path to succeeding with this has been to build a custom Request and load a
payload using a factory into it. This is my factory code:

    
    
    def PayloadRequestFactory():
        """
        Build a Request, configure it to look like a webhook payload from GitHub.
        """
        request_factory = APIRequestFactory()
        request = request_factory.post(url, data=PingPayloadFactory())
        request.META['HTTP_X_GITHUB_EVENT'] = 'ping'
        return request
    

The issue has arisen because I want to assert that `PayloadRequestFactory` is
generating valid requests for various passed arguments - so I'm trying to
parse them and assert their validity but DRF's `Request` class doesn't seem to
be able to achieve this - hence my question with a failing test.

So really my question is - how should I test this `PayloadRequestFactory` is
generating the kind of request that I need?


Answer: "Yo dawg, I heard you like Request, cos' you put a Request inside a Request"
XD

I'd do it like this:

    
    
    from rest_framework.test import APIClient
    
    client = APIClient()
    response = client.post('/', {'github': 'payload'}, format='json')
    self.assertEqual(response.data, {'github': 'payload'})
    # ...or assert something was called, etc.
    

Hope this helps

