title: Adding tests to the Django REST framework tutorial
body: <p>I'm trying to replace an existing function-based view using the <code>login_required</code> decorator with a Django REST framework API using a <code>ModelViewSet</code>. However, it seems like the authentication works a bit differently.</p>
  
  <p>In order to try to adapt my unit tests to the Django REST framework case, I cloned <a href="https://github.com/encode/rest-framework-tutorial" rel="nofollow noreferrer">https://github.com/encode/rest-framework-tutorial</a> and added a <code>tests.py</code> at the top level directory:</p>
  
  <pre><code>import json
  
  from django.contrib.auth.models import User
  from django.test import TestCase, Client
  
  from snippets.models import Snippet
  
  class SnippetTestCase(TestCase):
      def setUp(self):
          self.username = 'john_doe'
          self.password = 'foobar'
          self.user = User.objects.create(username=self.username, password=self.password)
  
          self.client = Client()
          self.snippet = Snippet.objects.create(owner=self.user, code="Foo Bar")
  
      def test_1(self):
          self.client.login(username=self.username, password=self.password)
          response = self.client.post(
                  path='http://localhost:8000/snippets/1/',
                  data=json.dumps({'code': 'New code'}),
                  content_type="application/json")
          self.assertEqual(response.status_code, 201)
  </code></pre>
  
  <p>However, this returns a <code>403 Forbidden</code> response:</p>
  
  <pre><code>Kurts-MacBook-Pro:rest-framework-tutorial kurtpeek$ python manage.py test
  Creating test database for alias 'default'...
  System check identified no issues (0 silenced).
  F
  ======================================================================
  FAIL: test_1 (tutorial.tests.SnippetTestCase)
  ----------------------------------------------------------------------
  Traceback (most recent call last):
    File "/Users/kurtpeek/Documents/source/rest-framework-tutorial/tutorial/tests.py", line 23, in test_1
      self.assertEqual(response.status_code, 201)
  AssertionError: 403 != 201
  
  ----------------------------------------------------------------------
  Ran 1 test in 0.049s
  
  FAILED (failures=1)
  Destroying test database for alias 'default'...
  </code></pre>
  
  <p>On the other hand, using HTTPie with the <code>-a</code> flag works fine:</p>
  
  <pre><code>Kurts-MacBook-Pro:rest-framework-tutorial kurtpeek$ http -a kurtpeek:foobar123 POST http://localhost:8000/snippets/ code="print 123"
  HTTP/1.1 201 Created
  Allow: GET, POST, HEAD, OPTIONS
  Content-Length: 212
  Content-Type: application/json
  Date: Thu, 25 Jan 2018 00:11:59 GMT
  Location: http://localhost:8000/snippets/2/
  Server: WSGIServer/0.2 CPython/3.6.4
  Vary: Accept, Cookie
  X-Frame-Options: SAMEORIGIN
  
  {
      "code": "print 123",
      "highlight": "http://localhost:8000/snippets/2/highlight/",
      "id": 2,
      "language": "python",
      "linenos": false,
      "owner": "kurtpeek",
      "style": "friendly",
      "title": "",
      "url": "http://localhost:8000/snippets/2/"
  }
  </code></pre>
  
  <p>It seems to me like this test should fulfill the requirements of the <code>IsOwnerOrReadonly</code> permissions class:</p>
  
  <pre><code>from rest_framework import permissions
  
  
  class IsOwnerOrReadOnly(permissions.BasePermission):
      """
      Custom permission to only allow owners of an object to edit it.
      """
  
      def has_object_permission(self, request, view, obj):
          # Read permissions are allowed to any request,
          # so we'll always allow GET, HEAD or OPTIONS requests.
          if request.method in permissions.SAFE_METHODS:
              return True
  
          # Write permissions are only allowed to the owner of the snippet.
          return obj.owner == request.user
  </code></pre>
  
  <p>because the same <code>User</code> is also the <code>owner</code> of the snippet. Any ideas why this is not working, or how I could construct test cases that do pass?</p>