def test_delete_queue_item(self): """ Performs DELETE request to queue id 2""" client = TestApiClient() response = client.delete('/api/queue/2/', data={'format': 'json'}) # 204 == Action Performed -> No Data self.assertEqual(response.status_code, 204)
class JobTest(ResourceTestCase): def setUp(self): super(JobTest, self).setUp() self.client = TestApiClient() self.endpoint = '/api/v1/jobs/' self.format = 'json' # Create one user self.user = User(username="******") self.user.save() # Create on token self.token = UserToken(user=self.user) self.token.save() # create a job self.job = Job(user=self.user, application=Application.objects.all()[0]) self.job.save() def test_get_job_list(self): url = "%s?token=%s" % (self.endpoint, self.token.token) request = self.client.get(url, self.format) self.assertValidJSONResponse(request) def test_get_job_detail(self): url = "%s%d/?token=%s" % (self.endpoint, self.job.id, self.token.token) request = self.client.get(url, self.format) self.assertValidJSONResponse(request) def test_post_job(self): data = {"application" : "/api/v1/apps/1/"} url = "%s?token=%s" % (self.endpoint, self.token.token) self.assertHttpCreated(self.client.post(url, self.format, data=data)) def test_patch_job(self): job = Job(user=self.user, application=Application.objects.all()[0]) job.save() data = {"progress":"50"} url = "%s%d/?token=%s" % (self.endpoint, job.id, self.token.token) resp = self.client.patch(url, self.format, data=data) self.assertHttpAccepted(resp) def test_delete_job(self): job = Job(user=self.user, application=Application.objects.all()[0]) job.save() url = "%s%d/?token=%s" % (self.endpoint, job.id, self.token.token) self.assertHttpAccepted(self.client.delete(url, self.format))
def mock_request(obj, method, url, **kwargs): client = TestApiClient() authentication = 'Basic %s' % base64.b64encode(':'.join([ get_setting('SUPERUSER_USERNAME', None), get_setting('SUPERUSER_PASSWORD', None), ])) if method == 'GET': data = kwargs.get('params', {}) djresponse = client.get(url, data=data, authentication=authentication) elif method == 'POST': data = json.loads(kwargs.get('data', '{}')) djresponse = client.post(url, data=data, authentication=authentication) elif method == 'PUT': data = json.loads(kwargs.get('data', '{}')) djresponse = client.put(url, data=data, authentication=authentication) elif method == 'PATCH': data = json.loads(kwargs.get('data', '{}')) djresponse = client.patch(url, data=data, authentication=authentication) elif method == 'DELETE': data = kwargs.get('params', {}) djresponse = client.delete(url, data=data, authentication=authentication) # convert django.http.HttpResponse to requests.models.Response response = requests.models.Response() response.status_code = djresponse.status_code response.headers = {} try: response.headers['content-type'] = djresponse['content-type'] response.headers['location'] = djresponse['location'] except: pass response.encoding = requests.utils.get_encoding_from_headers(response.headers) response._content = djresponse.content return response
class ProjectResourceTest(ResourceTestCase): fixtures = ['group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project.json', 'profile.json', 'oauth_client.json', 'oauth_token.json'] def setUp(self): self.api_client = TestApiClient() self.token = 'd3d81362dd46f415f17e15211875e1d38bf75898' self.category = Category(name='New category') self.category.save() self.post_data = {'title': 'My project', 'description': 'my description', 'category': self.category} self.project_id = 3 self.open_project_id = 1 self.open_detail_url = '/api/v1/project/{0}/'.format(self.open_project_id) self.detail_url = '/api/v1/project/{0}/'.format(self.project_id) self.list_url = '/api/v1/project/' self.serializer = Serializer() def get_credentials(self, type_user=None): if type_user is 'user': self.api_client.client.login(email='*****@*****.**', password='******') else: self.api_client.client.login(email='*****@*****.**', password='******') def test_post_list(self): self.get_credentials() self.assertIn('_auth_user_id', self.api_client.client.session) self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) self.assertEqual(Project.objects.count(), 2) resp = self.api_client.post(self.list_url, format='json', data=self.post_data) self.assertHttpCreated(resp) self.assertEqual(Project.objects.count(), 3) def test_get_list_unauthorized(self): self.assertHttpUnauthorized(self.api_client.get(self.list_url, format='json')) def test_get_list_unauthorized_open(self): resp = self.api_client.get('?'.join([self.list_url, 'open=true']), format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 1) def test_get_list(self): self.get_credentials() resp = self.api_client.get(self.list_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 2) def test_get_list_oauth(self): resp = self.api_client.client.get(self.list_url, format='json', **{'HTTP_AUTHORIZATION': 'OAuth %s' % self.token}) self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 2) def test_get_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.get(self.detail_url, format='json')) def test_get_detail(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['title'], 'Test Project') # FIXME Tastypie is not calling authorization before obj_create call # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', # data=self.post_data)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.put(self.detail_url, format='json', data={})) @mock.patch('wevolve.projects.api.update_drive_folder') def test_put_detail(self, method): self.get_credentials() original_data = json.loads(self.api_client.get(self.detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Post' self.assertEqual(Project.objects.count(), 2) self.assertHttpAccepted(self.api_client.put(self.detail_url, format='json', data=new_data)) self.assertEqual(Project.objects.count(), 2) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Project.objects.count(), 2) resp = self.api_client.delete(self.detail_url, format='json') self.assertHttpAccepted(resp) self.assertEqual(Project.objects.count(), 1) def test_delete_detail_with_user_perm(self): self.get_credentials('user') self.assertHttpUnauthorized(self.api_client.delete(self.detail_url, format='json')) def test_get_detail_open(self): resp = self.api_client.get(self.open_detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['title'], 'OPEN project') def test_put_detail_open(self): original_data = json.loads(self.api_client.get(self.open_detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Project Open' self.assertEqual(Project.objects.count(), 2) resp = self.api_client.put(self.open_detail_url, format='json', data=new_data) self.assertHttpUnauthorized(resp) def test_delete_detail_open(self): self.assertEqual(Project.objects.count(), 2) resp = self.api_client.delete(self.open_detail_url, format='json') self.assertHttpUnauthorized(resp)
class TaskResourceTest(ResourceTestCase): fixtures = ['group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json', 'task.json'] def setUp(self): self.api_client = TestApiClient() self.task_id = 1 self.project_part_id = 1 self.task = {'description': 'new Task', 'project_part': {'pk': self.project_part_id}, 'flag_finished': 0, 'weight': 20 } self.detail_url = '/api/v1/task/{0}/'.format(self.task_id) self.project_part_query = '='.join(['?project_part', str(self.project_part_id)]) self.list_url = '/api/v1/task/' self.serializer = Serializer() def get_credentials(self): result = self.api_client.client.login(email='*****@*****.**', password='******') def test_post_list(self): self.get_credentials() self.assertIn('_auth_user_id', self.api_client.client.session) self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) self.assertEqual(Task.objects.count(), 2) resp = self.api_client.post(self.list_url, format='json', data=self.task) self.assertHttpCreated(resp) self.assertEqual(Task.objects.count(), 3) def test_get_list_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.get(''.join([self.list_url, self.project_part_query]), format='json')) def test_get_list_json(self): self.get_credentials() resp = self.api_client.get(''.join([self.list_url, self.project_part_query]), format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 2) def test_get_detail_unauthenticated(self): resp = self.api_client.get(self.detail_url, format='json') self.assertHttpUnauthorized(resp) def test_get_detail_json(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['description'], 'new task') # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', # data=self.task)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.put(self.detail_url, format='json', data={})) def test_put_detail(self): self.get_credentials() original_data = json.loads(self.api_client.get(self.detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Task' self.assertEqual(Task.objects.count(), 2) self.assertHttpAccepted(self.api_client.put(self.detail_url, format='json', data=new_data)) self.assertEqual(Task.objects.count(), 2) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Task.objects.count(), 2) self.assertHttpAccepted(self.api_client.delete(self.detail_url, format='json')) self.assertEqual(Task.objects.count(), 1)
class TestCampaignResource(ResourceTestCase): def setUp(self): # Tastypie stuff super(TestCampaignResource, self).setUp() self.bob_api_client = TestApiClient() self.bill_api_client = TestApiClient() self.anon_api_client = TestApiClient() # Create a user bob. self.user_bob_username = "******" self.user_bob_password = "******" self.user_bob = User.objects.create_user(self.user_bob_username, "*****@*****.**", self.user_bob_password) # Create a user bob. self.user_bill_username = "******" self.user_bill_password = "******" self.user_bill = User.objects.create_user( self.user_bill_username, "*****@*****.**", self.user_bill_password ) self.bob_api_client.client.login(username="******", password="******") self.bill_api_client.client.login(username="******", password="******") # assign users to the Public group public_group, created = Group.objects.get_or_create(name="Public") self.user_bob.groups.add(public_group) self.user_bill.groups.add(public_group) guardian.utils.get_anonymous_user().groups.add(public_group) # make a couple of campaigns and save self.campaign_bobs = mommy.make_one("catamidb.Campaign") self.campaign_bills = mommy.make_one("catamidb.Campaign") # assign this one to bob authorization.apply_campaign_permissions(self.user_bob, self.campaign_bobs) # assign this one to bill authorization.apply_campaign_permissions(self.user_bill, self.campaign_bills) # the API url for campaigns self.campaign_url = "/api/dev/campaign/" # some post data for testing campaign creation self.post_data = { "short_name": "Blah", "description": "Blah", "associated_researchers": "Blah", "associated_publications": "Blah", "associated_research_grant": "Blah", "date_start": "2012-05-01", "date_end": "2012-05-01", "contact_person": "Blah", } # can only do GET at this stage def test_campaign_operations_disabled(self): # test that we are unauthorized to create self.assertHttpUnauthorized(self.anon_api_client.post(self.campaign_url, format="json", data=self.post_data)) # test that we can NOT modify self.assertHttpMethodNotAllowed( self.anon_api_client.put(self.campaign_url + self.campaign_bobs.id.__str__() + "/", format="json", data={}) ) # test that we can NOT delete self.assertHttpMethodNotAllowed( self.anon_api_client.delete(self.campaign_url + self.campaign_bobs.id.__str__() + "/", format="json") ) # test that we can NOT modify authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.put(self.campaign_url + self.campaign_bobs.id.__str__() + "/", format="json", data={}) ) # test that we can NOT delete authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.delete(self.campaign_url + self.campaign_bobs.id.__str__() + "/", format="json") ) # test can get a list of campaigns authorised def test_campaigns_operations_as_authorised_users(self): # create a campaign that only bill can see bills_campaign = mommy.make_one("catamidb.Campaign") assign("view_campaign", self.user_bill, bills_campaign) # check that bill can see via the API response = self.bill_api_client.get(self.campaign_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 3) # check that bill can get to the object itself response = self.bill_api_client.get(self.campaign_url + bills_campaign.id.__str__() + "/", format="json") self.assertValidJSONResponse(response) # check that bob can not see - now we know tastypie API has correct # permission validation response = self.bob_api_client.get(self.campaign_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 2) # check bob can NOT get to the hidden object response = self.bob_api_client.get(self.campaign_url + bills_campaign.id.__str__() + "/", format="json") self.assertHttpUnauthorized(response) # check that anonymous can see public ones as well response = self.anon_api_client.get(self.campaign_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 2) # check anonymous can NOT get to the hidden object response = self.anon_api_client.get(self.campaign_url + bills_campaign.id.__str__() + "/", format="json") self.assertHttpUnauthorized(response) # create via the API auth_post_data = { "short_name": "AuthBlah", "description": "AuthBlah", "associated_researchers": "AuthBlah", "associated_publications": "AuthBlah", "associated_research_grant": "AuthBlah", "date_start": "2012-05-01", "date_end": "2012-05-01", "contact_person": "AuthBlah", } # test that we can create authenticated self.assertHttpCreated(self.bob_api_client.post(self.campaign_url, format="json", data=auth_post_data)) # check that ones we created via API are there response = self.bill_api_client.get(self.campaign_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 4) # check public can see it too response = self.anon_api_client.get(self.campaign_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 3)
class TestCameraResource(ResourceTestCase): def setUp(self): # Tastypie stuff super(TestCameraResource, self).setUp() self.bob_api_client = TestApiClient() self.bill_api_client = TestApiClient() self.anon_api_client = TestApiClient() # Create a user bob. self.user_bob_username = "******" self.user_bob_password = "******" self.user_bob = User.objects.create_user(self.user_bob_username, "*****@*****.**", self.user_bob_password) # Create a user bob. self.user_bill_username = "******" self.user_bill_password = "******" self.user_bill = User.objects.create_user( self.user_bill_username, "*****@*****.**", self.user_bill_password ) self.bob_api_client.client.login(username="******", password="******") self.bill_api_client.client.login(username="******", password="******") # assign users to the Public group public_group, created = Group.objects.get_or_create(name="Public") self.user_bob.groups.add(public_group) self.user_bill.groups.add(public_group) guardian.utils.get_anonymous_user().groups.add(public_group) # make a couple of campaigns and save self.campaign_bobs = mommy.make_one("catamidb.Campaign", id=1) self.campaign_bills = mommy.make_one("catamidb.Campaign", id=2) # make a deployments self.deployment_bobs = mommy.make_recipe("catamidb.Deployment1", id=1, campaign=self.campaign_bobs) self.deployment_bills = mommy.make_recipe("catamidb.Deployment2", id=2, campaign=self.campaign_bills) # make images self.image_bobs = mommy.make_recipe("catamidb.Image1", id=1, deployment=self.deployment_bobs) self.image_bills = mommy.make_recipe("catamidb.Image2", id=2, deployment=self.deployment_bills) # make cameras self.camera_bobs = mommy.make_one("catamidb.Camera", id=1, image=self.image_bobs) self.camera_bills = mommy.make_one("catamidb.Camera", id=2, image=self.image_bills) # assign this one to bob authorization.apply_campaign_permissions(self.user_bob, self.campaign_bobs) # assign this one to bill authorization.apply_campaign_permissions(self.user_bill, self.campaign_bills) # the API url for deployments self.camera_url = "/api/dev/camera/" # some post data for testing camera creation self.post_data = [] def test_camera_operations_disabled(self): # test that we can NOT create self.assertHttpUnauthorized(self.anon_api_client.post(self.camera_url, format="json", data=self.post_data)) # test that we can NOT modify self.assertHttpUnauthorized( self.anon_api_client.put(self.camera_url + self.deployment_bobs.id.__str__() + "/", format="json", data={}) ) # test that we can NOT delete self.assertHttpMethodNotAllowed( self.anon_api_client.delete(self.camera_url + self.deployment_bobs.id.__str__() + "/", format="json") ) # test that we can NOT modify authenticated self.assertHttpUnauthorized( self.bob_api_client.put(self.camera_url + self.deployment_bobs.id.__str__() + "/", format="json", data={}) ) # test that we can NOT delete authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.delete(self.camera_url + self.deployment_bobs.id.__str__() + "/", format="json") ) def test_camera_operations_as_authorised_users(self): # create a campaign & deployment that ONLY bill can see bills_campaign = mommy.make_one("catamidb.Campaign", id=3, short_name="cp_3") bills_deployment = mommy.make_recipe("catamidb.Deployment3", id=3, campaign=bills_campaign) assign("view_campaign", self.user_bill, bills_campaign) # make exclusive image for bill and assign this image to camera to image self.image_bill_exc = mommy.make_recipe( "catamidb.Image3", id=3, deployment=bills_deployment ) # IMPORTANT camera checks campaign which has reference to deployment. Image has reference to deployment and camera # make exclusive camera for bill self.camera_bill_exc = mommy.make_one("catamidb.Camera", id=3, image=self.image_bill_exc) # check that bill can see via the API response = self.bill_api_client.get(self.camera_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 3) # check that bill can get to the object itself response = self.bill_api_client.get(self.camera_url + "3/", format="json") self.assertValidJSONResponse(response) # check that bob can not see - now we know tastypie API has correct # permission validation response = self.bob_api_client.get(self.camera_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 2) # check bob can NOT get to the hidden object response = self.bob_api_client.get(self.camera_url + "3/", format="json") self.assertHttpUnauthorized(response) # check that anonymous can see public ones as well response = self.anon_api_client.get(self.camera_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 2) # check anonymous can NOT get to the hidden object response = self.anon_api_client.get(self.camera_url + "3/", format="json") self.assertHttpUnauthorized(response)
class DocumentResourceTest(ResourceTestCase): fixtures = [ 'group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json', 'document.json' ] def setUp(self): self.api_client = TestApiClient() self.project_part_id = 1 self.document_data = { 'text': 'My document', 'project_part': { 'pk': self.project_part_id } } self.document_id = 1 self.project_part_query = '='.join( ['?project_part', str(self.project_part_id)]) self.detail_url = '/api/v1/document/{0}/'.format(self.document_id) self.list_url = '/api/v1/document/' self.serializer = Serializer() def get_credentials(self): result = self.api_client.client.login(email='*****@*****.**', password='******') def test_document_list(self): self.get_credentials() self.assertIn('_auth_user_id', self.api_client.client.session) self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) self.assertEqual(Document.objects.count(), 2) self.assertHttpCreated( self.api_client.post(self.list_url, format='json', data=self.document_data)) self.assertEqual(Document.objects.count(), 3) def test_get_list_unauthorzied(self): self.assertHttpUnauthorized( self.api_client.get(self.list_url, format='json')) def test_get_list(self): self.get_credentials() resp = self.api_client.get(''.join( [self.list_url, self.project_part_query]), format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 1) def test_get_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.get(self.detail_url, format='json')) def test_get_detail(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['text'], '<h1>hola</h1>') # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', # data=self.document_data)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.put(self.detail_url, format='json', data={'text': 'data'})) def test_put_detail(self): self.get_credentials() original_data = json.loads( self.api_client.get(self.detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Document' self.assertEqual(Document.objects.count(), 2) self.assertHttpAccepted( self.api_client.put(self.detail_url, format='json', data=new_data)) # Make sure the count hasn't changed & we did an update. self.assertEqual(Document.objects.count(), 2) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Document.objects.count(), 2) resp = self.api_client.delete(self.detail_url, format='json') self.assertHttpAccepted(resp) self.assertEqual(Document.objects.count(), 1)
class PostResourceTest(ResourceTestCase): fixtures = [ 'group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json', 'post.json', 'comment.json' ] def setUp(self): # Generic self.api_client = TestApiClient() self.serializer = Serializer() # API List data self.list_url = '/api/v1/post/' # API requests data self.project_part_id = 1 self.post_id = 1 self.detail_url = '/api/v1/post/{0}/'.format(self.post_id) self.project_part_query = '='.join( ['?project_part', str(self.project_part_id)]) self.post_data = { 'content': 'My post', 'project_part': { 'pk': self.project_part_id } } # Open API request data self.open_project_part_id = 2 self.open_post_id = 2 self.open_detail_url = '/api/v1/post/{0}/'.format(self.open_post_id) self.open_project_part_query = '='.join( ['?project_part', str(self.open_project_part_id)]) self.open_post_data = { 'content': 'My post', 'project_part': { 'pk': self.open_project_part_id } } def get_credentials(self): result = self.api_client.client.login(email='*****@*****.**', password='******') def test_post_list(self): self.get_credentials() self.assertIn('_auth_user_id', self.api_client.client.session) self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) self.assertEqual(Post.objects.count(), 2) self.assertHttpCreated( self.api_client.post(self.list_url, format='json', data=self.post_data)) self.assertEqual(Post.objects.count(), 3) def test_get_list_unauthorzied(self): self.assertHttpUnauthorized( self.api_client.get(self.list_url, format='json')) def test_get_list(self): self.get_credentials() resp = self.api_client.get(''.join( [self.list_url, self.project_part_query]), format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 1) def test_get_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.get(self.detail_url, format='json')) def test_get_detail(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['content'], 'hola') # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', # data=self.post_data)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.put(self.detail_url, format='json', data={})) def test_put_detail(self): self.get_credentials() original_data = json.loads( self.api_client.get(self.detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Post' self.assertEqual(Post.objects.count(), 2) self.assertHttpAccepted( self.api_client.put(self.detail_url, format='json', data=new_data)) # Make sure the count hasn't changed & we did an update. self.assertEqual(Post.objects.count(), 2) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Post.objects.count(), 2) resp = self.api_client.delete(self.detail_url, format='json') self.assertHttpAccepted(resp) self.assertEqual(Post.objects.count(), 1) # Open Projects # FIXME It fails because tastypie is not accessing authorization # before calling obj_create # def test_post_list_open(self): # self.assertEqual(Post.objects.count(), 2) # resp = self.api_client.post(self.list_url, # format='json', # data=self.open_post_data) # self.assertHttpUnauthorized(resp) def test_get_detail_open(self): resp = self.api_client.get(self.open_detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['content'], 'hola') def test_delete_detail_open(self): self.assertEqual(Post.objects.count(), 2) resp = self.api_client.delete(self.open_detail_url, format='json') self.assertHttpUnauthorized(resp) def test_put_detail_open(self): original_data = json.loads( self.api_client.get(self.open_detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Post' self.assertEqual(Post.objects.count(), 2) resp = self.api_client.put(self.open_detail_url, format='json', data=new_data) self.assertHttpUnauthorized(resp)
class TestCampaignResource(ResourceTestCase): def setUp(self): #Tastypie stuff super(TestCampaignResource, self).setUp() self.bob_api_client = TestApiClient() self.bill_api_client = TestApiClient() self.anon_api_client = TestApiClient() # Create a user bob. self.user_bob_username = '******' self.user_bob_password = '******' self.user_bob = User.objects.create_user(self.user_bob_username, '*****@*****.**', self.user_bob_password) # Create a user bob. self.user_bill_username = '******' self.user_bill_password = '******' self.user_bill = User.objects.create_user(self.user_bill_username, '*****@*****.**', self.user_bill_password) self.bob_api_client.client.login(username='******', password='******') self.bill_api_client.client.login(username='******', password='******') #assign users to the Public group public_group, created = Group.objects.get_or_create(name='Public') self.user_bob.groups.add(public_group) self.user_bill.groups.add(public_group) guardian.utils.get_anonymous_user().groups.add(public_group) #make a couple of campaigns and save self.campaign_bobs = mommy.make_one('catamidb.Campaign', id=1) self.campaign_bills = mommy.make_one('catamidb.Campaign', id=2) #assign this one to bob authorization.apply_campaign_permissions( self.user_bob, self.campaign_bobs) #assign this one to bill authorization.apply_campaign_permissions( self.user_bill, self.campaign_bills) #the API url for campaigns self.campaign_url = '/api/dev/campaign/' #some post data for testing campaign creation self.post_data = { 'short_name': 'Blah', 'description': 'Blah', 'associated_researchers': 'Blah', 'associated_publications': 'Blah', 'associated_research_grant': 'Blah', 'date_start': '2012-05-01', 'date_end': '2012-05-01', 'contact_person': 'Blah', } # can only do GET at this stage def test_campaign_operations_disabled(self): # test that we can NOT create self.assertHttpMethodNotAllowed( self.anon_api_client.post(self.campaign_url, format='json', data=self.post_data)) # test that we can NOT modify self.assertHttpMethodNotAllowed( self.anon_api_client.put( self.campaign_url + self.campaign_bobs.id.__str__() + "/", format='json', data={}) ) # test that we can NOT delete self.assertHttpMethodNotAllowed( self.anon_api_client.delete( self.campaign_url + self.campaign_bobs.id.__str__() + "/", format='json') ) # test that we can NOT create authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.post(self.campaign_url, format='json', data=self.post_data) ) # test that we can NOT modify authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.put( self.campaign_url + self.campaign_bobs.id.__str__() + "/", format='json', data={}) ) # test that we can NOT delete authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.delete( self.campaign_url + self.campaign_bobs.id.__str__() + "/", format='json')) #test can get a list of campaigns authorised def test_campaigns_operations_as_authorised_users(self): # create a campaign that only bill can see bills_campaign = mommy.make_one('catamidb.Campaign', id=3) assign('view_campaign', self.user_bill, bills_campaign) # check that bill can see via the API response = self.bill_api_client.get(self.campaign_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)['objects']), 3) # check that bill can get to the object itself response = self.bill_api_client.get(self.campaign_url + "3/", format='json') self.assertValidJSONResponse(response) # check that bob can not see - now we know tastypie API has correct # permission validation response = self.bob_api_client.get(self.campaign_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)['objects']), 2) # check bob can NOT get to the hidden object response = self.bob_api_client.get(self.campaign_url + "3/", format='json') self.assertHttpUnauthorized(response) #check that anonymous can see public ones as well response = self.anon_api_client.get(self.campaign_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)['objects']), 2) #check anonymous can NOT get to the hidden object response = self.anon_api_client.get(self.campaign_url + "3/", format='json') self.assertHttpUnauthorized(response)
class ApiResourceTestCaseMixin(SimpleTestCase): # TODO: Using the regular ROOT_URLCONF avoids a problem where failing tests print useless error messages, # because the 500.html error template includes a {% url %} lookup that isn't included in api.urls. # There could be a better way to handle this. # url_base = "/v1" url_base = "/api/v1" server_domain = "perma.dev" server_port = 8999 serve_files = [] rejected_status_code = 401 # Unauthorized # reduce wait times for testing perma.tasks.ROBOTS_TXT_TIMEOUT = perma.tasks.AFTER_LOAD_TIMEOUT = 1 @classmethod def setUpClass(cls): super(ApiResourceTestCaseMixin, cls).setUpClass() if len(cls.serve_files): cls.start_server() @classmethod def tearDownClass(cls): if getattr(cls, "_server_process", None): cls.kill_server() def setUp(self): super(ApiResourceTestCaseMixin, self).setUp() self.api_client = TestApiClient(serializer=MultipartSerializer()) self._media_org = settings.MEDIA_ROOT self._media_tmp = settings.MEDIA_ROOT = tempfile.mkdtemp() try: self.list_url = "{0}/{1}".format(self.url_base, self.resource.Meta.resource_name) except: pass def tearDown(self): settings.MEDIA_ROOT = self._media_org shutil.rmtree(self._media_tmp) def get_credentials(self, user=None): user = user or self.user return "ApiKey %s" % user.api_key.key @classmethod def start_server(cls): """ Set up a server with some known files to run captures against. Example: with run_server_in_temp_folder([ 'test/assets/test.html', 'test/assets/test.pdf', ['test/assets/test.html', 'some_other_url.html']): assert(requests.get("http://localhost/test.html") == contents_of_file("test.html")) assert(requests.get("http://localhost/some_other_url.html") == contents_of_file("test.html")) """ assert socket.gethostbyname(cls.server_domain) in ( '0.0.0.0', '127.0.0.1' ), "Please add `127.0.0.1 " + cls.server_domain + "` to your hosts file before running this test." # Run in temp dir. # We have to (implicitly) cwd to this so SimpleHTTPRequestHandler serves the files for us. cwd = os.getcwd() cls._server_tmp = tempfile.mkdtemp() os.chdir(cls._server_tmp) # Copy over files to current temp dir, stripping paths. for source_file in cls.serve_files: # handle single strings if isinstance(source_file, basestring): target_url = os.path.basename(source_file) # handle tuple like (source_file, target_url) else: source_file, target_url = source_file copy_file_or_dir(os.path.join(cwd, source_file), target_url) # start server cls._httpd = TestHTTPServer(('', cls.server_port), SimpleHTTPRequestHandler) cls._httpd._BaseServer__is_shut_down = multiprocessing.Event() cls._server_process = Process(target=cls._httpd.serve_forever) cls._server_process.start() # once the server is started, we can return to our working dir # and the server thread will continue to server from the tmp dir os.chdir(cwd) return cls._server_process @classmethod def kill_server(cls): # If you don't close the server before terminating # the thread the port isn't freed up. cls._httpd.server_close() cls._server_process.terminate() shutil.rmtree(cls._server_tmp) @contextmanager def serve_file(self, src): if not getattr(self.__class__, "_server_process", None): self.__class__.start_server() dst = os.path.join(self._server_tmp, os.path.basename(src)) try: copy_file_or_dir(src, dst) yield finally: os.remove(dst) @cached_property def server_url(self): return "http://" + self.server_domain + ":" + str(self.server_port) @contextmanager def header_timeout(self, timeout): prev_t = models.HEADER_CHECK_TIMEOUT try: models.HEADER_CHECK_TIMEOUT = timeout yield finally: models.HEADER_CHECK_TIMEOUT = prev_t def assertValidJSONResponse(self, resp): # Modified from tastypie to allow 201's as well # https://github.com/toastdriven/django-tastypie/blob/master/tastypie/test.py#L448 try: self.assertHttpOK(resp) except AssertionError: self.assertHttpCreated(resp) self.assertTrue(resp['Content-Type'].startswith('application/json')) self.assertValidJSON(force_text(resp.content)) def detail_url(self, obj): return "{0}/{1}".format(self.list_url, obj.pk) def get_req_kwargs(self, kwargs): req_kwargs = {} if kwargs.get('format', None): req_kwargs['format'] = kwargs['format'] if kwargs.get('user', None): req_kwargs['authentication'] = self.get_credentials(kwargs['user']) return req_kwargs def successful_get(self, url, data=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) resp = self.api_client.get(url, data=data, **req_kwargs) self.assertHttpOK(resp) self.assertValidJSONResponse(resp) data = self.deserialize(resp) if kwargs.get('fields', None): self.assertKeys(data, kwargs['fields']) if kwargs.get('count', None): self.assertEqual(len(data['objects']), kwargs['count']) return data def rejected_get(self, url, expected_status_code=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) resp = self.api_client.get(url, **req_kwargs) self.assertEqual(resp.status_code, expected_status_code or self.rejected_status_code) return resp def successful_post(self, url, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) count = self.resource._meta.queryset.count() resp = self.api_client.post(url, data=kwargs['data'], **req_kwargs) self.assertHttpCreated(resp) self.assertValidJSONResponse(resp) # Make sure the count changed self.assertEqual(self.resource._meta.queryset.count(), count + 1) return self.deserialize(resp) def rejected_post(self, url, expected_status_code=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) count = self.resource._meta.queryset.count() resp = self.api_client.post(url, data=kwargs['data'], **req_kwargs) self.assertEqual(resp.status_code, expected_status_code or self.rejected_status_code) self.assertEqual(self.resource._meta.queryset.count(), count) return resp def successful_put(self, url, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) if kwargs.get('data', None): req_kwargs['data'] = kwargs['data'] count = self.resource._meta.queryset.count() resp = self.api_client.put(url, **req_kwargs) self.assertHttpAccepted(resp) # Make sure the count hasn't changed self.assertEqual(self.resource._meta.queryset.count(), count) def rejected_put(self, url, expected_status_code=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) if kwargs.get('data', None): req_kwargs['data'] = kwargs['data'] count = self.resource._meta.queryset.count() resp = self.api_client.put(url, **req_kwargs) self.assertEqual(resp.status_code, expected_status_code or self.rejected_status_code) # Make sure the count hasn't changed self.assertEqual(self.resource._meta.queryset.count(), count) def successful_patch(self, url, check_results=True, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) new_data = kwargs['data'] if check_results: # Fetch the existing data for comparison. resp = self.api_client.get(url, **req_kwargs) self.assertHttpOK(resp) self.assertValidJSONResponse(resp) old_data = self.deserialize(resp) count = self.resource._meta.queryset.count() patch_resp = self.api_client.patch(url, data=new_data, **req_kwargs) self.assertHttpAccepted(patch_resp) # Make sure the count hasn't changed & we did an update. self.assertEqual(self.resource._meta.queryset.count(), count) if check_results: fresh_data = self.deserialize( self.api_client.get(url, **req_kwargs)) for attr in kwargs['data'].keys(): try: # Make sure the data actually changed self.assertNotEqual(fresh_data[attr], old_data[attr]) # Make sure the data changed to what we specified self.assertEqual(fresh_data[attr], new_data[attr]) except AssertionError: # If we specified a nested ID, we'll be getting back an object if str(new_data[attr]).isdigit() and isinstance( fresh_data[attr], dict): self.assertEqual(new_data[attr], fresh_data[attr]['id']) else: raise except KeyError: pass return fresh_data else: return self.deserialize(patch_resp) def rejected_patch(self, url, expected_status_code=None, expected_data=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) old_data = self.deserialize(self.api_client.get(url, **req_kwargs)) new_data = kwargs['data'] count = self.resource._meta.queryset.count() resp = self.api_client.patch(url, data=new_data, **req_kwargs) self.assertEqual(resp.status_code, expected_status_code or self.rejected_status_code) if expected_data: self.assertDictEqual(self.deserialize(resp), expected_data) self.assertEqual(self.resource._meta.queryset.count(), count) self.assertEqual( self.deserialize(self.api_client.get(url, **req_kwargs)), old_data) return resp def successful_delete(self, url, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) count = self.resource._meta.queryset.count() self.assertHttpOK(self.api_client.get(url, **req_kwargs)) self.assertHttpAccepted(self.api_client.delete(url, **req_kwargs)) self.assertEqual(self.resource._meta.queryset.count(), count - 1) self.assertHttpNotFound(self.api_client.get(url, **req_kwargs)) def rejected_delete(self, url, expected_status_code=None, expected_data=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) count = self.resource._meta.queryset.count() delete_resp = self.api_client.delete(url, **req_kwargs) self.assertEqual(delete_resp.status_code, expected_status_code or self.rejected_status_code) if expected_data: self.assertDictEqual(self.deserialize(delete_resp), expected_data) self.assertEqual(self.resource._meta.queryset.count(), count) resp = self.api_client.get(url, **req_kwargs) try: # If the user doesn't have access, that's okay - # we were testing delete from an unauthorized user self.assertHttpUnauthorized(resp) except AssertionError: # Check for OK last so that this is the assertion # that shows up as the failure if it doesn't pass self.assertHttpOK(resp) return delete_resp
class ProjectPartResourceTest(ResourceTestCase): fixtures = [ 'group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json' ] def setUp(self): self.api_client = TestApiClient() self.post_data = { 'title': 'new part', 'project_id': { 'pk': 3 }, 'project_part_id': { 'pk': 1 }, 'order': 0, 'weight': 20 } self.project_part_id = 1 self.open_project_part_id = 2 self.detail_base_url = '/api/v1/project_part/{0}/' self.open_detail_url = self.detail_base_url.format( self.open_project_part_id) self.detail_url = self.detail_base_url.format(self.project_part_id) self.list_url = '/api/v1/project_part/' self.serializer = Serializer() def get_credentials(self): self.api_client.client.login(email='*****@*****.**', password='******') def test_get_list_unauthorized(self): self.assertHttpUnauthorized( self.api_client.get(self.list_url, format='json')) def test_get_list(self): self.get_credentials() self.assertHttpUnauthorized( self.api_client.get(self.list_url, format='json')) def test_get_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.get(self.detail_url, format='json')) def test_get_detail(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['title'], 'Project Part 1') # FIXME Idem from above # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', data=self.post_data)) def test_post_list(self): self.get_credentials() self.assertEqual(ProjectPart.objects.count(), 2) resp = self.api_client.post(self.list_url, format='json', data=self.post_data) self.assertHttpCreated(resp) self.assertEqual(ProjectPart.objects.count(), 3) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.put(self.detail_url, format='json', data={})) @mock.patch('wevolve.projects.api.update_drive_folder') def test_put_detail(self, method): self.get_credentials() content = self.api_client.get(self.detail_url, format='json').content original_data = json.loads(content) new_data = original_data.copy() new_data['title'] = 'Updated First Post' self.assertEqual(ProjectPart.objects.count(), 2) resp = self.api_client.put(self.detail_url, format='json', data=new_data) self.assertHttpAccepted(resp) self.assertEqual(ProjectPart.objects.count(), 2) self.assertEqual( ProjectPart.objects.get(pk=self.project_part_id).title, 'Updated First Post') def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(ProjectPart.objects.count(), 2) self.assertHttpAccepted( self.api_client.delete(self.detail_url, format='json')) self.assertEqual(ProjectPart.objects.count(), 1) # Project parts in open projects def test_get_detail_open(self): resp = self.api_client.get(self.open_detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['title'], 'Project Part 2') def test_put_detail_open(self): content = self.api_client.get(self.open_detail_url, format='json').content original_data = json.loads(content) new_data = original_data.copy() new_data['title'] = 'Updated First Post' self.assertEqual(ProjectPart.objects.count(), 2) resp = self.api_client.put(self.detail_url, format='json', data=new_data) self.assertHttpUnauthorized(resp) def test_delete_detail_open(self): self.assertEqual(ProjectPart.objects.count(), 2) resp = self.api_client.delete(self.open_detail_url, format='json') self.assertHttpUnauthorized(resp)
class DepartmentResourceTest(ResourceTestCaseMixin, TestCase): def setUp(self): super(DepartmentResourceTest, self).setUp() # Define new account test and create it. register_user(self) # Define variable to use requests properly self.client = TestApiClient() # Create and save a new department self.department_1 = DepartmentFactory.create() # Define api url for get and post method self.api_url = '/api/v1/department/' # Define data for POST method self.post_data = {'name': 'test department'} def tearDown(self): Department.objects.all().delete() def get_credentials(self): return self.create_basic(username=self.username, password=self.password) def test_get_list_unauthenticated(self): self.assertHttpUnauthorized( self.client.get(self.api_url, format='json')) def test_get_list_json(self): resp = self.client.get(self.api_url, format='json', authentication=self.get_credentials()) self.assertValidJSONResponse(resp) def test_get_list(self): get = self.client.get(self.api_url, format='json', authentication=self.get_credentials()) self.assertHttpOK(get) self.assertEqual(Department.objects.count(), 1) def test_post_single(self): self.assertEqual(Department.objects.count(), 1) # Test number department before post post = self.client.post(self.api_url, format='json', data=self.post_data, authentication=self.get_credentials()) self.assertHttpCreated(post) self.assertEqual(Department.objects.count(), 2) # Test number department after post def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized( self.client.delete(self.api_url, format='json')) def test_delete_detail(self): self.assertEqual(Department.objects.count(), 1) delete = self.client.delete(self.api_url, format='json', authentication=self.get_credentials()) self.assertHttpAccepted(delete) self.assertEqual(Department.objects.count(), 0) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized( self.client.put(self.api_url, format='json', data={})) def test_update_detail(self): api_update = '/api/v1/department/1/' original_data = self.deserialize( self.client.get(api_update, format='json', authentication=self.get_credentials())) new_data = original_data.copy() new_data['name'] = 'Name A' self.assertEqual(Department.objects.count(), 1) self.assertHttpAccepted( self.client.put(api_update, format='json', data=new_data, authentication=self.get_credentials())) # Make sure the count hasn't changed & we did an update. self.assertEqual(Department.objects.count(), 1) # Check for updated data. self.assertEqual(Department.objects.get(id=1).name, 'Name A')
class ProjectResourceTest(ResourceTestCase): fixtures = [ 'group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project.json', 'profile.json', 'oauth_client.json', 'oauth_token.json' ] def setUp(self): self.api_client = TestApiClient() self.token = 'd3d81362dd46f415f17e15211875e1d38bf75898' self.category = Category(name='New category') self.category.save() self.post_data = { 'title': 'My project', 'description': 'my description', 'category': self.category } self.project_id = 3 self.open_project_id = 1 self.open_detail_url = '/api/v1/project/{0}/'.format( self.open_project_id) self.detail_url = '/api/v1/project/{0}/'.format(self.project_id) self.list_url = '/api/v1/project/' self.serializer = Serializer() def get_credentials(self, type_user=None): if type_user is 'user': self.api_client.client.login(email='*****@*****.**', password='******') else: self.api_client.client.login(email='*****@*****.**', password='******') def test_post_list(self): self.get_credentials() self.assertIn('_auth_user_id', self.api_client.client.session) self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) self.assertEqual(Project.objects.count(), 2) resp = self.api_client.post(self.list_url, format='json', data=self.post_data) self.assertHttpCreated(resp) self.assertEqual(Project.objects.count(), 3) def test_get_list_unauthorized(self): self.assertHttpUnauthorized( self.api_client.get(self.list_url, format='json')) def test_get_list_unauthorized_open(self): resp = self.api_client.get('?'.join([self.list_url, 'open=true']), format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 1) def test_get_list(self): self.get_credentials() resp = self.api_client.get(self.list_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 2) def test_get_list_oauth(self): resp = self.api_client.client.get( self.list_url, format='json', **{'HTTP_AUTHORIZATION': 'OAuth %s' % self.token}) self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 2) def test_get_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.get(self.detail_url, format='json')) def test_get_detail(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['title'], 'Test Project') # FIXME Tastypie is not calling authorization before obj_create call # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', # data=self.post_data)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.put(self.detail_url, format='json', data={})) @mock.patch('wevolve.projects.api.update_drive_folder') def test_put_detail(self, method): self.get_credentials() original_data = json.loads( self.api_client.get(self.detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Post' self.assertEqual(Project.objects.count(), 2) self.assertHttpAccepted( self.api_client.put(self.detail_url, format='json', data=new_data)) self.assertEqual(Project.objects.count(), 2) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Project.objects.count(), 2) resp = self.api_client.delete(self.detail_url, format='json') self.assertHttpAccepted(resp) self.assertEqual(Project.objects.count(), 1) def test_delete_detail_with_user_perm(self): self.get_credentials('user') self.assertHttpUnauthorized( self.api_client.delete(self.detail_url, format='json')) def test_get_detail_open(self): resp = self.api_client.get(self.open_detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['title'], 'OPEN project') def test_put_detail_open(self): original_data = json.loads( self.api_client.get(self.open_detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Project Open' self.assertEqual(Project.objects.count(), 2) resp = self.api_client.put(self.open_detail_url, format='json', data=new_data) self.assertHttpUnauthorized(resp) def test_delete_detail_open(self): self.assertEqual(Project.objects.count(), 2) resp = self.api_client.delete(self.open_detail_url, format='json') self.assertHttpUnauthorized(resp)
class TestGenericPointAnnotationResource(ResourceTestCase): def setUp(self): #Tastypie stuff super(TestGenericPointAnnotationResource, self).setUp() create_setup(self) self.bob_api_client = TestApiClient() self.bill_api_client = TestApiClient() self.anon_api_client = TestApiClient() # Create a user bob. self.user_bob_username = '******' self.user_bob_password = '******' self.user_bob = User.objects.create_user(self.user_bob_username, '*****@*****.**', self.user_bob_password) # Create a user bob. self.user_bill_username = '******' self.user_bill_password = '******' self.user_bill = User.objects.create_user(self.user_bill_username, '*****@*****.**', self.user_bill_password) self.bob_api_client.client.login(username='******', password='******') self.bill_api_client.client.login(username='******', password='******') #add the users to the main campaign for permission purposes catamidbauthorization.apply_campaign_permissions(self.user_bob, self.campaign_one) catamidbauthorization.apply_campaign_permissions(self.user_bill, self.campaign_one) #assign users to the Public group public_group, created = Group.objects.get_or_create(name='Public') self.user_bob.groups.add(public_group) self.user_bill.groups.add(public_group) guardian.utils.get_anonymous_user().groups.add(public_group) #make a couple of projects and save #self.project_bobs = mommy.make_recipe('project.project1', id=1, owner=self.user_bob) #self.project_bills = mommy.make_recipe('project.project2', id=2, owner=self.user_bill) self.project_bobs = mommy.make_one(Project, owner=self.user_bob, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two]) self.project_bills = mommy.make_one(Project, owner=self.user_bill, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two]) #assign this one to bob authorization.apply_project_permissions( self.user_bob, self.project_bobs) #assign this one to bill authorization.apply_project_permissions( self.user_bill, self.project_bills) self.generic_annotation_set_bobs = mommy.make_one(GenericAnnotationSet, project=self.project_bobs, owner=self.user_bob, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two], annotation_methodology=0, image_sampling_methodology=0) self.generic_annotation_set_bills = mommy.make_one(GenericAnnotationSet, project=self.project_bills, owner=self.user_bob, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two], annotation_methodology=1, image_sampling_methodology=0) #assign this one to bob authorization.apply_generic_annotation_set_permissions( self.user_bob, self.generic_annotation_set_bobs) #assign this one to bill authorization.apply_generic_annotation_set_permissions( self.user_bill, self.generic_annotation_set_bills) self.annotation_point_bobs = mommy.make_one(GenericPointAnnotation, generic_annotation_set=self.generic_annotation_set_bobs, image=self.mock_image_one, owner=self.user_bob, ) self.annotation_point_bills = mommy.make_one(GenericPointAnnotation, generic_annotation_set=self.generic_annotation_set_bills, image=self.mock_image_one, owner=self.user_bill, ) #the API url for annotation points self.point_annotation_url = '/api/dev/generic_point_annotation/' def test_point_annotation_operations_disabled(self): # test that we can not Create Update Delete as anonymous self.assertHttpUnauthorized( self.anon_api_client.post( self.point_annotation_url, format='json', data={}) ) self.assertHttpUnauthorized( self.anon_api_client.put( self.point_annotation_url + self.annotation_point_bills.id.__str__() + "/", format='json', data={}) ) self.assertHttpUnauthorized( self.anon_api_client.delete( self.point_annotation_url + self.annotation_point_bills.id.__str__() + "/", format='json') ) def test_point_annotation_operations_as_authorised_users(self): # create a point annotation that only bill can see bills_private_generic_annotation_set = mommy.make_one(GenericAnnotationSet, project=self.project_bills, owner=self.user_bob, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two], annotation_methodology=2, image_sampling_methodology=0) assign_perm('view_genericannotationset', self.user_bill, bills_private_generic_annotation_set) bills_private_point_annotation = mommy.make_one(GenericPointAnnotation, generic_annotation_set=bills_private_generic_annotation_set, image=self.mock_image_one, owner=self.user_bill, ) #assign('view_genericannotationset', self.user_bill, bills_point_annotation) # check that bill can see via the API response = self.bill_api_client.get(self.point_annotation_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 3) # check that bill can get to the object itself response = self.bill_api_client.get(self.point_annotation_url + bills_private_point_annotation.id.__str__() + "/", format='json') self.assertValidJSONResponse(response) # check that bob can not see - now we know tastypie API has correct # permission validation response = self.bob_api_client.get(self.point_annotation_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 2) # check bob can NOT get to the hidden object response = self.bob_api_client.get(self.point_annotation_url + bills_private_point_annotation.id.__str__() + "/", format='json') self.assertHttpUnauthorized(response) #check that anonymous can see public ones as well response = self.anon_api_client.get(self.point_annotation_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 2) #check anonymous can NOT get to the hidden object response = self.anon_api_client.get(self.point_annotation_url + bills_private_point_annotation.id.__str__() + "/", format='json') self.assertHttpUnauthorized(response) #check bill can POST #some post data for testing project creation self.bill_post_data = {'generic_annotation_set':'/api/dev/generic_annotation_set/' + self.generic_annotation_set_bills.id.__str__() + '/', #'generic_annotation_set': self.generic_annotation_set_bills.id.__str__(), 'annotation_caab_code': 'caab1', 'qualifier_short_name': 'qualifier1', 'owner': "/api/dev/users/" + self.user_bill.id.__str__()+"/", 'image': "/api/dev/generic_image/" + self.mock_image_one.id.__str__() +"/", 'x': '5', 'y': '15' } response = self.bill_api_client.post( self.point_annotation_url, format='json', data=self.bill_post_data) self.assertHttpCreated(response) # check that bill can see via the API response = self.bill_api_client.get(self.point_annotation_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 4) # check that bill can get to the object itself response = self.bill_api_client.get(self.point_annotation_url + "?image=" + self.mock_image_one.id.__str__(), format='json') self.assertValidJSONResponse(response) new_pointannotation_id = self.deserialize(response)[0]['id'].__str__() #check we can modify it - add images self.bill_put_data = {'annotation_caab_code' : 'caab2'} response = self.bill_api_client.put( self.point_annotation_url + new_pointannotation_id + "/", format='json', data=self.bill_put_data) self.assertHttpAccepted(response) response = self.bill_api_client.get(self.point_annotation_url + "?image=" + self.mock_image_one.id.__str__(), format='json') #check bill can DELETE response = self.bill_api_client.delete( self.point_annotation_url + new_pointannotation_id + "/", format='json') self.assertHttpAccepted(response) # check that bill can see via the API response = self.bill_api_client.get(self.point_annotation_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 3)
class TestProjectResource(ResourceTestCase): def setUp(self): #Tastypie stuff super(TestProjectResource, self).setUp() create_setup(self) self.bob_api_client = TestApiClient() self.bill_api_client = TestApiClient() self.anon_api_client = TestApiClient() # Create a user bob. self.user_bob_username = '******' self.user_bob_password = '******' self.user_bob = User.objects.create_user(self.user_bob_username, '*****@*****.**', self.user_bob_password) # Create a user bob. self.user_bill_username = '******' self.user_bill_password = '******' self.user_bill = User.objects.create_user(self.user_bill_username, '*****@*****.**', self.user_bill_password) self.bob_api_client.client.login(username='******', password='******') self.bill_api_client.client.login(username='******', password='******') #need these permissions for bill and bob to attach images to projects catamidbauthorization.apply_campaign_permissions(self.user_bob, self.campaign_one) catamidbauthorization.apply_campaign_permissions(self.user_bill, self.campaign_one) #assign users to the Public group public_group, created = Group.objects.get_or_create(name='Public') self.user_bob.groups.add(public_group) self.user_bill.groups.add(public_group) guardian.utils.get_anonymous_user().groups.add(public_group) #make a couple of projects and save #self.project_bobs = mommy.make_recipe('project.project1', id=1, owner=self.user_bob) #self.project_bills = mommy.make_recipe('project.project2', id=2, owner=self.user_bill) self.project_bobs = mommy.make_one(Project, owner=self.user_bob, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two]) self.project_bills = mommy.make_one(Project, owner=self.user_bill, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two]) #assign this one to bob authorization.apply_project_permissions( self.user_bob, self.project_bobs) #assign this one to bill authorization.apply_project_permissions( self.user_bill, self.project_bills) #the API url for campaigns self.project_url = '/api/dev/project/' def test_project_operations_disabled(self): # test that we can not Create Update Delete as anonymous self.assertHttpUnauthorized( self.anon_api_client.post( self.project_url, format='json', data={}) ) self.assertHttpUnauthorized( self.anon_api_client.put( self.project_url + self.project_bobs.id.__str__() + "/", format='json', data={}) ) self.assertHttpUnauthorized( self.anon_api_client.delete( self.project_url + self.project_bobs.id.__str__() + "/", format='json') ) #test can get a list of campaigns authorised def test_projects_operations_as_authorised_users(self): # create a campaign that only bill can see bills_project = mommy.make_one(Project, owner=self.user_bill, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two]) assign_perm('view_project', self.user_bill, bills_project) # check that bill can see via the API response = self.bill_api_client.get(self.project_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 3) # check that bill can get to the object itself response = self.bill_api_client.get(self.project_url + bills_project.id.__str__() + "/", format='json') self.assertValidJSONResponse(response) # check that bob can not see - now we know tastypie API has correct # permission validation response = self.bob_api_client.get(self.project_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 2) # check bob can NOT get to the hidden object response = self.bob_api_client.get(self.project_url + bills_project.id.__str__() + "/", format='json') self.assertHttpUnauthorized(response) #check that anonymous can see public ones as well response = self.anon_api_client.get(self.project_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 2) #check anonymous can NOT get to the hidden object response = self.anon_api_client.get(self.project_url + bills_project.id.__str__() + "/", format='json') self.assertHttpUnauthorized(response) #check bill can POST #some post data for testing project creation self.bill_post_data = {'name': 'myName', 'description': 'my description', 'generic_images': '' } response = self.bill_api_client.post( self.project_url, format='json', data=self.bill_post_data) self.assertHttpCreated(response) # check that bill can see via the API response = self.bill_api_client.get(self.project_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 4) # check that bill can get to the object itself response = self.bill_api_client.get(self.project_url + "?name=myName&owner=" + self.user_bill.id.__str__(), format='json') self.assertValidJSONResponse(response) new_project_id = self.deserialize(response)[0]['id'].__str__() #check we can modify it - add images self.bill_put_data = {'generic_images' : ["/api/dev/generic_image/" + self.mock_image_one.id.__str__() + "/", "/api/dev/generic_image/" + self.mock_image_two.id.__str__() + "/"]} response = self.bill_api_client.put( self.project_url + new_project_id + "/", format='json', data=self.bill_put_data) self.assertHttpAccepted(response) response = self.bill_api_client.get(self.project_url + "?name=myName&owner=" + self.user_bill.id.__str__(), format='json') #check bill can DELETE response = self.bill_api_client.delete( self.project_url + new_project_id + "/", format='json') self.assertHttpAccepted(response) # check that bill can see via the API response = self.bill_api_client.get(self.project_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 3)
class TestGenericAnnotationSetResource(ResourceTestCase): def setUp(self): #Tastypie stuff super(TestGenericAnnotationSetResource, self).setUp() create_setup(self) self.bob_api_client = TestApiClient() self.bill_api_client = TestApiClient() self.anon_api_client = TestApiClient() # Create a user bob. self.user_bob_username = '******' self.user_bob_password = '******' self.user_bob = User.objects.create_user(self.user_bob_username, '*****@*****.**', self.user_bob_password) # Create a user bob. self.user_bill_username = '******' self.user_bill_password = '******' self.user_bill = User.objects.create_user(self.user_bill_username, '*****@*****.**', self.user_bill_password) self.bob_api_client.client.login(username='******', password='******') self.bill_api_client.client.login(username='******', password='******') #need these permissions for bill and bob to attach images to projects catamidbauthorization.apply_campaign_permissions(self.user_bob, self.campaign_one) catamidbauthorization.apply_campaign_permissions(self.user_bill, self.campaign_one) #assign users to the Public group public_group, created = Group.objects.get_or_create(name='Public') self.user_bob.groups.add(public_group) self.user_bill.groups.add(public_group) guardian.utils.get_anonymous_user().groups.add(public_group) #make a couple of projects and save #self.project_bobs = mommy.make_recipe('project.project1', id=1, owner=self.user_bob) #self.project_bills = mommy.make_recipe('project.project2', id=2, owner=self.user_bill) self.project_bobs = mommy.make_one(Project, owner=self.user_bob, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two]) self.project_bills = mommy.make_one(Project, owner=self.user_bill, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two]) #assign this one to bob authorization.apply_project_permissions( self.user_bob, self.project_bobs) #assign this one to bill authorization.apply_project_permissions( self.user_bill, self.project_bills) self.generic_annotation_set_bobs = mommy.make_one(GenericAnnotationSet, project=self.project_bobs, owner=self.user_bob, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two], annotation_methodology=0, image_sampling_methodology=0) self.generic_annotation_set_bills = mommy.make_one(GenericAnnotationSet, project=self.project_bills, owner=self.user_bob, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two], annotation_methodology=1, image_sampling_methodology=0) #assign this one to bob authorization.apply_generic_annotation_set_permissions( self.user_bob, self.generic_annotation_set_bobs) #assign this one to bill authorization.apply_generic_annotation_set_permissions( self.user_bill, self.generic_annotation_set_bills) #create a big project with 20 images self.project_bills_big = mommy.make_one(Project, owner=self.user_bill, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=self.mock_image_list) #assign this one to bill authorization.apply_project_permissions( self.user_bill, self.project_bills_big) #the API url for resources self.generic_annotation_set_url = '/api/dev/generic_annotation_set/' self.generic_point_annotation_url = '/api/dev/generic_point_annotation/' def test_project_operations_disabled(self): # test that we can not Create Update Delete as anonymous self.assertHttpUnauthorized( self.anon_api_client.post( self.generic_annotation_set_url, format='json', data={'image_sample_size': '20'}) ) self.assertHttpUnauthorized( self.anon_api_client.put( self.generic_annotation_set_url + self.generic_annotation_set_bobs.id.__str__() + "/", format='json', data={}) ) self.assertHttpUnauthorized( self.anon_api_client.delete( self.generic_annotation_set_url + self.generic_annotation_set_bobs.id.__str__() + "/", format='json') ) def test_annotationset_operations_as_authorised_users(self): # create a campaign that only bill can see bills_generic_annotation_set = mommy.make_one(GenericAnnotationSet, project=self.project_bills, owner=self.user_bob, creation_date=datetime.now(), modified_date=datetime.now(), generic_images=[self.mock_image_one, self.mock_image_two], annotation_methodology=2, image_sampling_methodology=0) assign_perm('view_genericannotationset', self.user_bill, bills_generic_annotation_set) # check that bill can see via the API response = self.bill_api_client.get(self.generic_annotation_set_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 3) # check that bill can get to the object itself response = self.bill_api_client.get(self.generic_annotation_set_url + bills_generic_annotation_set.id.__str__() + "/", format='json') self.assertValidJSONResponse(response) # check that bob can not see - now we know tastypie API has correct # permission validation response = self.bob_api_client.get(self.generic_annotation_set_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 2) # check bob can NOT get to the hidden object response = self.bob_api_client.get(self.generic_annotation_set_url + bills_generic_annotation_set.id.__str__() + "/", format='json') self.assertHttpUnauthorized(response) #check that anonymous can see public ones as well response = self.anon_api_client.get(self.generic_annotation_set_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 2) #check anonymous can NOT get to the hidden object response = self.anon_api_client.get(self.generic_annotation_set_url + bills_generic_annotation_set.id.__str__() + "/", format='json') self.assertHttpUnauthorized(response) #check bill can POST #some post data for testing project creation self.bill_post_data = {'project':'/api/dev/project/' + self.project_bills_big.id.__str__() + '/', 'name': 'myName2', 'description': 'my description', 'owner': "/api/dev/users/" + self.user_bill.id.__str__()+"/", 'creation_date': '2012-05-01', 'modified_date': '2012-05-01', #'generic_images': [ "/api/dev/generic_image/" + self.mock_image_one.id.__str__() + "/", # "/api/dev/generic_image/" + self.mock_image_two.id.__str__() + "/"], 'generic_images': '', 'annotation_methodology': '0', 'image_sampling_methodology': '0', 'image_sample_size': '10', 'point_sample_size': '15' } response = self.bill_api_client.post( self.generic_annotation_set_url, format='json', data=self.bill_post_data) self.assertHttpCreated(response) # check that bill can see via the API response = self.bill_api_client.get(self.generic_annotation_set_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 4) # check that bill can get to the object itself response = self.bill_api_client.get(self.generic_annotation_set_url + "?name=myName2&owner=" + self.user_bill.id.__str__(), format='json') self.assertValidJSONResponse(response) new_annotationset_id = self.deserialize(response)[0]['id'].__str__() #check we can modify it - add images self.bill_put_data = {'description' : 'my new description'} response = self.bill_api_client.put( self.generic_annotation_set_url + new_annotationset_id + "/", format='json', data=self.bill_put_data) self.assertHttpAccepted(response) response = self.bill_api_client.get(self.generic_annotation_set_url + "?name=myName&owner=" + self.user_bill.id.__str__(), format='json') #check bill can DELETE response = self.bill_api_client.delete( self.generic_annotation_set_url + new_annotationset_id + "/", format='json') self.assertHttpAccepted(response) # check that bill can see via the API response = self.bill_api_client.get(self.generic_annotation_set_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), 3) def test_annotation_set_creation_random(self): #some post data for testing project creation self.bill_post_data = {'project':'/api/dev/project/' + self.project_bills_big.id.__str__() + '/', 'name': 'myName', 'description': 'my description', 'owner': "/api/dev/users/" + self.user_bill.id.__str__()+"/", 'creation_date': '2012-05-01', 'modified_date': '2012-05-01', 'generic_images': '', 'annotation_methodology': '0', 'image_sampling_methodology': '0', 'image_sample_size': '10', 'point_sample_size': '15' } response = self.bill_api_client.post( self.generic_annotation_set_url, format='json', data=self.bill_post_data) self.assertHttpCreated(response) # check that bill can get to the object itself response = self.bill_api_client.get(self.generic_annotation_set_url + "?name=myName&owner=" + self.user_bill.id.__str__(), format='json') # check that the API did indeed samle 10 images generic_images = self.deserialize(response)[0]['generic_images'] self.assertEqual(len(generic_images), 10) # check that the API set 15 points per image for image in generic_images: response = self.bill_api_client.get(self.generic_point_annotation_url + "?image=" + image['id'].__str__(), format='json') self.assertEqual(len(self.deserialize(response)), 15) def test_annotation_set_creation_stratified(self): #some post data for testing project creation self.bill_post_data = {'project':'/api/dev/project/' + self.project_bills_big.id.__str__() + '/', 'name': 'myName', 'description': 'my description', 'owner': "/api/dev/users/" + self.user_bill.id.__str__()+"/", 'creation_date': '2012-05-01', 'modified_date': '2012-05-01', 'generic_images': '', 'annotation_methodology': '0', 'image_sampling_methodology': '1', 'image_sample_size': '10', 'point_sample_size': '5' } response = self.bill_api_client.post( self.generic_annotation_set_url, format='json', data=self.bill_post_data) self.assertHttpCreated(response) # check that bill can get to the object itself response = self.bill_api_client.get(self.generic_annotation_set_url + "?name=myName&owner=" + self.user_bill.id.__str__(), format='json') # check that the API did indeed samle 10 images generic_images = self.deserialize(response)[0]['generic_images'] self.assertEqual(len(generic_images), 10) # check that the API set 5 points per image for image in generic_images: response = self.bill_api_client.get(self.generic_point_annotation_url + "?image=" + image['id'].__str__(), format='json') self.assertEqual(len(self.deserialize(response)), 5) def test_annotation_set_creation_unimplemented(self): #some post data for testing project creation self.bill_post_data = {'project':'/api/dev/project/' + self.project_bills_big.id.__str__() + '/', 'name': 'myName2', 'description': 'my description', 'owner': "/api/dev/users/" + self.user_bill.id.__str__()+"/", 'creation_date': '2012-05-01', 'modified_date': '2012-05-01', 'generic_images': '', 'annotation_methodology': '4', 'image_sampling_methodology': '4', 'image_sample_size': '10', 'point_sample_size': '5' } response = self.bill_api_client.post( self.generic_annotation_set_url, format='json', data=self.bill_post_data) self.assertHttpNotImplemented(response)
class ProjectPartResourceTest(ResourceTestCase): fixtures = ['group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json'] def setUp(self): self.api_client = TestApiClient() self.post_data = {'title': 'new part', 'project_id': {'pk': 3}, 'project_part_id': {'pk': 1}, 'order': 0, 'weight': 20 } self.project_part_id = 1 self.open_project_part_id = 2 self.detail_base_url = '/api/v1/project_part/{0}/' self.open_detail_url = self.detail_base_url.format(self.open_project_part_id) self.detail_url = self.detail_base_url.format(self.project_part_id) self.list_url = '/api/v1/project_part/' self.serializer = Serializer() def get_credentials(self): self.api_client.client.login(email='*****@*****.**', password='******') def test_get_list_unauthorized(self): self.assertHttpUnauthorized(self.api_client.get(self.list_url, format='json')) def test_get_list(self): self.get_credentials() self.assertHttpUnauthorized(self.api_client.get(self.list_url, format='json')) def test_get_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.get(self.detail_url, format='json')) def test_get_detail(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['title'], 'Project Part 1') # FIXME Idem from above # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', data=self.post_data)) def test_post_list(self): self.get_credentials() self.assertEqual(ProjectPart.objects.count(), 2) resp = self.api_client.post(self.list_url, format='json', data=self.post_data) self.assertHttpCreated(resp) self.assertEqual(ProjectPart.objects.count(), 3) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.put(self.detail_url, format='json', data={})) @mock.patch('wevolve.projects.api.update_drive_folder') def test_put_detail(self, method): self.get_credentials() content = self.api_client.get(self.detail_url, format='json').content original_data = json.loads(content) new_data = original_data.copy() new_data['title'] = 'Updated First Post' self.assertEqual(ProjectPart.objects.count(), 2) resp = self.api_client.put(self.detail_url, format='json', data=new_data) self.assertHttpAccepted(resp) self.assertEqual(ProjectPart.objects.count(), 2) self.assertEqual(ProjectPart.objects.get(pk=self.project_part_id).title, 'Updated First Post') def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(ProjectPart.objects.count(), 2) self.assertHttpAccepted(self.api_client.delete(self.detail_url, format='json')) self.assertEqual(ProjectPart.objects.count(), 1) # Project parts in open projects def test_get_detail_open(self): resp = self.api_client.get(self.open_detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['title'], 'Project Part 2') def test_put_detail_open(self): content = self.api_client.get(self.open_detail_url, format='json').content original_data = json.loads(content) new_data = original_data.copy() new_data['title'] = 'Updated First Post' self.assertEqual(ProjectPart.objects.count(), 2) resp = self.api_client.put(self.detail_url, format='json', data=new_data) self.assertHttpUnauthorized(resp) def test_delete_detail_open(self): self.assertEqual(ProjectPart.objects.count(), 2) resp = self.api_client.delete(self.open_detail_url, format='json') self.assertHttpUnauthorized(resp)
class ResourceTest(ResourceTestCase): def setUp(self): self.logger = logging.getLogger(__name__) self.api_client = TestApiClient() self.username = "******" self.password = "******" # create a user to be used for creating the resource self.user_creator = hydroshare.create_account( "*****@*****.**", username=self.username, first_name="Creator_FirstName", last_name="Creator_LastName", superuser=False, password=self.password, groups=[], ) self.user_url = "/hsapi/accounts/{0}/".format(self.user_creator.username) self.api_client.client.login(username=self.username, password=self.password) # create a resource self.resource = hydroshare.create_resource( resource_type="GenericResource", title="My resource", owner=self.user_creator, last_changed_by=self.user_creator, ) self.resource_url_base = "/hsapi/resource/" self.resource_url = "{0}{1}/".format(self.resource_url_base, self.resource.short_id) self.post_data = {"title": "My REST API-created resource", "resource_type": "GenericResource"} def tearDown(self): User.objects.all().delete() GenericResource.objects.all().delete() def get_credentials(self): k = self.create_basic(username=self.username, password=self.password) print k return k def test_resource_get(self): resp = self.api_client.get(self.resource_url) self.assertTrue(resp["Location"].endswith(".zip")) def test_resource_post(self): resp = self.api_client.post(self.resource_url_base, data=self.post_data) self.assertIn(resp.status_code, [201, 200]) # PID comes back as body of response, but API client doesn't seem to be # parsing the response for us pid = str(resp).split("\n")[-1] new_resource_url = "{0}{1}/".format(self.resource_url_base, pid) # Fetch the newly created resource resp = self.api_client.get(new_resource_url) self.assertTrue(resp["Location"].endswith(".zip")) def test_resource_put(self): new_data = {} new_data["title"] = "My UPDATED REST API-created resource" resp = self.api_client.put(self.resource_url, data=new_data) self.assertIn(resp.status_code, ["202", "204"]) def test_resource_delete(self): x = self.api_client.delete(self.resource_url, format="json") self.assertIn(x.status_code, [202, 204, 301]) self.assertHttpNotFound(self.api_client.get(self.resource_url, format="json"))
class AuthResourceTest(ResourceTestCase): fixtures = ['test_auth.json'] def setUp(self): super(AuthResourceTest, self).setUp() self.client = TestApiClient() self.endpoint = '/api/v1/auth/' self.format = 'json' # Get user 1 and token 1 from fixture self.user = User.objects.all()[0] self.token = self.user.usertoken_set.all()[0] self.password = '******' self.detail = '/api/v1/auth/{0}/'.format(self.token.id) # Get user 2 and token 2 from fixture self.user2 = User.objects.all()[1] self.token2 = self.user2.usertoken_set.all()[0] self.detail2 = '/api/v1/auth/{0}/'.format(self.token2.id) def get_credentials(self): return self.create_basic(username=self.user.username, password=self.password) # Try to get tokens without credentials def test_get_keys_unauthorzied(self): self.assertHttpUnauthorized(self.client.get(self.endpoint, self.format)) # Try to create a token (POST) def test_create_token_json(self): post_data = {} credentials = self.get_credentials() self.assertHttpCreated(self.client.post(self.endpoint, self.format, data=post_data, authentication=credentials)) # Try to get all tokens (GET) def test_get_keys_json(self): credentials = self.get_credentials() resp = self.client.get(self.endpoint, self.format, authentication=credentials) self.assertValidJSONResponse(resp) # Try to delete a token (DELETE) def test_delete_token_json(self): credentials = self.get_credentials() self.assertEqual(UserToken.objects.count(), 2) resp = self.client.delete(self.detail, format=self.format, authentication=credentials) self.assertHttpAccepted(resp) self.assertEqual(UserToken.objects.count(), 1) # User 1 try to delete user 2 token def test_delete_another_token(self): credentials = self.get_credentials() self.assertHttpNotFound(self.client.delete(self.detail2, format=self.format, authentication=credentials)) # Try to create a token (POST) with wrong credentials def test_create_token_with_wrong_credentials_json(self): post_data = {} credentials = self.create_basic(username=self.user.username, password="******") self.assertHttpUnauthorized(self.client.post(self.endpoint, self.format, data=post_data, authentication=credentials))
class DocumentResourceTest(ResourceTestCase): fixtures = ['group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json', 'document.json'] def setUp(self): self.api_client = TestApiClient() self.project_part_id = 1 self.document_data = {'text': 'My document', 'project_part': {'pk': self.project_part_id}} self.document_id = 1 self.project_part_query = '='.join(['?project_part', str(self.project_part_id)]) self.detail_url = '/api/v1/document/{0}/'.format(self.document_id) self.list_url = '/api/v1/document/' self.serializer = Serializer() def get_credentials(self): result = self.api_client.client.login(email='*****@*****.**', password='******') def test_document_list(self): self.get_credentials() self.assertIn('_auth_user_id', self.api_client.client.session) self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) self.assertEqual(Document.objects.count(), 2) self.assertHttpCreated(self.api_client.post(self.list_url, format='json', data=self.document_data)) self.assertEqual(Document.objects.count(), 3) def test_get_list_unauthorzied(self): self.assertHttpUnauthorized(self.api_client.get(self.list_url, format='json')) def test_get_list(self): self.get_credentials() resp = self.api_client.get(''.join([self.list_url, self.project_part_query]), format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 1) def test_get_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.get(self.detail_url, format='json')) def test_get_detail(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['text'], '<h1>hola</h1>') # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', # data=self.document_data)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.put(self.detail_url, format='json', data={'text': 'data'})) def test_put_detail(self): self.get_credentials() original_data = json.loads(self.api_client.get(self.detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Document' self.assertEqual(Document.objects.count(), 2) self.assertHttpAccepted(self.api_client.put(self.detail_url, format='json', data=new_data)) # Make sure the count hasn't changed & we did an update. self.assertEqual(Document.objects.count(), 2) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Document.objects.count(), 2) resp = self.api_client.delete(self.detail_url, format='json') self.assertHttpAccepted(resp) self.assertEqual(Document.objects.count(), 1)
class CommentResourceTest(ResourceTestCase): fixtures = ['group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json', 'post.json', 'comment.json'] def setUp(self): self.api_client = TestApiClient() self.post_id = 1 self.post_data = {'post': {'pk': self.post_id, 'text': 'New comment'}} self.detail_url = '/api/v1/comment/{0}/'.format(self.post_id) self.list_url = '/api/v1/comment/' self.serializer = Serializer() def get_credentials(self): result = self.api_client.client.login(email='*****@*****.**', password='******') # def test_post_list(self): # self.get_credentials() # self.assertIn('_auth_user_id', self.api_client.client.session) # self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) # self.assertEqual(Comment.objects.count(), 1) # self.assertHttpCreated(self.api_client.post(self.list_url, # format='json', # data=self.post_data)) # self.assertEqual(Comment.objects.count(), 2) def test_get_list_unauthorized(self): self.assertHttpUnauthorized(self.api_client.get(self.list_url, format='json')) def test_get_list(self): self.get_credentials() resp = self.api_client.get(self.list_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 1) def test_get_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.get(self.detail_url, format='json')) # def test_get_detail(self): # self.get_credentials() # resp = self.api_client.get(self.detail_url, format='json') # self.assertValidJSONResponse(resp) # self.assertEqual(json.loads(resp.content)['comment'], '') def test_post_list_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', data=self.post_data)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.put(self.detail_url, format='json', data={})) def test_put_detail(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') original_data = json.loads(resp.content) new_data = original_data.copy() new_data['title'] = 'Updated: First Comment' self.assertEqual(Comment.objects.count(), 1) self.assertHttpAccepted(self.api_client.put(self.detail_url, format='json', data=new_data)) self.assertEqual(Comment.objects.count(), 1) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Comment.objects.count(), 1) resp = self.api_client.delete(self.detail_url, format='json') self.assertHttpAccepted(resp) self.assertEqual(Comment.objects.count(), 0)
class CommentResourceTest(ResourceTestCase): fixtures = [ 'group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json', 'post.json', 'comment.json' ] def setUp(self): self.api_client = TestApiClient() self.post_id = 1 self.post_data = {'post': {'pk': self.post_id, 'text': 'New comment'}} self.detail_url = '/api/v1/comment/{0}/'.format(self.post_id) self.list_url = '/api/v1/comment/' self.serializer = Serializer() def get_credentials(self): result = self.api_client.client.login(email='*****@*****.**', password='******') # def test_post_list(self): # self.get_credentials() # self.assertIn('_auth_user_id', self.api_client.client.session) # self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) # self.assertEqual(Comment.objects.count(), 1) # self.assertHttpCreated(self.api_client.post(self.list_url, # format='json', # data=self.post_data)) # self.assertEqual(Comment.objects.count(), 2) def test_get_list_unauthorized(self): self.assertHttpUnauthorized( self.api_client.get(self.list_url, format='json')) def test_get_list(self): self.get_credentials() resp = self.api_client.get(self.list_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 1) def test_get_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.get(self.detail_url, format='json')) # def test_get_detail(self): # self.get_credentials() # resp = self.api_client.get(self.detail_url, format='json') # self.assertValidJSONResponse(resp) # self.assertEqual(json.loads(resp.content)['comment'], '') def test_post_list_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.post(self.list_url, format='json', data=self.post_data)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.put(self.detail_url, format='json', data={})) def test_put_detail(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') original_data = json.loads(resp.content) new_data = original_data.copy() new_data['title'] = 'Updated: First Comment' self.assertEqual(Comment.objects.count(), 1) self.assertHttpAccepted( self.api_client.put(self.detail_url, format='json', data=new_data)) self.assertEqual(Comment.objects.count(), 1) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Comment.objects.count(), 1) resp = self.api_client.delete(self.detail_url, format='json') self.assertHttpAccepted(resp) self.assertEqual(Comment.objects.count(), 0)
class PostResourceTest(ResourceTestCase): fixtures = ['group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json', 'post.json', 'comment.json'] def setUp(self): # Generic self.api_client = TestApiClient() self.serializer = Serializer() # API List data self.list_url = '/api/v1/post/' # API requests data self.project_part_id = 1 self.post_id = 1 self.detail_url = '/api/v1/post/{0}/'.format(self.post_id) self.project_part_query = '='.join(['?project_part', str(self.project_part_id)]) self.post_data = {'content': 'My post', 'project_part': {'pk': self.project_part_id}} # Open API request data self.open_project_part_id = 2 self.open_post_id = 2 self.open_detail_url = '/api/v1/post/{0}/'.format(self.open_post_id) self.open_project_part_query = '='.join(['?project_part', str(self.open_project_part_id)]) self.open_post_data = {'content': 'My post', 'project_part': {'pk': self.open_project_part_id}} def get_credentials(self): result = self.api_client.client.login(email='*****@*****.**', password='******') def test_post_list(self): self.get_credentials() self.assertIn('_auth_user_id', self.api_client.client.session) self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) self.assertEqual(Post.objects.count(), 2) self.assertHttpCreated(self.api_client.post(self.list_url, format='json', data=self.post_data)) self.assertEqual(Post.objects.count(), 3) def test_get_list_unauthorzied(self): self.assertHttpUnauthorized(self.api_client.get(self.list_url, format='json')) def test_get_list(self): self.get_credentials() resp = self.api_client.get(''.join([self.list_url, self.project_part_query]), format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 1) def test_get_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.get(self.detail_url, format='json')) def test_get_detail(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['content'], 'hola') # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', # data=self.post_data)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.put(self.detail_url, format='json', data={})) def test_put_detail(self): self.get_credentials() original_data = json.loads(self.api_client.get(self.detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Post' self.assertEqual(Post.objects.count(), 2) self.assertHttpAccepted(self.api_client.put(self.detail_url, format='json', data=new_data)) # Make sure the count hasn't changed & we did an update. self.assertEqual(Post.objects.count(), 2) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Post.objects.count(), 2) resp = self.api_client.delete(self.detail_url, format='json') self.assertHttpAccepted(resp) self.assertEqual(Post.objects.count(), 1) # Open Projects # FIXME It fails because tastypie is not accessing authorization # before calling obj_create # def test_post_list_open(self): # self.assertEqual(Post.objects.count(), 2) # resp = self.api_client.post(self.list_url, # format='json', # data=self.open_post_data) # self.assertHttpUnauthorized(resp) def test_get_detail_open(self): resp = self.api_client.get(self.open_detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['content'], 'hola') def test_delete_detail_open(self): self.assertEqual(Post.objects.count(), 2) resp = self.api_client.delete(self.open_detail_url, format='json') self.assertHttpUnauthorized(resp) def test_put_detail_open(self): original_data = json.loads(self.api_client.get(self.open_detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Post' self.assertEqual(Post.objects.count(), 2) resp = self.api_client.put(self.open_detail_url, format='json', data=new_data) self.assertHttpUnauthorized(resp)
class ResourceTest(ResourceTestCase): def setUp(self): self.logger = logging.getLogger(__name__) self.api_client = TestApiClient() self.username = '******' self.password = '******' # create a user to be used for creating the resource self.user_creator = hydroshare.create_account( '*****@*****.**', username=self.username, first_name='Creator_FirstName', last_name='Creator_LastName', superuser=False, password=self.password, groups=[]) self.user_url = '/hsapi/accounts/{0}/'.format( self.user_creator.username) self.api_client.client.login(username=self.username, password=self.password) # create a resource self.resource = hydroshare.create_resource( resource_type='GenericResource', title='My resource', owner=self.user_creator, last_changed_by=self.user_creator) self.resource_url_base = '/hsapi/resource/' self.resource_url = '{0}{1}/'.format(self.resource_url_base, self.resource.short_id) self.post_data = { 'title': 'My REST API-created resource', 'resource_type': 'GenericResource' } def tearDown(self): User.objects.all().delete() GenericResource.objects.all().delete() def get_credentials(self): k = self.create_basic(username=self.username, password=self.password) print k return k def test_resource_get(self): resp = self.api_client.get(self.resource_url) self.assertTrue(resp['Location'].endswith('.zip')) def test_resource_post(self): resp = self.api_client.post(self.resource_url_base, data=self.post_data) self.assertIn(resp.status_code, [201, 200]) # PID comes back as body of response, but API client doesn't seem to be # parsing the response for us pid = str(resp).split('\n')[-1] new_resource_url = '{0}{1}/'.format(self.resource_url_base, pid) # Fetch the newly created resource resp = self.api_client.get(new_resource_url) self.assertTrue(resp['Location'].endswith('.zip')) def test_resource_put(self): new_data = {} new_data['title'] = 'My UPDATED REST API-created resource' resp = self.api_client.put(self.resource_url, data=new_data) self.assertIn(resp.status_code, ['202', '204']) def test_resource_delete(self): x = self.api_client.delete(self.resource_url, format='json') self.assertIn(x.status_code, [202, 204, 301]) self.assertHttpNotFound( self.api_client.get(self.resource_url, format='json'))
class Private_v1__PhotoResourceTest(ResourceTestCase): fixtures = [ 'packages.json', 'api_accounts_and_keys.json', 'accounts_and_users.json', 'events.json', 'photos.json' ] def setUp(self): super(Private_v1__PhotoResourceTest, self).setUp() # we need a custom serializer for multipart uploads self.api_client = TestApiClient(serializer=MultipartSerializer()) self.api_key = 'key123' self.api_secret = 'sec123' # The data we'll send on POST requests. filename = 'trashcat.jpg' filepath = os.path.join(settings.PROJECT_PATH, 'api', 'assets', filename) f = open(filepath, 'rb') self.post_data = { 'event': '/private_v1/event/1/', 'caption': 'My super awesome caption!', 'type': '/private_v1/type/1/', 'image': { 'filename': filename, 'data': f.read(), } } def get_credentials(self, method, uri): return DatabaseAuthentication.create_signature(self.api_key, self.api_secret, method, uri) def test_post_photo(self): uri = '/private_v1/photo/' resp = self.api_client.post(uri, data=self.post_data, format='multipart', authentication=self.get_credentials( 'POST', uri)) data = self.deserialize(resp) # make sure the resource was created self.assertHttpCreated(resp) # test to make sure all the keys are in the response self.assertKeys(self.deserialize(resp), [ 'author_name', 'caption', 'created_at', 'event', 'guest', 'image', 'is_streamable', 'resource_uri', 'streamable', 'timestamp', 'type', ]) # make sure the timestamp is in the format we want (ISO8601) without micro # expected format: 2013-01-21T18:12:45 self.assertTrue( re.search('^\d{4}-(\d{2}-?){2}T(\d{2}:?){3}$', data['timestamp'])) def test_post_photo_noimage(self): uri = '/private_v1/photo/' del (self.post_data['image']) resp = self.api_client.post(uri, data=self.post_data, format='multipart', authentication=self.get_credentials( 'POST', uri)) data = self.deserialize(resp) # make sure the resource was created self.assertHttpBadRequest(resp) def test_put_photo(self): uri = '/private_v1/photo/1/' put_data = {'caption': 'awesome'} resp = self.api_client.put(uri, data=put_data, format='json', authentication=self.get_credentials( 'PUT', uri)) data = self.deserialize(resp) # make sure the resource has a valid response self.assertHttpOK(resp) # test to make sure all the keys are in the response self.assertEqual(data['caption'], put_data['caption']) def test_patch_photo(self): uri = '/private_v1/photo/1/' patch_data = {'is_streamable': False} resp = self.api_client.patch(uri, data=patch_data, format='json', authentication=self.get_credentials( 'PATCH', uri)) data = self.deserialize(resp) # make sure the resource has a valid response self.assertHttpAccepted(resp) # test to make sure all the keys are in the response self.assertEqual(data['is_streamable'], patch_data['is_streamable']) def test_delete_photo(self): uri = '/private_v1/photo/1/' resp = self.api_client.delete(uri, format='json', authentication=self.get_credentials( 'DELETE', uri)) self.assertHttpAccepted(resp)
class ResourceTest(ResourceTestCase): serializer= Serializer() def setUp(self): self.api_client = TestApiClient() self.username = '******' self.password = '******' self.user = hydroshare.create_account( '*****@*****.**', username=self.username, password=self.password, first_name='User0_FirstName', last_name='User0_LastName', ) self.api_client.client.login(username=self.username, password=self.password) self.url_proto = '/hsapi/resource/{0}/files/{1}/' self.filename = 'test.txt' def tearDown(self): User.objects.all().delete() GenericResource.objects.all().delete() def test_resource_file_get(self): myfile = open(self.filename, 'w') myfile.write('hello world!\n') myfile.close() myfile = open(self.filename, 'r') res1 = hydroshare.create_resource('GenericResource', self.user, 'res1') hydroshare.add_resource_files(res1.short_id, myfile) url = self.url_proto.format(res1.short_id, self.filename) resp = self.api_client.get(url) self.assertIn(resp.status_code, [201, 200]) def test_resource_file_put(self): myfile = open(self.filename, 'w') myfile.write('hello world!\n') myfile.close() myfile = open(self.filename, 'r') res1 = hydroshare.create_resource('GenericResource', self.user, 'res1') hydroshare.add_resource_files(res1.short_id, myfile) mynewfile = open(self.filename, 'w') mynewfile.write('anyone there?\n') mynewfile.close() mynewfile = open(self.filename, 'r') url = self.url_proto.format(res1.short_id, self.filename) put_data = { 'resource_file': mynewfile } resp = self.api_client.put(url, data=put_data) self.assertHttpAccepted(resp) resp = self.api_client.get(url) self.assertIn(resp.status_code, [201, 200]) def test_resource_file_post(self): myfile = open(self.filename, 'w') myfile.write('hello world!\n') myfile.close() myfile = open(self.filename, 'r') res1 = hydroshare.create_resource('GenericResource', self.user, 'res1') post_data = { 'resource_file': myfile } url = self.url_proto.format(res1.short_id, self.filename) resp = self.api_client.post(url, data=post_data) self.assertHttpAccepted(resp) resp = self.api_client.get(url) self.assertIn(resp.status_code, [201, 200]) def test_resource_file_delete(self): myfile = open(self.filename, 'w') myfile.write('hello world!\n') myfile.close() myfile = open(self.filename, 'r') res1 = hydroshare.create_resource('GenericResource', self.user, 'res1') hydroshare.add_resource_files(res1.short_id, myfile) url = self.url_proto.format(res1.short_id, self.filename) resp = self.api_client.delete(url) self.assertIn(resp.status_code, [200, 202, 204]) self.assertHttpNotFound( self.api_client.get(url, format='json') )
def test_2api_init(self): print '***================ super: db test_2api_init =============== ' super(TestApiInit, self).test_2api_init() print '***================ local: db test_2api_init =============== ' serializer = CSVSerializer() # todo: doesn't work for post, see TestApiClient.post() method, it is # incorrectly "serializing" the data before posting testApiClient = TestApiClient(serializer=serializer) filename = os.path.join(self.db_directory, 'api_init_actions.csv') with open(filename) as input_file: api_init_actions = serializer.from_csv(input_file.read(), root=None) bootstrap_files = [ 'metahash_resource_data.csv', 'vocabularies_data.csv' ] for action in api_init_actions: print '\n++++=========== processing action', json.dumps(action) command = action['command'].lower() resource = action['resource'].lower() resource_uri = BASE_REPORTS_URI + '/' + resource if command == 'delete': resp = testApiClient.delete( resource_uri, authentication=self.get_credentials()) self.assertHttpAccepted(resp) else: filename = os.path.join(self.db_directory, action['file']) search_excludes = [] # exclude 'resource_uri' from equivalency check during # bootstrap, because resource table needs to be loaded for # the uri generation if action['file'] in bootstrap_files: search_excludes = ['resource_uri'] logger.info(str(('+++++++++++processing file', filename))) with open(filename) as data_file: input_data = serializer.from_csv(data_file.read()) if command == 'put': resp = testApiClient.put( resource_uri, format='csv', data=input_data, authentication=self.get_credentials()) logger.debug( str(('action: ', json.dumps(action), 'response: ', resp.status_code))) self.assertTrue(resp.status_code in [200], str((resp.status_code, resp))) # now see if we can get these objects back resp = testApiClient.get( resource_uri, format='json', authentication=self.get_credentials(), data={'limit': 999}) self.assertTrue(resp.status_code in [200], str((resp.status_code, resp))) # self.assertValidJSONResponse(resp) new_obj = self.deserialize(resp) result, msgs = find_all_obj_in_list( input_data['objects'], new_obj['objects'], excludes=search_excludes) self.assertTrue( result, str((command, 'input file', filename, msgs, new_obj['objects']))) elif command == 'patch': resp = testApiClient.patch( resource_uri, format='csv', data=input_data, authentication=self.get_credentials()) # self.assertHttpAccepted(resp) self.assertTrue( resp.status_code in [202, 204], str(('response not accepted, resource_uri:', resource_uri, 'response', resp))) resp = testApiClient.get( resource_uri, format='json', authentication=self.get_credentials(), data={'limit': 999}) self.assertTrue(resp.status_code in [200], str((resp.status_code, resp))) # self.assertValidJSONResponse(resp) new_obj = self.deserialize(resp) with open(filename) as f2: input_data2 = serializer.from_csv(f2.read()) result, msgs = find_all_obj_in_list( input_data2['objects'], new_obj['objects'], excludes=search_excludes) self.assertTrue( result, str((command, 'input file', filename, msgs))) elif command == 'post': self.fail(( 'resource entry: ' + json.dumps(action) + '; ' 'cannot POST multiple objects to tastypie; ' 'therefore the "post" command is invalid with ' 'the initialization scripts')) else: self.fail('unknown command: ' + command + ', ' + json.dumps(action))
class TestMeasurementsResource(ResourceTestCase): def setUp(self): # Tastypie stuff super(TestMeasurementsResource, self).setUp() self.bob_api_client = TestApiClient() self.bill_api_client = TestApiClient() self.anon_api_client = TestApiClient() # Create a user bob. self.user_bob_username = "******" self.user_bob_password = "******" self.user_bob = User.objects.create_user(self.user_bob_username, "*****@*****.**", self.user_bob_password) # Create a user bob. self.user_bill_username = "******" self.user_bill_password = "******" self.user_bill = User.objects.create_user( self.user_bill_username, "*****@*****.**", self.user_bill_password ) self.bob_api_client.client.login(username="******", password="******") self.bill_api_client.client.login(username="******", password="******") # assign users to the Public group public_group, created = Group.objects.get_or_create(name="Public") self.user_bob.groups.add(public_group) self.user_bill.groups.add(public_group) guardian.utils.get_anonymous_user().groups.add(public_group) # make a couple of campaigns and save self.campaign_bobs = mommy.make_one("catamidb.Campaign", id=1) self.campaign_bills = mommy.make_one("catamidb.Campaign", id=2) # make a deployments self.deployment_bobs = mommy.make_recipe("catamidb.Deployment1", id=1, campaign=self.campaign_bobs) self.deployment_bills = mommy.make_recipe("catamidb.Deployment2", id=2, campaign=self.campaign_bills) # make images self.image_bobs = mommy.make_recipe("catamidb.Image1", id=1, deployment=self.deployment_bobs) self.image_bills = mommy.make_recipe("catamidb.Image2", id=2, deployment=self.deployment_bills) # make measurements self.measurements_bobs = mommy.make_one("catamidb.Measurement", id=1, image=self.image_bobs) self.measurements_bills = mommy.make_one("catamidb.Measurement", id=2, image=self.image_bills) # assign this one to bob authorization.apply_campaign_permissions(self.user_bob, self.campaign_bobs) # assign this one to bill authorization.apply_campaign_permissions(self.user_bill, self.campaign_bills) # the API url for Measurements self.image_measurement_url = "/api/dev/measurements/" self.post_data = { "altitude": "13", "pitch": "1", "roll": "5", "salinity": "20", "temperature": "22", "yaw": "1", } # can only do GET at this stage def test_measurement_operations_disabled(self): # test that we can NOT modify self.assertHttpUnauthorized( self.anon_api_client.put( self.image_measurement_url + self.deployment_bobs.id.__str__() + "/", format="json", data={} ) ) # test that we can NOT delete self.assertHttpMethodNotAllowed( self.anon_api_client.delete( self.image_measurement_url + self.deployment_bobs.id.__str__() + "/", format="json" ) ) # test that we can NOT modify authenticated self.assertHttpUnauthorized( self.bob_api_client.put( self.image_measurement_url + self.deployment_bobs.id.__str__() + "/", format="json", data={} ) ) # test that we can NOT delete authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.delete( self.image_measurement_url + self.deployment_bobs.id.__str__() + "/", format="json" ) ) def test_measurement_operations_as_authorised_users(self): # create a campaign & deployment that ONLY bill can see bills_campaign = mommy.make_one("catamidb.Campaign", id=3, short_name="cp__3") bills_deployment = mommy.make_recipe("catamidb.Deployment1", id=3, campaign=bills_campaign, short_name="dp__3") bills_image = mommy.make_recipe("catamidb.Image3", id=3, deployment=bills_deployment) bills_measurements = mommy.make_one("catamidb.Measurement", id=3, image=bills_image) assign("view_campaign", self.user_bill, bills_campaign) # check that bill can see via the API response = self.bill_api_client.get(self.image_measurement_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 3) # check that bill can get to the object itself response = self.bill_api_client.get(self.image_measurement_url + "3/", format="json") self.assertValidJSONResponse(response) # check that bob can not see - now we know tastypie API has correct # permission validation response = self.bob_api_client.get(self.image_measurement_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 2) # check bob can NOT get to the hidden object response = self.bob_api_client.get(self.image_measurement_url + "3/", format="json") self.assertHttpUnauthorized(response) # check that anonymous can see public ones as well response = self.anon_api_client.get(self.image_measurement_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 2) # check anonymous can NOT get to the hidden object response = self.anon_api_client.get(self.image_measurement_url + "3/", format="json") self.assertHttpUnauthorized(response)
def test_2api_init(self): print '***================ super: db test_2api_init =============== ' super(TestApiInit, self).test_2api_init() print '***================ local: db test_2api_init =============== ' serializer=CSVSerializer() # todo: doesn't work for post, see TestApiClient.post() method, it is # incorrectly "serializing" the data before posting testApiClient = TestApiClient(serializer=serializer) filename = os.path.join(self.db_directory,'api_init_actions.csv') with open(filename) as input_file: api_init_actions = serializer.from_csv(input_file.read(), root=None) bootstrap_files = [ 'metahash_resource_data.csv', 'vocabularies_data.csv'] for action in api_init_actions: print '\n++++=========== processing action', json.dumps(action) command = action['command'].lower() resource = action['resource'].lower() resource_uri = BASE_REPORTS_URI + '/' + resource if command == 'delete': resp = testApiClient.delete( resource_uri, authentication=self.get_credentials()) self.assertHttpAccepted(resp) else: filename = os.path.join(self.db_directory,action['file']) search_excludes = [] # exclude 'resource_uri' from equivalency check during # bootstrap, because resource table needs to be loaded for # the uri generation if action['file'] in bootstrap_files: search_excludes = ['resource_uri'] logger.info(str(('+++++++++++processing file', filename))) with open(filename) as data_file: input_data = serializer.from_csv(data_file.read()) if command == 'put': resp = testApiClient.put( resource_uri, format='csv', data=input_data, authentication=self.get_credentials() ) logger.debug(str(('action: ', json.dumps(action), 'response: ' , resp.status_code))) self.assertTrue( resp.status_code in [200], str((resp.status_code, resp))) # now see if we can get these objects back resp = testApiClient.get( resource_uri, format='json', authentication=self.get_credentials(), data={ 'limit': 999 }) self.assertTrue( resp.status_code in [200], str((resp.status_code, resp))) # self.assertValidJSONResponse(resp) new_obj = self.deserialize(resp) result, msgs = find_all_obj_in_list( input_data['objects'], new_obj['objects'], excludes=search_excludes) self.assertTrue( result, str((command, 'input file', filename, msgs, new_obj['objects'])) ) elif command == 'patch': resp = testApiClient.patch( resource_uri, format='csv', data=input_data, authentication=self.get_credentials() ) # self.assertHttpAccepted(resp) self.assertTrue(resp.status_code in [202, 204], str(( 'response not accepted, resource_uri:', resource_uri, 'response', resp))) resp = testApiClient.get( resource_uri, format='json', authentication=self.get_credentials(), data={ 'limit': 999 } ) self.assertTrue( resp.status_code in [200], str((resp.status_code, resp))) # self.assertValidJSONResponse(resp) new_obj = self.deserialize(resp) with open(filename) as f2: input_data2 = serializer.from_csv(f2.read()) result, msgs = find_all_obj_in_list( input_data2['objects'], new_obj['objects'], excludes=search_excludes) self.assertTrue( result, str(( command, 'input file', filename, msgs )) ) elif command == 'post': self.fail(( 'resource entry: ' + json.dumps(action) + '; ' 'cannot POST multiple objects to tastypie; ' 'therefore the "post" command is invalid with ' 'the initialization scripts')) else: self.fail('unknown command: ' + command + ', ' + json.dumps(action))
class ResourceTest(ResourceTestCase): serializer = Serializer() def setUp(self): self.api_client = TestApiClient() self.username = '******' self.password = '******' self.user = hydroshare.create_account( '*****@*****.**', username=self.username, password=self.password, first_name='User0_FirstName', last_name='User0_LastName', ) self.api_client.client.login(username=self.username, password=self.password) self.url_proto = '/hsapi/resource/{0}/files/{1}/' self.filename = 'test.txt' def tearDown(self): User.objects.all().delete() GenericResource.objects.all().delete() def test_resource_file_get(self): myfile = open(self.filename, 'w') myfile.write('hello world!\n') myfile.close() myfile = open(self.filename, 'r') res1 = hydroshare.create_resource('GenericResource', self.user, 'res1') hydroshare.add_resource_files(res1.short_id, myfile) url = self.url_proto.format(res1.short_id, self.filename) resp = self.api_client.get(url) self.assertIn(resp.status_code, [201, 200]) def test_resource_file_put(self): myfile = open(self.filename, 'w') myfile.write('hello world!\n') myfile.close() myfile = open(self.filename, 'r') res1 = hydroshare.create_resource('GenericResource', self.user, 'res1') hydroshare.add_resource_files(res1.short_id, myfile) mynewfile = open(self.filename, 'w') mynewfile.write('anyone there?\n') mynewfile.close() mynewfile = open(self.filename, 'r') url = self.url_proto.format(res1.short_id, self.filename) put_data = {'resource_file': mynewfile} resp = self.api_client.put(url, data=put_data) self.assertHttpAccepted(resp) resp = self.api_client.get(url) self.assertIn(resp.status_code, [201, 200]) def test_resource_file_post(self): myfile = open(self.filename, 'w') myfile.write('hello world!\n') myfile.close() myfile = open(self.filename, 'r') res1 = hydroshare.create_resource('GenericResource', self.user, 'res1') post_data = {'resource_file': myfile} url = self.url_proto.format(res1.short_id, self.filename) resp = self.api_client.post(url, data=post_data) self.assertHttpAccepted(resp) resp = self.api_client.get(url) self.assertIn(resp.status_code, [201, 200]) def test_resource_file_delete(self): myfile = open(self.filename, 'w') myfile.write('hello world!\n') myfile.close() myfile = open(self.filename, 'r') res1 = hydroshare.create_resource('GenericResource', self.user, 'res1') hydroshare.add_resource_files(res1.short_id, myfile) url = self.url_proto.format(res1.short_id, self.filename) resp = self.api_client.delete(url) self.assertIn(resp.status_code, [200, 202, 204]) self.assertHttpNotFound(self.api_client.get(url, format='json'))
class TestScientificImageMeasurementResource(ResourceTestCase): def setUp(self): #Tastypie stuff super(TestScientificImageMeasurementResource, self).setUp() self.bob_api_client = TestApiClient() self.bill_api_client = TestApiClient() self.anon_api_client = TestApiClient() # Create a user bob. self.user_bob_username = '******' self.user_bob_password = '******' self.user_bob = User.objects.create_user(self.user_bob_username, '*****@*****.**', self.user_bob_password) # Create a user bob. self.user_bill_username = '******' self.user_bill_password = '******' self.user_bill = User.objects.create_user(self.user_bill_username, '*****@*****.**', self.user_bill_password) self.bob_api_client.client.login(username='******', password='******') self.bill_api_client.client.login(username='******', password='******') #assign users to the Public group public_group, created = Group.objects.get_or_create(name='Public') self.user_bob.groups.add(public_group) self.user_bill.groups.add(public_group) guardian.utils.get_anonymous_user().groups.add(public_group) #make a couple of campaigns and save self.campaign_bobs = mommy.make_one('catamidb.Campaign', id=1) self.campaign_bills = mommy.make_one('catamidb.Campaign', id=2) #make a deployments self.deployment_bobs = mommy.make_recipe('catamidb.auvdeployment1', id=1, campaign=self.campaign_bobs) self.deployment_bills = mommy.make_recipe('catamidb.auvdeployment2', id=2, campaign=self.campaign_bills) #make poses self.pose_bobs = mommy.make_recipe('catamidb.pose1', id=1, deployment=self.deployment_bobs) self.pose_bills = mommy.make_recipe('catamidb.pose2', id=2, deployment=self.deployment_bills) #make cameras self.camera_bobs = mommy.make_one('catamidb.Camera', id=1, deployment=self.deployment_bobs) self.camera_bills = mommy.make_one('catamidb.Camera', id=2, deployment=self.deployment_bills) #make images self.image_bobs = mommy.make_one( 'catamidb.Image', id=1, pose=self. pose_bobs, camera=self.camera_bobs) self.image_bills = mommy.make_one( 'catamidb.Image', id=2, pose=self. pose_bills, camera=self.camera_bills) #make image measurements self.image_measurement_bobs = mommy.make_one( 'catamidb.ScientificImageMeasurement', id=1, image=self.image_bobs ) self.image_measurement_bills = mommy.make_one( 'catamidb.ScientificImageMeasurement', id=2, image=self. image_bills) #assign this one to bob authorization.apply_campaign_permissions( self.user_bob, self.campaign_bobs) #assign this one to bill authorization.apply_campaign_permissions( self.user_bill, self.campaign_bills) #the API url for campaigns self.image_measurement_url = '/api/dev/scientificimagemeasurement/' self.post_data = [] # can only do GET at this stage def test_image_measurement_operations_disabled(self): # test that we can NOT create self.assertHttpMethodNotAllowed( self.anon_api_client.post(self.image_measurement_url, format='json', data=self.post_data)) # test that we can NOT modify self.assertHttpMethodNotAllowed( self.anon_api_client.put( self.image_measurement_url + self.deployment_bobs.id.__str__() + "/", format='json', data={} ) ) # test that we can NOT delete self.assertHttpMethodNotAllowed( self.anon_api_client.delete( self.image_measurement_url + self.deployment_bobs.id.__str__() + "/", format='json' ) ) # test that we can NOT create authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.post( self.image_measurement_url, format='json', data=self.post_data ) ) # test that we can NOT modify authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.put( self.image_measurement_url + self.deployment_bobs.id.__str__() + "/", format='json', data={} ) ) # test that we can NOT delete authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.delete( self.image_measurement_url + self.deployment_bobs.id.__str__() + "/", format='json' ) ) def test_image_measurement_operations_as_authorised_users(self): # create a campaign & deployment that ONLY bill can see bills_campaign = mommy.make_one('catamidb.Campaign', id=3) bills_deployment = mommy.make_recipe('catamidb.auvdeployment', id=3, campaign=bills_campaign) bills_pose = mommy.make_recipe('catamidb.pose3', id=3, deployment=bills_deployment) bills_camera = mommy.make_one('catamidb.Camera', id=3, deployment=bills_deployment) bills_image = mommy.make_one('catamidb.Image', id=3, pose=bills_pose, camera=bills_camera) bills_image_measurement = mommy.make_one( 'catamidb.ScientificImageMeasurement', id=3, image=bills_image) assign('view_campaign', self.user_bill, bills_campaign) # check that bill can see via the API response = self.bill_api_client.get(self.image_measurement_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)['objects']), 3) # check that bill can get to the object itself response = self.bill_api_client.get(self.image_measurement_url + "3/", format='json') self.assertValidJSONResponse(response) # check that bob can not see - now we know tastypie API has correct # permission validation response = self.bob_api_client.get(self.image_measurement_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)['objects']), 2) # check bob can NOT get to the hidden object response = self.bob_api_client.get(self.image_measurement_url + "3/", format='json') self.assertHttpUnauthorized(response) #check that anonymous can see public ones as well response = self.anon_api_client.get(self.image_measurement_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)['objects']), 2) #check anonymous can NOT get to the hidden object response = self.anon_api_client.get(self.image_measurement_url + "3/", format='json') self.assertHttpUnauthorized(response)
class ApiResourceTestCase(ResourceTestCase): # TODO: Using the regular ROOT_URLCONF avoids a problem where failing tests print useless error messages, # because the 500.html error template includes a {% url %} lookup that isn't included in api.urls. # There could be a better way to handle this. # url_base = "/v1" url_base = "/api/v1" server_domain = "perma.dev" server_port = 8999 serve_files = [] rejected_status_code = 401 # Unauthorized # reduce wait times for testing perma.tasks.ROBOTS_TXT_TIMEOUT = perma.tasks.AFTER_LOAD_TIMEOUT = 1 @classmethod def setUpClass(cls): if len(cls.serve_files): cls.start_server() @classmethod def tearDownClass(cls): if getattr(cls, "_server_process", None): cls.kill_server() def setUp(self): super(ApiResourceTestCase, self).setUp() self.api_client = TestApiClient(serializer=MultipartSerializer()) self._media_org = settings.MEDIA_ROOT self._media_tmp = settings.MEDIA_ROOT = tempfile.mkdtemp() try: self.list_url = "{0}/{1}".format(self.url_base, self.resource.Meta.resource_name) except: pass def tearDown(self): settings.MEDIA_ROOT = self._media_org shutil.rmtree(self._media_tmp) def get_credentials(self, user=None): user = user or self.user return "ApiKey %s" % user.api_key.key @classmethod def start_server(cls): """ Set up a server with some known files to run captures against. Example: with run_server_in_temp_folder([ 'test/assets/test.html', 'test/assets/test.pdf', ['test/assets/test.html', 'some_other_url.html']): assert(requests.get("http://localhost/test.html") == contents_of_file("test.html")) assert(requests.get("http://localhost/some_other_url.html") == contents_of_file("test.html")) """ assert socket.gethostbyname(cls.server_domain) in ('0.0.0.0', '127.0.0.1'), "Please add `127.0.0.1 " + cls.server_domain + "` to your hosts file before running this test." # Run in temp dir. # We have to (implicitly) cwd to this so SimpleHTTPRequestHandler serves the files for us. cwd = os.getcwd() cls._server_tmp = tempfile.mkdtemp() os.chdir(cls._server_tmp) # Copy over files to current temp dir, stripping paths. for source_file in cls.serve_files: # handle single strings if isinstance(source_file, basestring): target_url = os.path.basename(source_file) # handle tuple like (source_file, target_url) else: source_file, target_url = source_file copy_file_or_dir(os.path.join(cwd, source_file), target_url) # start server cls._httpd = TestHTTPServer(('', cls.server_port), SimpleHTTPRequestHandler) cls._httpd._BaseServer__is_shut_down = multiprocessing.Event() cls._server_process = Process(target=cls._httpd.serve_forever) cls._server_process.start() # once the server is started, we can return to our working dir # and the server thread will continue to server from the tmp dir os.chdir(cwd) return cls._server_process @classmethod def kill_server(cls): # If you don't close the server before terminating # the thread the port isn't freed up. cls._httpd.server_close() cls._server_process.terminate() shutil.rmtree(cls._server_tmp) @contextmanager def serve_file(self, src): if not getattr(self.__class__, "_server_process", None): self.__class__.start_server() dst = os.path.join(self._server_tmp, os.path.basename(src)) try: copy_file_or_dir(src, dst) yield finally: os.remove(dst) @cached_property def server_url(self): return "http://" + self.server_domain + ":" + str(self.server_port) @contextmanager def header_timeout(self, timeout): prev_t = models.HEADER_CHECK_TIMEOUT try: models.HEADER_CHECK_TIMEOUT = timeout yield finally: models.HEADER_CHECK_TIMEOUT = prev_t def assertValidJSONResponse(self, resp): # Modified from tastypie to allow 201's as well # https://github.com/toastdriven/django-tastypie/blob/master/tastypie/test.py#L448 try: self.assertHttpOK(resp) except AssertionError: self.assertHttpCreated(resp) self.assertTrue(resp['Content-Type'].startswith('application/json')) self.assertValidJSON(force_text(resp.content)) def detail_url(self, obj): return "{0}/{1}".format(self.list_url, obj.pk) def get_req_kwargs(self, kwargs): req_kwargs = {} if kwargs.get('format', None): req_kwargs['format'] = kwargs['format'] if kwargs.get('user', None): req_kwargs['authentication'] = self.get_credentials(kwargs['user']) return req_kwargs def successful_get(self, url, data=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) resp = self.api_client.get(url, data=data, **req_kwargs) self.assertHttpOK(resp) self.assertValidJSONResponse(resp) data = self.deserialize(resp) if kwargs.get('fields', None): self.assertKeys(data, kwargs['fields']) if kwargs.get('count', None): self.assertEqual(len(data['objects']), kwargs['count']) return data def rejected_get(self, url, expected_status_code=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) resp = self.api_client.get(url, **req_kwargs) self.assertEqual(resp.status_code, expected_status_code or self.rejected_status_code) return resp def successful_post(self, url, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) count = self.resource._meta.queryset.count() resp = self.api_client.post(url, data=kwargs['data'], **req_kwargs) self.assertHttpCreated(resp) self.assertValidJSONResponse(resp) # Make sure the count changed self.assertEqual(self.resource._meta.queryset.count(), count+1) return self.deserialize(resp) def rejected_post(self, url, expected_status_code=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) count = self.resource._meta.queryset.count() resp = self.api_client.post(url, data=kwargs['data'], **req_kwargs) self.assertEqual(resp.status_code, expected_status_code or self.rejected_status_code) self.assertEqual(self.resource._meta.queryset.count(), count) return resp def successful_put(self, url, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) if kwargs.get('data', None): req_kwargs['data'] = kwargs['data'] count = self.resource._meta.queryset.count() resp = self.api_client.put(url, **req_kwargs) self.assertHttpAccepted(resp) # Make sure the count hasn't changed self.assertEqual(self.resource._meta.queryset.count(), count) def rejected_put(self, url, expected_status_code=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) if kwargs.get('data', None): req_kwargs['data'] = kwargs['data'] count = self.resource._meta.queryset.count() resp = self.api_client.put(url, **req_kwargs) self.assertEqual(resp.status_code, expected_status_code or self.rejected_status_code) # Make sure the count hasn't changed self.assertEqual(self.resource._meta.queryset.count(), count) def successful_patch(self, url, check_results=True, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) if check_results: # Fetch the existing data for comparison. resp = self.api_client.get(url, **req_kwargs) self.assertHttpOK(resp) self.assertValidJSONResponse(resp) old_data = self.deserialize(resp) new_data = dict(old_data, **kwargs['data']) else: new_data = kwargs['data'] count = self.resource._meta.queryset.count() patch_resp = self.api_client.patch(url, data=new_data, **req_kwargs) self.assertHttpAccepted(patch_resp) # Make sure the count hasn't changed & we did an update. self.assertEqual(self.resource._meta.queryset.count(), count) if check_results: fresh_data = self.deserialize(self.api_client.get(url, **req_kwargs)) for attr in kwargs['data'].keys(): try: # Make sure the data actually changed self.assertNotEqual(fresh_data[attr], old_data[attr]) # Make sure the data changed to what we specified self.assertEqual(fresh_data[attr], new_data[attr]) except AssertionError: # If we specified a nested ID, we'll be getting back an object if str(new_data[attr]).isdigit() and isinstance(fresh_data[attr], dict): self.assertEqual(new_data[attr], fresh_data[attr]['id']) else: raise except KeyError: pass return fresh_data else: return self.deserialize(patch_resp) def rejected_patch(self, url, expected_status_code=None, expected_data=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) old_data = self.deserialize(self.api_client.get(url, **req_kwargs)) # User might not have GET access to grab initial data if old_data: new_data = old_data.copy() new_data.update(kwargs['data']) else: new_data = kwargs['data'] count = self.resource._meta.queryset.count() resp = self.api_client.patch(url, data=new_data, **req_kwargs) self.assertEqual(resp.status_code, expected_status_code or self.rejected_status_code) if expected_data: self.assertDictEqual(self.deserialize(resp), expected_data) self.assertEqual(self.resource._meta.queryset.count(), count) self.assertEqual(self.deserialize(self.api_client.get(url, **req_kwargs)), old_data) return resp def successful_delete(self, url, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) count = self.resource._meta.queryset.count() self.assertHttpOK( self.api_client.get(url, **req_kwargs)) self.assertHttpAccepted( self.api_client.delete(url, **req_kwargs)) self.assertEqual(self.resource._meta.queryset.count(), count-1) self.assertHttpNotFound( self.api_client.get(url, **req_kwargs)) def rejected_delete(self, url, expected_status_code=None, expected_data=None, **kwargs): req_kwargs = self.get_req_kwargs(kwargs) count = self.resource._meta.queryset.count() delete_resp = self.api_client.delete(url, **req_kwargs) self.assertEqual(delete_resp.status_code, expected_status_code or self.rejected_status_code) if expected_data: self.assertDictEqual(self.deserialize(delete_resp), expected_data) self.assertEqual(self.resource._meta.queryset.count(), count) resp = self.api_client.get(url, **req_kwargs) try: # If the user doesn't have access, that's okay - # we were testing delete from an unauthorized user self.assertHttpUnauthorized(resp) except AssertionError: # Check for OK last so that this is the assertion # that shows up as the failure if it doesn't pass self.assertHttpOK(resp) return delete_resp
class TaskResourceTest(ResourceTestCase): fixtures = [ 'group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json', 'task.json' ] def setUp(self): self.api_client = TestApiClient() self.task_id = 1 self.project_part_id = 1 self.task = { 'description': 'new Task', 'project_part': { 'pk': self.project_part_id }, 'flag_finished': 0, 'weight': 20 } self.detail_url = '/api/v1/task/{0}/'.format(self.task_id) self.project_part_query = '='.join( ['?project_part', str(self.project_part_id)]) self.list_url = '/api/v1/task/' self.serializer = Serializer() def get_credentials(self): result = self.api_client.client.login(email='*****@*****.**', password='******') def test_post_list(self): self.get_credentials() self.assertIn('_auth_user_id', self.api_client.client.session) self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) self.assertEqual(Task.objects.count(), 2) resp = self.api_client.post(self.list_url, format='json', data=self.task) self.assertHttpCreated(resp) self.assertEqual(Task.objects.count(), 3) def test_get_list_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.get(''.join( [self.list_url, self.project_part_query]), format='json')) def test_get_list_json(self): self.get_credentials() resp = self.api_client.get(''.join( [self.list_url, self.project_part_query]), format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 2) def test_get_detail_unauthenticated(self): resp = self.api_client.get(self.detail_url, format='json') self.assertHttpUnauthorized(resp) def test_get_detail_json(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['description'], 'new task') # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', # data=self.task)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.put(self.detail_url, format='json', data={})) def test_put_detail(self): self.get_credentials() original_data = json.loads( self.api_client.get(self.detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Task' self.assertEqual(Task.objects.count(), 2) self.assertHttpAccepted( self.api_client.put(self.detail_url, format='json', data=new_data)) self.assertEqual(Task.objects.count(), 2) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized( self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Task.objects.count(), 2) self.assertHttpAccepted( self.api_client.delete(self.detail_url, format='json')) self.assertEqual(Task.objects.count(), 1)