class ConsumerTest(TestCase): fixtures = ['models.json'] def setUp(self): self.consumer = Consumer() self.consumer.name = "Piston Test Consumer" self.consumer.description = "A test consumer for Piston." self.consumer.user = User.objects.get(pk=3) self.consumer.generate_random_codes() def _pre_test_email(self): template = "piston/mails/consumer_%s.txt" % self.consumer.status try: loader.render_to_string(template, { 'consumer': self.consumer, 'user': self.consumer.user }) return True except TemplateDoesNotExist: """ They haven't set up the templates, which means they might not want these emails sent. """ return False def test_create_pending(self): """ Ensure creating a pending Consumer sends proper emails """ # Verify if the emails can be sent if not self._pre_test_email(): return # If it's pending we should have two messages in the outbox; one # to the consumer and one to the site admins. if len(settings.ADMINS): self.assertEquals(len(mail.outbox), 2) else: self.assertEquals(len(mail.outbox), 1) expected = "Your API Consumer for example.com is awaiting approval." self.assertEquals(mail.outbox[0].subject, expected) def test_delete_consumer(self): """ Ensure deleting a Consumer sends a cancel email """ # Clear out the outbox before we test for the cancel email. mail.outbox = [] # Delete the consumer, which should fire off the cancel email. self.consumer.delete() # Verify if the emails can be sent if not self._pre_test_email(): return self.assertEquals(len(mail.outbox), 1) expected = "Your API Consumer for example.com has been canceled." self.assertEquals(mail.outbox[0].subject, expected)
class OAuthTests(APIMainTest): """ OAuthTest Does oauth handshake test and gives derived test classes tests the possibility to do OAuth resource requests. """ signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1() def setUp(self): super(OAuthTests, self).setUp() self.consumer = Consumer(name='Test Consumer', description='Test', status='accepted') self.consumer.generate_random_codes() self.consumer.save() self.oa_atoken = None self.test_handshake() def tearDown(self): super(OAuthTests, self).tearDown() self.consumer.delete() def do_oauth_request(self, url, parameters={}, http_method='POST'): oaconsumer = oauth.OAuthConsumer(self.consumer.key, self.consumer.secret) request = oauth.OAuthRequest.from_consumer_and_token( oaconsumer, http_method=http_method, token=self.oa_atoken, http_url='http://testserver%s' % url) request.parameters.update(parameters) request.sign_request(self.signature_method, oaconsumer, self.oa_atoken) if http_method == 'POST': response = self.client.post(url, request.parameters) else: response = self.client.get(url, request.parameters) return response def test_handshake(self): '''Test the OAuth handshake procedure ''' oaconsumer = oauth.OAuthConsumer(self.consumer.key, self.consumer.secret) # Get a request key... request = oauth.OAuthRequest.from_consumer_and_token( oaconsumer, http_url='http://testserver/oauth/request_token/') request.sign_request(self.signature_method, oaconsumer, None) response = self.client.get('/oauth/request_token/', request.parameters) oatoken = oauth.OAuthToken.from_string(response.content) token = Token.objects.get(key=oatoken.key, token_type=Token.REQUEST) self.assertEqual(token.secret, oatoken.secret) # Simulate user authentication... self.failUnless(self.client.login(username='******', password='******')) request = oauth.OAuthRequest.from_token_and_callback( token=oatoken, callback='http://printer.example.com/request_token_ready', http_url='http://testserver/oauth/authorize/') request.sign_request(self.signature_method, oaconsumer, oatoken) # Request the login page # TODO: Parse the response to make sure all the fields exist # response = self.client.get('/api/oauth/authorize', { # 'oauth_token': oatoken.key, # 'oauth_callback': 'http://printer.example.com/request_token_ready', # }) response = self.client.post( '/oauth/authorize/', { 'oauth_token': oatoken.key, 'oauth_callback': 'http://printer.example.com/request_token_ready', 'csrf_signature': OAuthAuthenticationForm.get_csrf_signature( settings.SECRET_KEY, oatoken.key), 'authorize_access': 1, }) # Response should be a redirect... self.assertEqual(302, response.status_code) self.assertEqual( 'http://printer.example.com/request_token_ready?oauth_token=' + oatoken.key, response['Location']) # Obtain access token... request = oauth.OAuthRequest.from_consumer_and_token( oaconsumer, token=oatoken, http_url='http://testserver/oauth/access_token/') request.sign_request(self.signature_method, oaconsumer, oatoken) response = self.client.get('/oauth/access_token/', request.parameters) oa_atoken = oauth.OAuthToken.from_string(response.content) atoken = Token.objects.get(key=oa_atoken.key, token_type=Token.ACCESS) self.assertEqual(atoken.secret, oa_atoken.secret) # save the acces token so we can do oauth requests self.oa_atoken = oa_atoken
class OAuthTests(MainTests): signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1() def setUp(self): super(OAuthTests, self).setUp() self.consumer = Consumer(name='Test Consumer', description='Test', status='accepted') self.consumer.generate_random_codes() self.consumer.save() def tearDown(self): super(OAuthTests, self).tearDown() self.consumer.delete() def test_handshake(self): '''Test the OAuth handshake procedure ''' oaconsumer = oauth.OAuthConsumer(self.consumer.key, self.consumer.secret) # Get a request key... request = oauth.OAuthRequest.from_consumer_and_token( oaconsumer, http_url='http://testserver/api/oauth/request_token') request.sign_request(self.signature_method, oaconsumer, None) response = self.client.get('/api/oauth/request_token', request.parameters) oatoken = oauth.OAuthToken.from_string(response.content) token = Token.objects.get(key=oatoken.key, token_type=Token.REQUEST) self.assertEqual(token.secret, oatoken.secret) # Simulate user authentication... self.failUnless(self.client.login(username='******', password='******')) request = oauth.OAuthRequest.from_token_and_callback( token=oatoken, callback='http://printer.example.com/request_token_ready', http_url='http://testserver/api/oauth/authorize') request.sign_request(self.signature_method, oaconsumer, oatoken) # Request the login page # TODO: Parse the response to make sure all the fields exist # response = self.client.get('/api/oauth/authorize', { # 'oauth_token': oatoken.key, # 'oauth_callback': 'http://printer.example.com/request_token_ready', # }) response = self.client.post( '/api/oauth/authorize', { 'oauth_token': oatoken.key, 'oauth_callback': 'http://printer.example.com/request_token_ready', 'csrf_signature': OAuthAuthenticationForm.get_csrf_signature( settings.SECRET_KEY, oatoken.key), 'authorize_access': 1, }) # Response should be a redirect... self.assertEqual(302, response.status_code) self.assertEqual( 'http://printer.example.com/request_token_ready?oauth_token=' + oatoken.key, response['Location']) # Obtain access token... request = oauth.OAuthRequest.from_consumer_and_token( oaconsumer, token=oatoken, http_url='http://testserver/api/oauth/access_token') request.sign_request(self.signature_method, oaconsumer, oatoken) response = self.client.get('/api/oauth/access_token', request.parameters) oa_atoken = oauth.OAuthToken.from_string(response.content) atoken = Token.objects.get(key=oa_atoken.key, token_type=Token.ACCESS) self.assertEqual(atoken.secret, oa_atoken.secret)
class OAuthTests(MainTests): signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1() def setUp(self): super(OAuthTests, self).setUp() self.consumer = Consumer(name="Test Consumer", description="Test", status="accepted") self.consumer.generate_random_codes() self.consumer.save() def tearDown(self): super(OAuthTests, self).tearDown() self.consumer.delete() def test_handshake(self): """Test the OAuth handshake procedure """ oaconsumer = oauth.OAuthConsumer(self.consumer.key, self.consumer.secret) # Get a request key... request = oauth.OAuthRequest.from_consumer_and_token( oaconsumer, http_url="http://testserver/api/oauth/request_token" ) request.sign_request(self.signature_method, oaconsumer, None) response = self.client.get("/api/oauth/request_token", request.parameters) oatoken = oauth.OAuthToken.from_string(response.content) token = Token.objects.get(key=oatoken.key, token_type=Token.REQUEST) self.assertEqual(token.secret, oatoken.secret) # Simulate user authentication... self.failUnless(self.client.login(username="******", password="******")) request = oauth.OAuthRequest.from_token_and_callback( token=oatoken, callback="http://printer.example.com/request_token_ready", http_url="http://testserver/api/oauth/authorize", ) request.sign_request(self.signature_method, oaconsumer, oatoken) # Request the login page # TODO: Parse the response to make sure all the fields exist # response = self.client.get('/api/oauth/authorize', { # 'oauth_token': oatoken.key, # 'oauth_callback': 'http://printer.example.com/request_token_ready', # }) response = self.client.post( "/api/oauth/authorize", { "oauth_token": oatoken.key, "oauth_callback": "http://printer.example.com/request_token_ready", "csrf_signature": OAuthAuthenticationForm.get_csrf_signature(settings.SECRET_KEY, oatoken.key), "authorize_access": 1, }, ) # Response should be a redirect... self.assertEqual(302, response.status_code) self.assertEqual( "http://printer.example.com/request_token_ready?oauth_token=" + oatoken.key, response["Location"] ) # Obtain access token... request = oauth.OAuthRequest.from_consumer_and_token( oaconsumer, token=oatoken, http_url="http://testserver/api/oauth/access_token" ) request.sign_request(self.signature_method, oaconsumer, oatoken) response = self.client.get("/api/oauth/access_token", request.parameters) oa_atoken = oauth.OAuthToken.from_string(response.content) atoken = Token.objects.get(key=oa_atoken.key, token_type=Token.ACCESS) self.assertEqual(atoken.secret, oa_atoken.secret)
class OAuthTests(APIMainTest): """ OAuthTest Does oauth handshake test and gives derived test classes tests the possibility to do OAuth resource requests. """ signature_method = oauth.OAuthSignatureMethod_HMAC_SHA1() def setUp(self): super(OAuthTests, self).setUp() self.consumer = Consumer(name='Test Consumer', description='Test', status='accepted') self.consumer.generate_random_codes() self.consumer.save() self.oa_atoken = None self.test_handshake() def tearDown(self): super(OAuthTests, self).tearDown() self.consumer.delete() def do_oauth_request(self, url , parameters = {} , http_method = 'POST' ): oaconsumer = oauth.OAuthConsumer(self.consumer.key, self.consumer.secret) request = oauth.OAuthRequest.from_consumer_and_token( oaconsumer, http_method=http_method, token=self.oa_atoken, http_url='http://testserver%s' % url ) request.parameters.update( parameters ) request.sign_request(self.signature_method, oaconsumer, self.oa_atoken ) if http_method == 'POST': response = self.client.post( url, request.parameters ) else : response = self.client.get( url, request.parameters ) return response def test_handshake(self): '''Test the OAuth handshake procedure ''' oaconsumer = oauth.OAuthConsumer(self.consumer.key, self.consumer.secret) # Get a request key... request = oauth.OAuthRequest.from_consumer_and_token(oaconsumer, http_url='http://testserver/oauth/request_token/' ) request.sign_request(self.signature_method, oaconsumer, None) response = self.client.get('/oauth/request_token/', request.parameters) oatoken = oauth.OAuthToken.from_string(response.content) token = Token.objects.get(key=oatoken.key, token_type=Token.REQUEST) self.assertEqual(token.secret, oatoken.secret) # Simulate user authentication... self.failUnless(self.client.login(username='******', password='******')) request = oauth.OAuthRequest.from_token_and_callback(token=oatoken, callback='http://printer.example.com/request_token_ready', http_url='http://testserver/oauth/authorize/') request.sign_request(self.signature_method, oaconsumer, oatoken) # Request the login page # TODO: Parse the response to make sure all the fields exist # response = self.client.get('/api/oauth/authorize', { # 'oauth_token': oatoken.key, # 'oauth_callback': 'http://printer.example.com/request_token_ready', # }) response = self.client.post('/oauth/authorize/', { 'oauth_token': oatoken.key, 'oauth_callback': 'http://printer.example.com/request_token_ready', 'csrf_signature': OAuthAuthenticationForm.get_csrf_signature(settings.SECRET_KEY, oatoken.key), 'authorize_access': 1, }) # Response should be a redirect... self.assertEqual(302, response.status_code) self.assertEqual('http://printer.example.com/request_token_ready?oauth_token='+oatoken.key, response['Location']) # Obtain access token... request = oauth.OAuthRequest.from_consumer_and_token(oaconsumer, token=oatoken, http_url='http://testserver/oauth/access_token/') request.sign_request(self.signature_method, oaconsumer, oatoken) response = self.client.get('/oauth/access_token/', request.parameters) oa_atoken = oauth.OAuthToken.from_string(response.content) atoken = Token.objects.get(key=oa_atoken.key, token_type=Token.ACCESS) self.assertEqual(atoken.secret, oa_atoken.secret) # save the acces token so we can do oauth requests self.oa_atoken = oa_atoken
class ApiTestCase(TestCase): fixtures = ['basic.json'] def setUp(self): # Although client.put now exists in Django 1.1, it is unusable for us: # http://code.djangoproject.com/ticket/11371 # So, we override it with our own working version: self.client.put = curry(self.client.post, REQUEST_METHOD='PUT') # TODO: Use standard consumer? self.consumer = Consumer(name='Test Consumer', description='Test', status='accepted') self.consumer.key = "123" self.consumer.secret = "123" self.consumer.save() self.admin_requester = OAuthRequester(self, 'admin', 'admin', self.consumer) self.test1_requester = OAuthRequester(self, 'test1', 'test1', self.consumer) def tearDown(self): self.consumer.delete() def testUser(self): # Test a user with missing fields response = self.client.get('/api/1.0/admin/') self.assertEqual(response.status_code, 200) # TODO: Genericize URL stuff self.assertEqual( json.loads(response.content), { 'user-name': 'admin', 'last-name': '', 'notes-ref': { 'href': 'http://example.com/admin/notes/', 'api-ref': 'http://example.com/api/1.0/admin/notes/' }, 'current-sync-guid': '5ec1f08a-19f1-416a-b086-ff22f6f7c9e8', 'first-name': '', 'latest-sync-revision': -1 }) # Test a user with all fields, with and without auth for client in self.client, self.test1_requester: response = client.get('/api/1.0/test1/') self.assertEqual(response.status_code, 200) self.assertEqual( json.loads(response.content), { 'user-name': 'test1', 'last-name': 'Doe', 'notes-ref': { 'href': 'http://example.com/test1/notes/', 'api-ref': 'http://example.com/api/1.0/test1/notes/' }, 'current-sync-guid': '1886ae92-6c46-43e8-86c0-bb74df89f66c', 'first-name': 'John', 'latest-sync-revision': -1 }) def testUserBadMethods(self): # PUT/POST/DELETE are not allowed # POST and PUT need some dummy data, otherwise piston replies "Bad Request" response = self.admin_requester.put('/api/1.0/admin/', '{ "test" : "test" }') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET') response = self.admin_requester.post('/api/1.0/admin/', '{ "test" : "test" }') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET') response = self.admin_requester.delete('/api/1.0/admin/') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET') def testRootNoAuth(self): # Test w/out auth response = self.client.get('/api/1.0/') self.assertEqual(response.status_code, 200) self.assertEqual( json.loads(response.content), { 'api-version': '1.0', 'oauth_access_token_url': 'http://example.com/oauth/access_token/', 'oauth_authorize_url': 'http://example.com/oauth/authenticate/', 'oauth_request_token_url': 'http://example.com/oauth/request_token/' }) def testRootWithAuth(self): # Test w/ auth (admin user) response = self.admin_requester.get('/api/1.0/') self.assertEqual(response.status_code, 200) self.assertEqual( json.loads(response.content), { 'api-version': '1.0', 'user-ref': { 'href': 'http://example.com/admin/', 'api-ref': 'http://example.com/api/1.0/admin/' }, 'oauth_access_token_url': 'http://example.com/oauth/access_token/', 'oauth_authorize_url': 'http://example.com/oauth/authenticate/', 'oauth_request_token_url': 'http://example.com/oauth/request_token/' }) # Test w/ auth (test1 user) response = self.test1_requester.get('/api/1.0/') self.assertEqual(response.status_code, 200) self.assertEqual( json.loads(response.content), { 'api-version': '1.0', 'user-ref': { 'href': 'http://example.com/test1/', 'api-ref': 'http://example.com/api/1.0/test1/' }, 'oauth_access_token_url': 'http://example.com/oauth/access_token/', 'oauth_authorize_url': 'http://example.com/oauth/authenticate/', 'oauth_request_token_url': 'http://example.com/oauth/request_token/' }) def testRootBadMethods(self): # PUT/POST/DELETE are not allowed # POST and PUT need some dummy data, otherwise piston replies "Bad Request" response = self.admin_requester.put('/api/1.0/', '{ "test" : "test" }') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET') response = self.admin_requester.post('/api/1.0/', '{ "test" : "test" }') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET') response = self.admin_requester.delete('/api/1.0/') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET') def testNotes(self): noteJson = '{"guid": "002e91a2-2e34-4e2d-bf88-21def49a7705",' + \ '"title" :"New Note 6",' + \ '"note-content" :"New Note 6\\nDescribe youre note <b>here</b>.",' + \ '"note-content-version" : 0.2,' + \ '"last-change-date" : "2009-04-19T21:29:23.2197340-07:00",' + \ '"last-metadata-change-date" : "2009-04-19T21:29:23.2197340-07:00",' + \ '"create-date" : "2008-03-06T13:44:46.4342680-08:00",' + \ '"last-sync-revision" : 0,' + \ '"open-on-startup" : false,' + \ '"tags" : ["tag1","tag2"]' + \ '}' notesJson = '{"latest-sync-revision" : 0,' + \ '"note-changes" : [' + noteJson + ']}' full_notes = { "notes": [{ "guid": "002e91a2-2e34-4e2d-bf88-21def49a7705", "ref": { "href": "http://example.com/admin/notes/1/", "api-ref": "http://example.com/api/1.0/admin/notes/1/" }, "title": "New Note 6" }], "latest-sync-revision": 0 } public_notes = {"notes": [], "latest-sync-revision": 0} response = self.admin_requester.put('/api/1.0/admin/notes/', notesJson) self.assertEqual(json.loads(response.content), full_notes) response = self.client.get('/api/1.0/admin/notes/') self.assertEqual(response.status_code, 401) response = self.admin_requester.get('/api/1.0/admin/notes/') self.assertEqual(json.loads(response.content), full_notes) response = self.test1_requester.get('/api/1.0/admin/notes/') self.assertEqual(json.loads(response.content), public_notes) # Make a note public # TODO: Test collections with a mix of public and private notes admin = User.objects.get(username='******') note = Note.objects.get(author=admin, guid="002e91a2-2e34-4e2d-bf88-21def49a7705") note.permissions = 1 note.save() response = self.test1_requester.get('/api/1.0/admin/notes/') self.assertEqual(json.loads(response.content), full_notes) def testNotesBadMethods(self): # POST/DELETE are not allowed # POST and PUT need some dummy data, otherwise piston replies "Bad Request" response = self.admin_requester.post('/api/1.0/admin/notes/', '{ "test" : "test" }') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET, PUT') response = self.admin_requester.delete('/api/1.0/admin/notes/') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET, PUT') def testNote(self): note = { "note-content": "New Note 6\\nDescribe youre note <b>here</b>.", "open-on-startup": False, "last-metadata-change-date": "2010-01-28T18:30:45Z", "tags": ["tag1", "tag2"], "title": "New Note 6", "create-date": "2009-08-28T18:30:45Z", "pinned": False, "last-sync-revision": 0, "last-change-date": "2010-01-28T18:30:45Z", "guid": "002e91a2-2e34-4e2d-bf88-21def49a7705" } # Put testing data into the database notesJson = '{"latest-sync-revision" : 0,' + \ '"note-changes" : [' + json.dumps(note) + ']}' response = self.admin_requester.put('/api/1.0/admin/notes/', notesJson) # Strip the domain from the api-ref noteAPIRef = json.loads(response.content)['notes'][0]['ref']['api-ref'] noteAPIRef = noteAPIRef.partition('/api/')[1] + noteAPIRef.partition( '/api/')[2] response = self.admin_requester.get(noteAPIRef) responseNote = json.loads(response.content)['note'][0] self.assertEqual(response.status_code, 200) self.assertEqual(responseNote, note) def testNoteBadMethods(self): # PUT/POST/DELETE are not allowed # POST and PUT need some dummy data, otherwise piston replies "Bad Request" response = self.admin_requester.put('/api/1.0/admin/notes/1/', '{ "test" : "test" }') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET') response = self.admin_requester.post('/api/1.0/admin/notes/1/', '{ "test" : "test" }') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET') response = self.admin_requester.delete('/api/1.0/admin/notes/1/') self.assertEqual(response.status_code, 405) self.assertEqual(response['Allow'], 'GET')