class SetAccessRulesTest(ResourceTestCase): serializer = Serializer() def setUp(self): self.account_url_base = '/hsapi/resource/accessRules/' self.api_client = TestApiClient() def tearDown(self): User.objects.all().delete() Group.objects.all().delete() def test_set_user_rules(self): user = hydroshare.create_account( '*****@*****.**', username='******', first_name='User0_FirstName', last_name='User0_LastName', ) url = '{0}{1}/'.format(self.account_url_base, user.id) put_data = { 'pid': user.id, 'principaltype': 'user', 'principleID': user.id, 'access': 'view', 'allow': 'true' } resp = self.api_client.put(url, data=put_data) self.assertEqual(resp.status_code, 200) def test_set_group_rules(self): group = hydroshare.create_group(name="group0") url = '{0}{1}/'.format(self.account_url_base, group.id) put_data = self.serialize({ 'principaltype': 'group', 'principleID': group.id, 'access': 'view', 'allow': 'true' }) resp = self.api_client.put(url, data=put_data) self.assertEqual(resp.status_code, 200)
class SetResourceOwnerTest(ResourceTestCase): serializer = Serializer() def setUp(self): self.api_client = TestApiClient() self.user = hydroshare.create_account('*****@*****.**', username='******', first_name='User_FirstName', last_name='User_LastName', password='******', superuser=True) self.url_base = '/hsapi/resource/owner/' self.api_client.client.login(username=self.user.username, password=self.user.password) def tearDown(self): User.objects.all().delete() def test_set_owner(self): res = hydroshare.create_resource('GenericResource', self.user, 'res1') user2 = hydroshare.create_account('*****@*****.**', username='******', first_name='User2_FirstName', last_name='User2_LastName', password='******') post_data = {'user': user2.pk, 'api_key': self.user.api_key.key} url = '{0}{1}/'.format(self.url_base, res.short_id) resp = self.api_client.put(url, data=post_data) self.assertEqual(resp.body, res.short_id) hydroshare.delete_resource(res.short_id)
class TestResolveDOIView(ResourceTestCase): serializer = Serializer() def setUp(self): self.api_client = TestApiClient() user = hydroshare.create_account( '*****@*****.**', username='******', first_name='User0_FirstName', last_name='User0_LastName', ) self.res = hydroshare.create_resource('GenericResource', user, 'myres') def tearDown(self): User.objects.all().delete() hydroshare.delete_resource(self.res.short_id) def test_put(self): url = 'hsapi/publishResource/{0}/'.format(self.res.short_id) resp = self.api_client.put(url) self.assertValidJSONResponse(resp) resp_pk = self.deserialize(resp) self.assertEqual(self.res.short_id, resp_pk)
class SetAccessRulesTest(ResourceTestCase): serializer = Serializer() def setUp(self): self.account_url_base = '/hsapi/resource/accessRules/' self.api_client = TestApiClient() def tearDown(self): User.objects.all().delete() Group.objects.all().delete() def test_set_user_rules(self): user = hydroshare.create_account( '*****@*****.**', username='******', first_name='User0_FirstName', last_name='User0_LastName', ) url = '{0}{1}/'.format(self.account_url_base, user.id) put_data = { 'pid':user.id, 'principaltype': 'user', 'principleID': user.id, 'access': 'view', 'allow': 'true' } resp = self.api_client.put(url, data=put_data) self.assertEqual(resp.status_code, 200) def test_set_group_rules(self): group = hydroshare.create_group(name="group0") url = '{0}{1}/'.format(self.account_url_base, group.id) put_data = self.serialize({ 'principaltype': 'group', 'principleID': group.id, 'access': 'view', 'allow': 'true' }) resp = self.api_client.put(url, data=put_data) self.assertEqual(resp.status_code, 200)
def test_put_queue(self): """ Performs PUT request for queue id=2""" client = TestApiClient() response = client.put('/api/queue/2/', data={'place': 990}) # 204 == Action Performed -> No Data self.assertEqual(response.status_code, 204)
def test_put_vars_for_current(self): """ Performs PUT request for mag-current value """ client = TestApiClient() response = client.put('/api/variables/2/', data={'values_used': 215}) # 204 == Action Performed -> No Data self.assertEqual(response.status_code, 204)
def test_put_vars(self): """ Performs PUT request for vars id=1""" client = TestApiClient() response = client.put('/api/variables/1/', data={'values_used': 150}) # 204 == Action Performed -> No Data self.assertEqual(response.status_code, 204)
class SetResourceOwnerTest(ResourceTestCase): serializer = Serializer() def setUp(self): self.api_client = TestApiClient() self.user = hydroshare.create_account( "*****@*****.**", username="******", first_name="User_FirstName", last_name="User_LastName", password="******", superuser=True, ) self.url_base = "/hsapi/resource/owner/" self.api_client.client.login(username=self.user.username, password=self.user.password) def tearDown(self): User.objects.all().delete() def test_set_owner(self): res = hydroshare.create_resource("GenericResource", self.user, "res1") user2 = hydroshare.create_account( "*****@*****.**", username="******", first_name="User2_FirstName", last_name="User2_LastName", password="******", ) post_data = {"user": user2.pk, "api_key": self.user.api_key.key} url = "{0}{1}/".format(self.url_base, res.short_id) resp = self.api_client.put(url, data=post_data) self.assertEqual(resp.body, res.short_id) hydroshare.delete_resource(res.short_id)
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 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 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 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)
class ToDoAppTestCase(TestCase): def setUp(self): self.client = TestApiClient() def test_task_creation(self): due_date = date.today() - timedelta(days=2) for i in range(16): response = self.client.post('/api/v1/task/', data={ "title": "test task 1", "due_date": due_date, "status": "Pending" }) due_date = due_date + timedelta(days=1) self.assertEqual(response.status_code, 201) def test_today_task_fetch(self): self.test_task_creation() response = self.client.get('/api/v1/filter/', data={"during": "today"}) res_obj = response.json() self.assertEqual(response.status_code, 200) self.assertEqual(len(res_obj.get('objects')), 1) def test_this_week_task_fetch(self): self.test_task_creation() response = self.client.get('/api/v1/filter/', data={"during": "this_week"}) res_obj = response.json() today = date.today() start = today week_start = today - timedelta(days=today.weekday()) end = week_start + timedelta(days=6) count = (end - start).days + 1 self.assertEqual(response.status_code, 200) self.assertEqual(len(res_obj.get('objects')), count) def test_next_week_task_fetch(self): self.test_task_creation() response = self.client.get('/api/v1/filter/', data={"during": "next_week"}) res_obj = response.json() self.assertEqual(response.status_code, 200) self.assertEqual(len(res_obj.get('objects')), 7) def test_overdue_task_fetch(self): self.test_task_creation() response = self.client.get('/api/v1/filter/', data={"during": "overdue"}) res_obj = response.json() self.assertEqual(response.status_code, 200) self.assertEqual(len(res_obj.get('objects')), 2) def test_subtask_creation(self): self.test_today_task_fetch() due_date = date.today() response = self.client.post('/api/v1/task/', data={ "title": "test sub task 1", "due_date": due_date, "status": "Pending", "parent": "/api/v1/task/1/" }) self.assertEqual(response.status_code, 201) def test_delete_task(self): self.test_subtask_creation() response = self.client.put('/api/v1/task/2/', data={ "deleted": True, "deletion_date": date.today() }) self.assertEqual(response.status_code, 204) def test_fetch_deleted_task(self): self.test_delete_task() response = self.client.get('/api/v1/deleted/') res_obj = response.json() self.assertEqual(response.status_code, 200) self.assertEqual(len(res_obj.get('objects')), 1)
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 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 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 UserTestBase(ResourceTestCase): def setUp(self): load_states() load_statutes() settings.DEBUG = True self.api_client = TestApiClient() self.get_credentials() #user creates all the groups and requests initially, user should always have edit perms unless another user takes that away self.user = User.objects.create_user('john', '*****@*****.**', 'secret') self.user.is_staff = True#someone has to be responsible self.user.save() self.usertwo = User.objects.create_user('yoko', '*****@*****.**', 'secret') self.userthree = User.objects.create_user('ringo', '*****@*****.**', 'secret') self.post_data = { 'name': 'A TEST GROUP' } self.up, created = UserProfile.objects.get_or_create(user=self.user) self.uptwo, created = UserProfile.objects.get_or_create(user=self.usertwo) self.upthree, created = UserProfile.objects.get_or_create(user=self.userthree) self.groupJSON = None self.group = None self.request = None self.agency = None self.agencyJSON = None self.contact = None self.contactJSON = None self.government = None self.governmentJSON = None def tearDown(self): Request.objects.all().delete() Contact.objects.all_them().delete() Agency.objects.all_them().delete() FeeExemptionOther.objects.all_them().delete() Statute.objects.all_them().delete() Government.objects.all().delete() Group.objects.all().delete() User.objects.all().delete() def get_user_group(self, userToGet): #each user has their own group named after then which they are the sole member of for group in userToGet.groups.all(): if group.name == userToGet.username: return group def create_group(self): #creates the default group and sets default json if self.groupJSON is not None: return self.groupJSON resp = self.api_client.post('/api/v1/group/', format='json', data=self.post_data, authentication=self.get_credentials()) self.group = Group.objects.get(name=self.post_data['name']) self.groupJSON = json.loads(resp.content) return resp def get_group_json(self, group): #gets json for a group resp = self.api_client.get('/api/v1/group/%s/' % group.id, format='json', data={}, authentication=self.get_credentials()) return json.loads(resp.content) def get_user_json(self, userToGet): users_resp = self.api_client.get("/api/v1/user/%s/" % userToGet.id, format='json', authentication=self.get_credentials()) return json.loads(users_resp.content) def add_user_to_group(self, userToAdd): self.create_group() users = self.get_user_json(userToAdd) groupjson = self.groupJSON.copy() groupjson['users'].append(users) update_resp = self.api_client.put(self.groupJSON['resource_uri'], format='json', data=groupjson, authentication=self.get_credentials()) def create_request(self, username=None): request_data = { 'contacts': [], 'free_edit_body': "<p>Something respectable, and testable!</p>", 'private': True, 'title': "test bangarang" } if username is None: self.api_client.post('/api/v1/request/', format='json', data=request_data, authentication=self.get_credentials()) else: self.api_client.post('/api/v1/request/', format='json', data=request_data, authentication=self.get_credentials_other(username)) self.request = Request.objects.get(title=request_data['title']) def get_credentials(self): #log in with self.user credentials result = self.api_client.client.login(username='******', password='******') return result def get_credentials_other(self, username): #log in with self.user credentials result = self.api_client.client.login(username=username, password='******') return result def create_agency(self): self.agencyData = { 'government': Government.objects.get(name="United States of America").id, 'name': "A test agency", 'hidden': False } resp = self.api_client.post('/api/v1/agency/', format='json', data=self.agencyData, authentication=self.get_credentials()) return resp def create_agency(self): if self.agencyJSON is not None: return self.agencyJSON self.agencyData = { 'government': Government.objects.get(name="United States of America").id, 'name': "A test agency", 'hidden': False } resp = self.api_client.post('/api/v1/agency/', format='json', data=self.agencyData, authentication=self.get_credentials()) self.agency = Agency.objects.get(name='A test agency') self.agencyJSON = json.loads(resp.content) return self.agencyJSON def create_contact(self, data=None): if self.agency is None: self.create_agency() if self.contactJSON is not None: return self.contactJSON self.contactData = { 'first_name': "Testy", "last_name": "McTester", "dob": "1990-07-19", "notes": ["nothing much"], "phone_numbers": ["999-999-9999"], "titles": ["Public Information Officer"], "emails": ["*****@*****.**"], "addresses": ["1600 Penn. Washington DC 99999"], "agencyId": self.agency.id } if data is not None: self.contactData = data resp = self.api_client.post('/api/v1/contact/', format='json', data=self.contactData, authentication=self.get_credentials()) self.contactJSON = json.loads(resp.content) self.contact = Contact.objects.get(first_name=self.contactData['first_name'], last_name=self.contactData['last_name']) return self.contactJSON
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 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 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 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 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 AnswerCreationResource(ResourceTestCase): def setUp(self): super(AnswerCreationResource, self).setUp() call_command('loaddata', 'example_data', verbosity=0) self.outbound_message = OutboundMessage.objects.all()[0] self.identifier = OutboundMessageIdentifier.objects.get(outbound_message=self.outbound_message) self.api_client = TestApiClient() self.user = User.objects.all()[0] self.data = {'format': 'json', 'username': self.user.username, 'api_key':self.user.api_key.key} def get_credentials(self): credentials = self.create_apikey(username=self.user.username, api_key=self.user.api_key.key) return credentials def test_I_can_create_an_answer_with_only_an_identifier_and_a_content(self): url = '/api/v1/create_answer/' content = 'Fiera tiene una pulga' answer_data = { 'key':self.identifier.key, 'content':content } previous_answers = Answer.objects.count() response = self.api_client.post(url, data = answer_data, format='json', authentication=self.get_credentials()) self.assertHttpCreated(response) answers_count = Answer.objects.count() self.assertEquals(answers_count, previous_answers + 1) def test_authorization_using_api_key(self): url = '/api/v1/create_answer/' content = 'una sola' answer_data = { 'key':self.identifier.key, 'content':content } response = self.api_client.post(url, data = answer_data, format='json') self.assertHttpUnauthorized(response) def test_only_the_owner_can_create_an_answer(self): not_the_owner = User.objects.create(username='******') his_api_key = not_the_owner.api_key credentials = self.create_apikey(username=not_the_owner.username, api_key=his_api_key.key) url = '/api/v1/create_answer/' content = 'una sola' answer_data = { 'key':self.identifier.key, 'content':content } response = self.api_client.post(url, data = answer_data, format='json', authentication=credentials) self.assertHttpUnauthorized(response) def test_only_post_endpoint(self): url = '/api/v1/create_answer/' content = 'una sola' answer_data = { 'key':self.identifier.key, 'content':content } response = self.api_client.get(url) self.assertHttpMethodNotAllowed(response) response = self.api_client.put(url, data = answer_data) self.assertHttpMethodNotAllowed(response) response = self.api_client.patch(url, data = answer_data) self.assertHttpMethodNotAllowed(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 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 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)
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): 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'))
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 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 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 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 Private_v1__EventResourceTest(ResourceTestCase): fixtures = ['packages.json', 'api_accounts_and_keys.json', 'accounts_and_users.json', 'events.json', 'photos.json'] def setUp(self): super(Private_v1__EventResourceTest, self).setUp() # we need a custom serializer for multipart uploads self.api_client = TestApiClient(serializer=SnapSerializer()) self.api_key = 'key123' self.api_secret = 'sec123' # Fetch the objects we'll use in testing. # Note that we aren't using PKs because they can change depending # on what other tests are running. self.event_1 = Event.objects.all()[0] self.post_data = { 'account': '/private_v1/account/3/', # account 3 has no users 'end': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(time.time() + 60*60)), 'start': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'title': 'My awesome test event', 'url': 'awesome-test-event', 'tz_offset': 0, } self.old_date_data = { 'are_photos_streamable': True, 'end': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(time.time() + 60*60)), 'is_public': False, 'start': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime()), 'title': 'Wedding Republic & Snapable Office Party', 'url': 'wr-snap-party', } self.patch_data = { 'are_photos_streamable': True, 'end_at': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(time.time() + 60*60)), 'is_public': False, 'start_at': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'title': 'Wedding Republic & Snapable Office Party', 'url': 'wr-snap-party', } def get_credentials(self, method, uri): return DatabaseAuthentication.create_signature(self.api_key, self.api_secret, method, uri) def test_get_event(self): uri = '/private_v1/event/{0}/'.format(self.event_1.pk) resp = self.api_client.get(uri, format='json', authentication=self.get_credentials('GET', uri)) # make sure the resource was created self.assertValidJSONResponse(resp) # test to make sure all the keys are in the response self.assertKeys(self.deserialize(resp), [ 'account', 'addons', 'addresses', 'are_photos_streamable', 'cover', 'created', 'created_at', 'creation_date', 'enabled', 'end', 'end_at', 'is_enabled', 'is_public', 'package', 'photo_count', 'pin', 'public', 'resource_uri', 'start', 'start_at', 'title', 'type', 'tz_offset', 'url', 'user', 'uuid' ]) def test_get_events(self): uri = '/private_v1/event/' data_get = {'start_at__gte': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(time.time() - 60))} resp = self.api_client.get(uri, data=data_get, format='json', authentication=self.get_credentials('GET', uri)) # make sure the resource was created self.assertValidJSONResponse(resp) count = self.deserialize(resp)['meta']['total_count'] self.assertTrue(count >= 0) self.assertTrue(count < Event.objects.count()) def test_get_event_cover(self): # this event doesn't have any data in cloud files uri = '/private_v1/event/{0}/'.format(self.event_1.pk) resp = self.api_client.get(uri, format='jpeg', authentication=self.get_credentials('GET', uri)) self.assertHttpNotFound(resp) def test_get_events_search(self): uri_post = '/private_v1/event/' uri_get = '/private_v1/event/search/' data_get = {'q': 'event', 'enabled': 'true', 'order_by': 'end'} events = Event.objects.all() events_count = events.count() # count() checks database, not queryset, so we save now resp_post = self.api_client.post(uri_post, data=self.post_data, format='json', authentication=self.get_credentials('POST', uri_post)) # make sure the resource was created self.assertHttpCreated(resp_post) resp_get = self.api_client.get(uri_get, data=data_get, format='json', authentication=self.get_credentials('GET', uri_get)) # make sure the response is valid self.assertValidJSONResponse(resp_get) # make sure we have some search results self.assertTrue(self.deserialize(resp_get)['meta']['total_count'] > 0) # we should have n+1 where n is existing events (+ 1 new) self.assertEqual(self.deserialize(resp_get)['meta']['total_count'], events_count + 1) # the first should be the new event url self.assertEqual(self.deserialize(resp_get)['objects'][0]['url'], self.post_data['url']) # the second should be the first event url self.assertEqual(self.deserialize(resp_get)['objects'][1]['url'], self.event_1.url) def test_put_event(self): uri_put = '/private_v1/event/{0}/'.format(self.event_1.pk) resp = self.api_client.put(uri_put, data=self.patch_data, format='json', authentication=self.get_credentials('PUT', uri_put)) event = Event.objects.get(pk=self.event_1.pk) event_start = event.start_at.strftime('%Y-%m-%dT%H:%M:%SZ') self.assertEqual(event_start, self.patch_data['start_at']) # deprecated code test resp = self.api_client.put(uri_put, data=self.old_date_data, format='json', authentication=self.get_credentials('PUT', uri_put)) event = Event.objects.get(pk=self.event_1.pk) event_start = event.start_at.strftime('%Y-%m-%d %H:%M:%S') self.assertEqual(event_start, self.old_date_data['start']) def test_patch_event(self): uri_patch = '/private_v1/event/{0}/'.format(self.event_1.pk) resp = self.api_client.patch(uri_patch, data=self.patch_data, format='json', authentication=self.get_credentials('PATCH', uri_patch)) event = Event.objects.get(pk=self.event_1.pk) event_start = event.start_at.strftime('%Y-%m-%dT%H:%M:%SZ') self.assertEqual(event_start, self.patch_data['start_at']) # deprecated code test resp = self.api_client.patch(uri_patch, data=self.old_date_data, format='json', authentication=self.get_credentials('PATCH', uri_patch)) event = Event.objects.get(pk=self.event_1.pk) event_start = event.start_at.strftime('%Y-%m-%d %H:%M:%S') self.assertEqual(event_start, self.old_date_data['start'])
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 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 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 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 AnswerCreationResource(ResourceTestCase): def setUp(self): super(AnswerCreationResource, self).setUp() call_command('loaddata', 'example_data', verbosity=0) self.outbound_message = OutboundMessage.objects.get(id=1) self.identifier = OutboundMessageIdentifier.objects.get( outbound_message=self.outbound_message) self.api_client = TestApiClient() self.user = User.objects.get(id=1) self.data = { 'format': 'json', 'username': self.user.username, 'api_key': self.user.api_key.key } def get_credentials(self): credentials = self.create_apikey(username=self.user.username, api_key=self.user.api_key.key) return credentials def test_I_can_create_an_answer_with_only_an_identifier_and_a_content( self): url = '/api/v1/create_answer/' content = 'Fiera tiene una pulga' answer_data = { 'key': self.identifier.key, 'content': content, } previous_answers = Answer.objects.count() response = self.api_client.post(url, data=answer_data, format='json', authentication=self.get_credentials()) self.assertHttpCreated(response) answers_count = Answer.objects.count() self.assertEquals(answers_count, previous_answers + 1) answer_json = self.deserialize(response) self.assertEquals(answer_json['content'], content) self.assertIn('id', answer_json.keys()) def test_authorization_using_api_key(self): url = '/api/v1/create_answer/' content = 'una sola' answer_data = { 'key': self.identifier.key, 'content': content, } response = self.api_client.post(url, data=answer_data, format='json') self.assertHttpUnauthorized(response) def test_only_the_owner_can_create_an_answer(self): not_the_owner = User.objects.create(username='******') his_api_key = not_the_owner.api_key credentials = self.create_apikey(username=not_the_owner.username, api_key=his_api_key.key) url = '/api/v1/create_answer/' content = 'una sola' answer_data = { 'key': self.identifier.key, 'content': content, } response = self.api_client.post(url, data=answer_data, format='json', authentication=credentials) self.assertHttpUnauthorized(response) def test_only_post_endpoint(self): url = '/api/v1/create_answer/' content = 'una sola' answer_data = { 'key': self.identifier.key, 'content': content, } response = self.api_client.get(url) self.assertHttpMethodNotAllowed(response) response = self.api_client.put(url, data=answer_data) self.assertHttpMethodNotAllowed(response) response = self.api_client.patch(url, data=answer_data) self.assertHttpMethodNotAllowed(response)
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 UserTestBase(ResourceTestCase): def setUp(self): load_states() load_statutes() settings.DEBUG = True self.api_client = TestApiClient() self.get_credentials() #user creates all the groups and requests initially, user should always have edit perms unless another user takes that away self.user = User.objects.create_user('john', '*****@*****.**', 'secret') self.user.is_staff = True #someone has to be responsible self.user.save() self.usertwo = User.objects.create_user('yoko', '*****@*****.**', 'secret') self.userthree = User.objects.create_user('ringo', '*****@*****.**', 'secret') self.post_data = {'name': 'A TEST GROUP'} self.up, created = UserProfile.objects.get_or_create(user=self.user) self.uptwo, created = UserProfile.objects.get_or_create( user=self.usertwo) self.upthree, created = UserProfile.objects.get_or_create( user=self.userthree) self.groupJSON = None self.group = None self.request = None self.agency = None self.agencyJSON = None self.contact = None self.contactJSON = None self.government = None self.governmentJSON = None def tearDown(self): Request.objects.all().delete() Contact.objects.all_them().delete() Agency.objects.all_them().delete() FeeExemptionOther.objects.all_them().delete() Statute.objects.all_them().delete() Government.objects.all().delete() Group.objects.all().delete() User.objects.all().delete() def get_user_group(self, userToGet): #each user has their own group named after then which they are the sole member of for group in userToGet.groups.all(): if group.name == userToGet.username: return group def create_group(self): #creates the default group and sets default json if self.groupJSON is not None: return self.groupJSON resp = self.api_client.post('/api/v1/group/', format='json', data=self.post_data, authentication=self.get_credentials()) self.group = Group.objects.get(name=self.post_data['name']) self.groupJSON = json.loads(resp.content) return resp def get_group_json(self, group): #gets json for a group resp = self.api_client.get('/api/v1/group/%s/' % group.id, format='json', data={}, authentication=self.get_credentials()) return json.loads(resp.content) def get_user_json(self, userToGet): users_resp = self.api_client.get("/api/v1/user/%s/" % userToGet.id, format='json', authentication=self.get_credentials()) return json.loads(users_resp.content) def add_user_to_group(self, userToAdd): self.create_group() users = self.get_user_json(userToAdd) groupjson = self.groupJSON.copy() groupjson['users'].append(users) update_resp = self.api_client.put( self.groupJSON['resource_uri'], format='json', data=groupjson, authentication=self.get_credentials()) def create_request(self, username=None): request_data = { 'contacts': [], 'free_edit_body': "<p>Something respectable, and testable!</p>", 'private': True, 'title': "test bangarang" } if username is None: self.api_client.post('/api/v1/request/', format='json', data=request_data, authentication=self.get_credentials()) else: self.api_client.post( '/api/v1/request/', format='json', data=request_data, authentication=self.get_credentials_other(username)) self.request = Request.objects.get(title=request_data['title']) def get_credentials(self): #log in with self.user credentials result = self.api_client.client.login(username='******', password='******') return result def get_credentials_other(self, username): #log in with self.user credentials result = self.api_client.client.login(username=username, password='******') return result def create_agency(self): self.agencyData = { 'government': Government.objects.get(name="United States of America").id, 'name': "A test agency", 'hidden': False } resp = self.api_client.post('/api/v1/agency/', format='json', data=self.agencyData, authentication=self.get_credentials()) return resp def create_agency(self): if self.agencyJSON is not None: return self.agencyJSON self.agencyData = { 'government': Government.objects.get(name="United States of America").id, 'name': "A test agency", 'hidden': False } resp = self.api_client.post('/api/v1/agency/', format='json', data=self.agencyData, authentication=self.get_credentials()) self.agency = Agency.objects.get(name='A test agency') self.agencyJSON = json.loads(resp.content) return self.agencyJSON def create_contact(self, data=None): if self.agency is None: self.create_agency() if self.contactJSON is not None: return self.contactJSON self.contactData = { 'first_name': "Testy", "last_name": "McTester", "dob": "1990-07-19", "notes": ["nothing much"], "phone_numbers": ["999-999-9999"], "titles": ["Public Information Officer"], "emails": ["*****@*****.**"], "addresses": ["1600 Penn. Washington DC 99999"], "agencyId": self.agency.id } if data is not None: self.contactData = data resp = self.api_client.post('/api/v1/contact/', format='json', data=self.contactData, authentication=self.get_credentials()) self.contactJSON = json.loads(resp.content) self.contact = Contact.objects.get( first_name=self.contactData['first_name'], last_name=self.contactData['last_name']) return self.contactJSON
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)