5

I'm testing a CreateAPIView with an APITestCase class. Things are working as expected as an anonymous user, but when I login() as a user, I get a 405 HttpResponseNotAllowed exception. I'm able to successfully create an object while authed as a user through the django-rest-framework web frontend. I'm using djangorestframework version 3.9.4 and Django 1.11.29.

Here are the main parts of the code, for a general idea of what I'm doing:

class SherdNoteCreate(CreateAPIView): serializer_class = SherdNoteSerializer def post(self, request, *args, **kwargs): data = request.data.copy() data['asset'] = kwargs.get('asset_id') serializer = SherdNoteSerializer(data=data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) ​ class SherdNoteTests(APITestCase): def test_create_sherdnote_on_own_asset(self): # Removing this auth block allows the test to pass self.u = UserFactory(username='test_user') self.u.set_password('test') self.u.save() login = self.client.login(username='test_user', password='test') assert(login is True) asset = AssetFactory(primary_source='image', author=self.u) url = reverse('sherdnote-create', kwargs={'asset_id': asset.pk}) data = { 'title': 'note title', 'body': 'note body' } response = self.client.post(url, data, format='json') # This fails with a 405! self.assertEqual(response.status_code, status.HTTP_201_CREATED) 

The route in urls.py:

 url(r'^(?P<asset_id>\d+)/sherdnote/create/$', SherdNoteCreate.as_view(), name='sherdnote-create'), 

Here's the response and response.__dict__ printed out, from the test above:

<HttpResponseNotAllowed [GET, HEAD, OPTIONS] status_code=405, "text/html; charset=utf-8"> {'_headers': {'content-type': ('Content-Type', 'text/html; charset=utf-8'), 'allow': ('Allow', 'GET, HEAD, OPTIONS'), 'vary': ('Va ry', 'Origin, Cookie'), 'x-frame-options': ('X-Frame-Options', 'SAMEORIGIN'), 'content-length': ('Content-Length', '0')}, '_closab le_objects': [<WSGIRequest: POST '/asset/1/sherdnote/create/'>], '_handler_class': None, 'cookies': <SimpleCookie: >, 'closed': Tr ue, '_reason_phrase': None, '_charset': None, '_container': [b''], 'wsgi_request': <WSGIRequest: POST '/asset/1/sherdnote/create/' >, 'client': <rest_framework.test.APIClient object at 0x7f9880902f10>, 'request': {'PATH_INFO': '/asset/1/sherdnote/create/', 'REQ UEST_METHOD': 'POST', 'SERVER_PORT': '80', 'wsgi.url_scheme': 'http', 'CONTENT_LENGTH': 41, 'CONTENT_TYPE': 'application/json; cha rset=None', 'wsgi.input': <django.test.client.FakePayload object at 0x7f987e834790>, 'QUERY_STRING': ''}, 'templates': [], 'contex t': None, 'json': <function curry.<locals>._curried at 0x7f988018e440>, 'resolver_match': <SimpleLazyObject: <function Client.requ est.<locals>.<lambda> at 0x7f988018eef0>>, '_dont_enforce_csrf_checks': True} 

I've been having trouble tracking down why this is happening. Does anyone have any ideas?

6
  • Maybe this Tutorial can help. Commented Mar 27, 2020 at 23:52
  • 1
    Looks like some issue with url = reverse('sherdnote-create', kwargs={'asset_id': asset.pk}) can you debug this line and see if your post request is sent to correct url. Commented Mar 27, 2020 at 23:54
  • @MuhammadAdnan The post request is being sent to the correct url: /asset/1/sherdnote/create/ Commented Mar 28, 2020 at 2:38
  • Can you post using postman or curl successfully? 405 HTTP response status code indicates that the request method is known by the server but is not supported by the target resource. Commented Mar 30, 2020 at 14:16
  • @nnyby can you perhaps try to use the django TestCase instead of APITestCase and see if the output changes. Also, try replacing post method in your view to be create, they should be the same. Commented Mar 30, 2020 at 16:23

2 Answers 2

3

Okay, well there was some course middleware in my application that was interfering with my API requests. The solution was to make a sample course and make my test user a student in that course before making the request.

Sign up to request clarification or add additional context in comments.

Comments

0

For anyone else that ended up here like me looking for answers. I was upgrading my Django/graphene stack from Django 2.2 -> 3.2 and all the latest graphene-related things. The 405 for me was coming from a URL that didn't quite line up because of a lack of slashes to close out the URL;

I couldn't make my tests work because the graphene 3.0 default testing endpoint is set to '/graphql', where my url pattern in django was

path( "graphql/", csrf_exempt( ConsistentErrorsGraphQLView.as_view(graphiql=settings.USE_GRAPHIQL) ), ), 

to fix it, I set my graphene testing endpoint in my django settings:

GRAPHENE = { ... "TESTING_ENDPOINT": "/graphql/" ... } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.