I have to build the API for one of my web service. It’s Django and django-piston powered application and it works well. Okay. I chose the TDD technique. So my problem was: how do I test the API parts which need authentication (basic HTTP, not OAuth for now)? The built-in test client of Django doesn’t seem to have such a feature.
So, here is my small workaround: you have to generate the HTTP_AUTHORIZATION field of your HTTP request. I wrote a small base test class for tests which need authentication:
import base64
import unittest
from django.test.client import Client
class BaseAuthenticatedClient(unittest.TestCase):
def setUp(self):
self.client = Client()
auth = '%s:%s' % ('username', 'password')
auth = 'Basic %s' % base64.encodestring(auth)
auth = auth.strip()
self.extra = {
'HTTP_AUTHORIZATION': auth,
}
You just have to replace username and password, and write your own test suite:
class TestAPIAuth(BaseAuthenticatedClient):
def testrootauth(self):
response = self.client.get('/api/aresource/id', {}, **self.extra)
self.assertEqual(response.status_code, 200)
It should be OK. Have fun!

You are absolutely right. You know what? It turns out that the password field in my fixture was messed up. Not sure how that happened, but it's working now. Thank you so much for your help.
You are absolutely right. You know what? It turns out that the password field in my fixture was messed up. Not sure how that happened, but it's working now. Thank you so much for your help.
I think not. Here is the client.get() definition:
get(path, data={}, follow=False, **extra)
If data is omitted (in yours), it has the same value as mine.
the only difference I see is in the parameters at the end of the client.get() call:
… {}, **self.extra)
vs.
… HTTP_AUTHORIZATION='Basic %s' % base64.encodestring('%s:%s' % ('dave','password')).rstrip())
your has the extra {} in there. Does that make a difference?
Just tested in my local application: both strip and rstrip work.
This code does the same thing as mine, but it uses rstrip() insead of strip(). I'm not sure how it can impact on the result, yet try to change strip() to rstrip() in my code, and see if it works.
I got some help from the django-piston google group, and it looks like this works:
response = self.client.get('/api/stuff/', HTTP_AUTHORIZATION='Basic %s' % base64.encodestring('%s:%s' % ('dave','password')).rstrip())
which doesn't match what your code does above. Any ideas why this way works for me and not your way?
Yes, it looks like there is a problem in your configuration of your Piston auth backend (often set in urls.py). Paste your file here to see if we can fix it.
When I try to use this method of http authentication in a unit test against a django-piston api, I receive the following error message:
…/piston/authentication.py”, line 56, in is_authenticated
request.user = self.auth_func(username=username, password=password)
…/django/contrib/auth/init.py”, line 36, in authenticate
user = backend.authenticate(**credentials)
…/django/contrib/auth/backends.py”, line 19, in authenticate
if user.check_password(password):
…/django/contrib/auth/models.py”, line 197, in check_password
return check_password(raw_password, self.password)
…/django/contrib/auth/models.py”, line 53, in check_password
algo, salt, hsh = enc_password.split('$')
ValueError: need more than 2 values to unpack
Could this be related to the realm setting in my piston urls.py file?