OAuth authentication in unit tests using django rest framework and django oauth toolkit
How do I write unit tests for those endpoints of my API that require oAuth authentication?
Simply adding OAuth tokens to request headers doesn't work (possibly because the test database is not persistent). Loading items into the database doesn't help either.
I am using django-rest-framework along with django-oauth-toolkit.
My test.py code:
class Com_jm_Test(TestCase):
fixtures=['oauth.json',]
print 'test com jm'
multi_db=True
def test_list_job(self):
self.client=Client(HTTP_AUTHORIZATION='Bearer 0cx2G9gKm4XZdK8BFxoWy7AE025tvq')
response=self.client.get('/com-jm/jobs/')
self.assertEqual(response.status_code,200)
Result:
AssertionError: 401 != 200
source to share
Check out the DRF documentation for testing, specifically the Force Authentication chapter . From these docs:
For example, when forcing authentication using a token, you can do something like the following:
user = User.objects.get(username='olivia') request = factory.get('/accounts/django-superstars/') force_authenticate(request, user=user, token=user.token)
source to share
Do it like this:
- Create user
- Create application
-
Create a token
def __create_authorization_header(token): return "Bearer {0}".format(token) def __create_token(self, user): app = Application.objects.create( client_type=Application.CLIENT_CONFIDENTIAL, authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE, redirect_uris='https://www.none.com/oauth2/callback', name='dummy', user=user ) access_token = AccessToken.objects.create( user=user, scope='read write', expires=timezone.now() + timedelta(seconds=300), token='secret-access-token-key', application=self.app ) return access_token user = User(username='dummy', email='dummy@geneu.com') user.save() self.user = user token = __create_authorization_header(__create_token(user)) response=self.client.get('/com-jm/jobs/', format='json', HTTP_AUTHORIZATION=token)
self.assertEqual (response.status_code, 200)
Off course, this should be tailored to your needs, but that's the idea. For future problems of this nature (when you haven't found enough information in the documentation to archive your goals), I recommend that you check the source code. In this case, for example, you can find how to do this in the toolkit lib test. ( django-oauth-toolkit / oauth2_provider / tests / test_authorization_code.py )
source to share
I faced the same problem. Here is my solution.
DRF provides APIClient
to fulfill requests.
The class APIClient
supports the same request interface as the standard Django client class. This means that the .get(),.post(),.put(),.patch(),.delete(),.head()
standard .get(),.post(),.put(),.patch(),.delete(),.head()
and .options()
.
It also provides a method credentials
that you can use to set headers, which will then be included in all subsequent requests by the test client.
client = APIClient() client.credentials(HTTP_AUTHORIZATION='Token AB7JSH^4454')
Generating an Oauth token
create and get user
token = user.oauth2_provider_accesstoken.create(expires='expire_date', token='token')
Setting the Ouath Token Using APIClient
client = APIClient()
client.credentials(Authorization='Bearer {}'.format(token))
client.get(reverse('accounts_api:profile'))
We can set the default content type
REST_FRAMEWORK += {
'TEST_REQUEST_DEFAULT_FORMAT': 'json'
}
source to share