def testLoggingOutViaAPI(self): """ Check logging out via API method. Check both the user object and genesets. """ client = TestApiClient() # Log in client.post('/api/v1/user/login', format="json", data={ 'username': self.username, 'password': self.password }) # Now, log out client.post('/api/v1/user/logout', format="json", data={}) # Check for access to that user object resp = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(resp) self.assertEqual(self.deserialize(resp)['objects'], []) # Also check access that there is no access to user geneset r2 = client.get('/api/v1/geneset', format="json") self.assertValidJSONResponse(r2) self.assertEqual(self.deserialize(r2)['objects'], [])
class ApplicationTest(ResourceTestCase): def setUp(self): super(ApplicationTest, self).setUp() self.client = TestApiClient() self.endpoint = '/api/v1/apps/' self.format = 'json' # Create one user self.user = User(username="******") self.user.save() # Create on token self.token = UserToken(user=self.user) self.token.save() # list apps def test_get_apps(self): url = "%s?token=%s" % (self.endpoint, self.token.token) request = self.client.get(url, self.format) self.assertValidJSONResponse(request) # list apps details def test_get_apps_details(self): app_id = Application.objects.all()[0].id url = "%s%d/?token=%s" % (self.endpoint, app_id, self.token.token) request = self.client.get(url, self.format) self.assertValidJSONResponse(request)
class PersonResourceTestCase(ResourceTestCase): def setUp(self): super(PersonResourceTestCase, self).setUp() call_command('loaddata', 'example_data', verbosity=0) self.user = User.objects.get(id=1) self.writeitinstance = WriteItInstance.objects.create(name=u"a test", slug=u"a-test", owner=self.user) self.api_client = TestApiClient() 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_get_list_of_messages(self): url = '/api/v1/person/' response = self.api_client.get(url, authentication=self.get_credentials()) self.assertValidJSONResponse(response) persons = self.deserialize(response)['objects'] self.assertEqual(len(persons), Person.objects.count()) # All the instances def test_unauthorized_list_of_persons(self): url = '/api/v1/person/' response = self.api_client.get(url) self.assertHttpUnauthorized(response) def test_the_remote_url_of_the_person_points_to_its_popit_instance(self): url = '/api/v1/person/' response = self.api_client.get(url, authentication=self.get_credentials()) persons = self.deserialize(response)['objects'] self.assertEquals(persons[0]['popit_url'], persons[0]['resource_uri'])
class CheckTokenTest(ResourceTestCase): def setUp(self): super(CheckTokenTest, self).setUp() self.client = TestApiClient() self.endpoint = '/api/v1/token/' self.format = 'json' # Create one user self.user = User(username="******") self.user.save() # Create on token self.token = UserToken(user=self.user) self.token.save() # check for the token ttl def test_check_token(self): url = "%s?token=%s" % (self.endpoint, self.token.token) request = self.client.get(url, self.format) self.assertValidJSONResponse(request) # check for the WRONG token ttl def test_check_wrong_token(self): url = "%s?token=%s" % (self.endpoint, "not-a-valid-token") self.assertHttpUnauthorized(self.client.get(url, self.format)) # check for the NO token ttl def test_check_no_token(self): self.assertHttpUnauthorized(self.client.get(self.endpoint, self.format))
class RefTSGetSites(ResourceTestCase): def setUp(self): self.serializer = Serializer() self.logger = logging.getLogger(__name__) self.api_client = TestApiClient() self.client = Client() self.username = '******' self.password = '******' self.group, _ = Group.objects.get_or_create(name='Hydroshare Author') # 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.group] ) self.wsdl_url_swe = "http://hydroportal.cuahsi.org/SwedishMonitoringData/webapp/cuahsi_1_1.asmx?WSDL" self.wsdl_url_wwo = "http://worldwater.byu.edu/app/index.php/default/services/cuahsi_1_1.asmx?WSDL" self.rest_url = "http://worldwater.byu.edu/interactive/sandbox/services/index.php/cuahsi_1_1.asmx/GetValues?location=WWO:S-PRHD&variable=WWO:JSWL&startDate=&endDate=" self.site_code_swe = "wq2371" self.site_code_wwo = "S-PRHD" self.post_data = { 'title': 'My REST API-created resource', 'resource_type': 'GenericResource' } def tearDown(self): User.objects.all().delete() GenericResource.objects.all().delete() #TODO: This throws an encoding error... # def test_get_sites_wwo(self): # resp = self.api_client.get("/hsapi/_internal/search-sites/?wsdl_url="+self.wsdl_url_wwo) # self.assertEqual(resp.status_code, 200) def test_get_sites_swedish(self): resp = self.api_client.get("/hsapi/_internal/search-sites/?url="+self.wsdl_url_swe) self.assertEqual(resp.status_code, 200) def test_get_variables_wwo(self): resp = self.api_client.get("/hsapi/_internal/search-variables/?url="+self.wsdl_url_wwo+"&site="+self.site_code_wwo) self.assertEqual(resp.status_code, 200) self.assertTrue('Water level' in resp.content)
class RefTSSnotel(ResourceTestCase): def setUp(self): self.serializer = Serializer() self.logger = logging.getLogger(__name__) self.api_client = TestApiClient() self.client = Client() self.username = '******' self.password = '******' self.group, _ = Group.objects.get_or_create(name='Hydroshare Author') # 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.group] ) self.wsdl_url = "http://worldwater.byu.edu/interactive/snotel/services/index.php/cuahsi_1_1.asmx?WSDL" self.rest_url = "http://worldwater.byu.edu/interactive/snotel/services/index.php/cuahsi_1_1.asmx/GetValuesObject?location=SNOTEL:1039&variable=SNOTEL:WTEQ&startDate=2014-10-01&endDate=2015-03-19" self.time_series_base_rest = "/hsapi/_internal/time-series-from-service/?ref_type=rest&service_url=" self.time_series_base_soap = "/hsapi/_internal/time-series-from-service/?ref_type=soap&service_url=" self.site_code_swe = "wq2371" self.site_code_wwo = "S-PRHD" self.post_data = { 'title': 'My REST API-created resource', 'resource_type': 'GenericResource' } def tearDown(self): User.objects.all().delete() GenericResource.objects.all().delete() def test_time_series_from_service_rest(self): url = urllib.quote(self.rest_url) resp = self.api_client.get(self.time_series_base_rest+url) self.assertEqual(resp.status_code, 200) self.assertTrue('visualization' in resp.content) def test_time_series_from_service_soap(self): url = urllib.quote(self.wsdl_url) resp = self.api_client.get(self.time_series_base_soap+url+"&site=823&variable=WTEQ") self.assertEqual(resp.status_code, 200) self.assertTrue('visualization' in resp.content)
class JobTest(ResourceTestCase): def setUp(self): super(JobTest, self).setUp() self.client = TestApiClient() self.endpoint = '/api/v1/jobs/' self.format = 'json' # Create one user self.user = User(username="******") self.user.save() # Create on token self.token = UserToken(user=self.user) self.token.save() # create a job self.job = Job(user=self.user, application=Application.objects.all()[0]) self.job.save() def test_get_job_list(self): url = "%s?token=%s" % (self.endpoint, self.token.token) request = self.client.get(url, self.format) self.assertValidJSONResponse(request) def test_get_job_detail(self): url = "%s%d/?token=%s" % (self.endpoint, self.job.id, self.token.token) request = self.client.get(url, self.format) self.assertValidJSONResponse(request) def test_post_job(self): data = {"application" : "/api/v1/apps/1/"} url = "%s?token=%s" % (self.endpoint, self.token.token) self.assertHttpCreated(self.client.post(url, self.format, data=data)) def test_patch_job(self): job = Job(user=self.user, application=Application.objects.all()[0]) job.save() data = {"progress":"50"} url = "%s%d/?token=%s" % (self.endpoint, job.id, self.token.token) resp = self.client.patch(url, self.format, data=data) self.assertHttpAccepted(resp) def test_delete_job(self): job = Job(user=self.user, application=Application.objects.all()[0]) job.save() url = "%s%d/?token=%s" % (self.endpoint, job.id, self.token.token) self.assertHttpAccepted(self.client.delete(url, self.format))
class TestAnnotationCodesResource(ResourceTestCase): def setUp(self): #Tastypie stuff super(TestAnnotationCodesResource, self).setUp() #make some codes self.codes = mommy.make_many(AnnotationCodes, 10) self.bob_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) self.bob_api_client.client.login(username='******', password='******') #end point for the API self.annotation_code_url = '/api/dev/annotation_code/' def test_get_codes_anon(self): #check annon can get all the codes response = self.anon_api_client.get(self.annotation_code_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), len(self.codes)) #check annon can get the real code value for code in self.codes: response = self.anon_api_client.get(self.annotation_code_url + code.id.__str__() +"/", format='json') self.assertValidJSONResponse(response) code_from_request = self.deserialize(response)['caab_code'].__str__() self.assertEqual(code.caab_code.__str__(), code_from_request) #check bob can get all the codes response = self.bob_api_client.get(self.annotation_code_url, format='json') self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)), len(self.codes)) #check bob can get the real code value for code in self.codes: response = self.bob_api_client.get(self.annotation_code_url + code.id.__str__() +"/", format='json') self.assertValidJSONResponse(response) code_from_request = self.deserialize(response)['caab_code'].__str__() self.assertEqual(code.caab_code.__str__(), code_from_request)
def testCheckAuthorizationNotLoggedIn(self): """ Check that any end-user has no access to user objects OR genesets (since the only geneset at this point is private) if they are not logged in. """ client = TestApiClient() resp = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(resp) self.assertEqual(self.deserialize(resp)['objects'], []) # Check access to genesets r2 = client.get('/api/v1/geneset', format="json") self.assertValidJSONResponse(r2) self.assertEqual(self.deserialize(r2)['objects'], [])
class CreateOrListGroupsTest(ResourceTestCase): serializer = Serializer() def setUp(self): self.api_client = TestApiClient() self.user = hydroshare.create_account( '*****@*****.**', username='******', first_name='User0_FirstName', last_name='User0_LastName', superuser=True, password='******' ) g0=hydroshare.create_group(name="group0") g1=hydroshare.create_group(name="group1") g2=hydroshare.create_group(name="group2") self.user.groups.add(g0,g1,g2) self.g_ids=[g0.id,g1.id,g2.id] self.groups_url_base = '/hsapi/groups/' self.api_client.client.login(username=self.user.username, password=self.user.password) def tearDown(self): Group.objects.all().delete() User.objects.all().delete() def test_create_group(self): post_data = {'name': 'newgroup'} resp = self.api_client.post(self.groups_url_base, data=post_data) self.assertHttpCreated(resp) grouplist = Group.objects.all() num_of_groups=len(grouplist) self.assertTrue(any(Group.objects.filter(name='newgroup'))) self.assertEqual(num_of_groups, 4) def test_list_groups(self): query = self.serialize({'user': self.user.id}) get_data = {'query': query} resp = self.api_client.get(self.groups_url_base, data=get_data) print resp self.assertEqual(resp.status_code, 200) groups = self.deserialize(resp) new_ids = [] for num in range(len(groups)): new_ids.append(groups[num]['id']) self.assertTrue(Group.objects.filter(user='******'.format(num)).exists()) self.assertEqual(str(groups[num]['name']), 'group{0}'.format(num))c self.assertEqual(sorted(self.g_ids), sorted(new_ids))
class PublicMessagesInAPI(ResourceTestCase): def setUp(self): super(PublicMessagesInAPI,self).setUp() call_command('loaddata', 'example_data', verbosity=0) self.user = User.objects.all()[0] self.writeitinstance = WriteItInstance.objects.create(name="a test", slug="a-test", owner=self.user) self.writeitinstance.moderation_needed_in_all_messages = True self.writeitinstance.save() self.person1 = Person.objects.all()[0] self.api_client = TestApiClient() self.data = {'format': 'json', 'username': self.user.username, 'api_key':self.user.api_key.key} def test_non_confirmated_message_not_showing_in_api(self): """Non confirmated message is not in the API""" message = Message.objects.create(content = 'Content 1', author_name='Felipe', author_email="*****@*****.**", subject='public non confirmated message', writeitinstance= self.writeitinstance, persons = [self.person1]) #OK this is just to show that this message is not confirmed self.assertFalse(message.confirmated) self.assertNotIn(message, Message.public_objects.all()) #I've tested this in messages_test.py url = '/api/v1/instance/{0}/messages/'.format(self.writeitinstance.id) response = self.api_client.get(url,data = self.data) self.assertValidJSONResponse(response) messages = self.deserialize(response)['objects'] self.assertFalse(messages)
class GetCapabilities(ResourceTestCase): serializer = Serializer() def setUp(self): self.api_client = TestApiClient() self.user = hydroshare.create_account( "*****@*****.**", username="******", first_name="User_FirstName", last_name="User_LastName" ) self.url_base = "/hsapi/capabilities/" def tearDown(self): User.objects.all().delete() def test_generic(self): res = hydroshare.create_resource("GenericResource", self.user, "res1") url = "{0}{1}/".format(self.url_base, res.short_id) resp = self.api_client.get(url) self.assertValidJSONResponse(resp) capabilities = self.deserialize(resp) self.assertEqual(capabilities, None) def test_other_types(self): pass
class PublicMessagesInAPI(ResourceTestCase): def setUp(self): super(PublicMessagesInAPI, self).setUp() call_command('loaddata', 'example_data', verbosity=0) self.user = User.objects.get(id=1) self.writeitinstance = WriteItInstance.objects.create(name="a test", slug="a-test", owner=self.user) self.writeitinstance.config.moderation_needed_in_all_messages = True self.writeitinstance.config.save() self.person1 = Person.objects.get(id=1) self.api_client = TestApiClient() self.data = {'format': 'json', 'username': self.user.username, 'api_key': self.user.api_key.key} def test_non_confirmated_message_not_showing_in_api(self): """Non confirmated message is not in the API""" message = Message.objects.create( content='Content 1', author_name='Felipe', author_email="*****@*****.**", subject='public non confirmated message', writeitinstance=self.writeitinstance, persons=[self.person1], ) # OK this is just to show that this message is not confirmed self.assertFalse(message.confirmated) self.assertNotIn(message, Message.public_objects.all()) # I've tested this in messages_test.py url = '/api/v1/instance/{0}/messages/'.format(self.writeitinstance.id) response = self.api_client.get(url, data=self.data) self.assertValidJSONResponse(response) messages = self.deserialize(response)['objects'] self.assertFalse(messages)
class GetCapabilities(ResourceTestCase): serializer = Serializer() def setUp(self): self.api_client = TestApiClient() self.user = hydroshare.create_account( '*****@*****.**', username='******', first_name='User_FirstName', last_name='User_LastName', ) self.url_base = '/hsapi/capabilities/' def tearDown(self): User.objects.all().delete() def test_generic(self): res = hydroshare.create_resource('GenericResource', self.user, 'res1') url = '{0}{1}/'.format(self.url_base, res.short_id) resp = self.api_client.get(url) self.assertValidJSONResponse(resp) capabilities = self.deserialize(resp) self.assertEqual(capabilities, None) def test_other_types(self): pass
class PagePaginationTestCase(ResourceTestCase): def setUp(self): super(PagePaginationTestCase, self).setUp() call_command('loaddata', 'example_data', verbosity=0) self.user = User.objects.get(id=1) # self.writeitinstance = WriteItInstance.objects.create(name="a test", slug="a-test", owner=self.user) self.api_client = TestApiClient() self.data = {'format': 'json', 'username': self.user.username, 'api_key': self.user.api_key.key} def test_setting_all_variables(self): request_data = { 'limit': None, 'offset': 0, } objects = Message.objects.all() paginator = PagePaginator(request_data, objects) self.assertIsInstance(paginator, Paginator) def test_get_offset(self): request_data = { 'limit': None, 'offset': 5, } objects = Message.objects.all() paginator = PagePaginator(request_data, objects) self.assertEquals(paginator.get_offset(), request_data['offset']) def assertOffsetEquals(self, page, limit, offset, objects=Message.objects.all()): request_data = { 'limit': limit, 'page': page, } objects = objects paginator = PagePaginator(request_data, objects) self.assertEquals(paginator.get_offset(), offset) def test_get_page(self): self.assertOffsetEquals(1, 1, 0) self.assertOffsetEquals(1, 2, 0) self.assertOffsetEquals(2, 1, 1) self.assertOffsetEquals(2, 2, 2) def test_get_paginated(self): url = '/api/v1/message/' data = self.data data['page'] = 2 data['limit'] = 1 for message in Message.objects.all(): Confirmation.objects.create(message=message) message.recently_confirmated() response = self.api_client.get(url, data=data) # All messages must be confirmed # in order to be in the api messages = self.deserialize(response)['objects'] self.assertEquals( messages[0]['id'], Message.public_objects.order_by('-created')[1].id)
def test_api(username, password): api_client = TestApiClient() result = api_client.client.login(username=username, password=password) #print(api_client.get('http://localhost:8000/sensorimotordb/api/v1/visuomotor_classification_analysis_results/?analysis__experiment=73', format='json')) start = time.time() #print(api_client.get('http://localhost:8000/sensorimotordb/api/v1/full_recording_trial/?condition__in=432,433,437,438,442,443,434,439,444,430,435,440,431,436,441&limit=0', format='json')) #print(api_client.get('http://localhost:8000/sensorimotordb/api/v1/full_recording_trial/?unit_recordings__unit=518&limit=0', format='json')) print(api_client.get('http://localhost:8000/sensorimotordb/api/v1/event/?trial__condition__experiment=108', format='json')) end = time.time() print(end - start)
def testCheckAuthorizationNotLoggedIn(self): """ Check that a user has access to NO user objects if they are not logged in. """ client = TestApiClient() resp = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(resp) self.assertEqual(self.deserialize(resp)['objects'], [])
def testGETInvite(self): """ Test GET invite with a logged in user. Only POST is allowed, so this should return 405. """ client = TestApiClient() client.client.login(username=self.u1, password=self.p1) resp = client.get('/api/v1/user/invite', format="json", data={'email': self.e2}) self.assertHttpMethodNotAllowed(resp)
def testLoggingOutNotLoggedIn(self): """ Test that this just returns Unauthorized and gives users no access to user objects or genesets. """ client = TestApiClient() # Try to log out without logging in, check for Unauthorized response r1 = client.post('/api/v1/user/logout', format="json", data={}) self.assertHttpUnauthorized(r1) self.assertEqual(self.deserialize(r1)['success'], False) # Check that whoever makes this request still has no access to user objects r2 = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(r2) self.assertEqual(self.deserialize(r2)['objects'], []) # Also check access that there is no access to user geneset r3 = client.get('/api/v1/geneset', format="json") self.assertValidJSONResponse(r3) self.assertEqual(self.deserialize(r3)['objects'], [])
def testCheckAuthorizationLoggedIn(self): """ Check that a user has access to user object created previously if they ARE logged in (using the test-client login method). """ client = TestApiClient() client.client.login(username=self.username, password=self.password) resp = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(resp) self.assertEqual( self.deserialize(resp)['objects'][0]['username'], self.username)
def testLoggingInWrongCredentials1(self): """ Check trying (and failing) to authenticate with a previously created user via the API login method. Check both the user object and genesets. """ client = TestApiClient() client.post('/api/v1/user/login', format="json", data={ 'username': self.username, 'password': '******' }) r1 = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(r1) self.assertEqual(self.deserialize(r1)['objects'], []) # Also check that there is no access to user geneset r2 = client.get('/api/v1/geneset', format="json") self.assertValidJSONResponse(r2) self.assertEqual(self.deserialize(r2)['objects'], [])
def testLoggingInWrongCredentials2(self): """ Test logging in with wrong credentials for a user that was created through the API. """ client = TestApiClient() client.post('/api/v1/user', format="json", data=self.post_user2_data) client.post('/api/v1/user/login', format="json", data={ 'username': self.post_user2_data['username'], 'password': '******' }) resp = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(resp) self.assertEqual(self.deserialize(resp)['objects'], []) # Also check that there is no access to user geneset r2 = client.get('/api/v1/geneset', format="json") self.assertValidJSONResponse(r2) self.assertEqual(self.deserialize(r2)['objects'], [])
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') hydroshare.publish_resource(self.res.short_id) def tearDown(self): User.objects.all().delete() hydroshare.delete_resource(self.res.short_id) def test_get(self): url = 'hsapi/resolveDOI/{0}/'.format(self.res.doi) resp = self.api_client.get(url) self.assertValidJSONResponse(resp) resp_pk = self.deserialize(resp) self.assertEqual(self.res.short_id, resp_pk) def test_bad_doi(self): url = 'hsapi/resolveDOI/{0}/'.format('bad_doi') resp = self.api_client.get(url) self.assertEqual(resp.status_code, 404)
def testCheckUserPassword(self): """ Check that users have no access to user objects they just created if they supply the correct username but wrong password (This checks that the password is being set correctly when creating the user). """ client = TestApiClient() client.post('/api/v1/user', format="json", data=self.post_user_data) client.client.login(username=self.post_user_data['username'], password='******') resp = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(resp) self.assertEqual(self.deserialize(resp)['objects'], [])
def testLoggingInWithPreCreatedUser(self): """ Check logging in through API with previously created user. Check access to user object AND user's geneset (self.geneset1, which is not public) """ client = TestApiClient() client.post('/api/v1/user/login', format="json", data={ 'username': self.username, 'password': self.password }) r1 = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(r1) self.assertEqual( self.deserialize(r1)['objects'][0]['username'], self.username) # Check access to user geneset r2 = client.get('/api/v1/geneset', format="json") self.assertValidJSONResponse(r2) self.assertEqual( self.deserialize(r2)['objects'][0]['title'], self.geneset1.title)
def _get_userconfig_from_api(api_auth, api_url=None, requested_userid=None, qualifier=None, view=False): # safe way to talk to either the remote API or the in-process test server from omegaml import settings defaults = settings() api_url = ensure_api_url(api_url, defaults) api_url += '/api/v1/config/' api_url = api_url.replace('//api', '/api') query = [] if requested_userid: query.append('user={}'.format(requested_userid)) if view: query.append('view={}'.format(int(view))) if qualifier: query.append('qualifier={}'.format(qualifier)) api_url += '?' + '&'.join(query) # -- setup appropriate client API if api_url.startswith('http'): import requests server = session_backoff() server_kwargs = dict(auth=api_auth) deserialize = lambda resp: resp.json() elif api_url.startswith('test') or any('test' in v for v in sys.argv): try: from tastypie.test import TestApiClient except ModuleNotFoundError as e: # we need omegaee environment to proceed raise server = TestApiClient() server.close = lambda: None server_kwargs = dict(authentication=api_auth.get_credentials()) deserialize = lambda resp: json.loads(resp.content.decode('utf-8')) else: raise ValueError('invalid api_url {}'.format(api_url)) # -- actual logic to get configs fail_msg = ("Not authenticated using userid {api_auth.username}" " apikey {api_auth.apikey}, error was {resp.status_code} " "using {api_url}\n{resp.content}") resp = server.get(api_url, **server_kwargs) assert resp.status_code == 200, fail_msg.format(**locals()) configs = deserialize(resp) server.close() return configs
class TestGetResourceList(ResourceTestCase): serializer = Serializer() def setUp(self): self.api_client = TestApiClient() self.username = '******' self.password = '******' # create a user self.user = hydroshare.create_account( '*****@*****.**', username=self.username, first_name='Tian', last_name='Gan', superuser=False, password=self.password, groups=[] ) # create a resource self.res = hydroshare.create_resource( 'GenericResource', self.user, 'My resource' ) # create a group self.group = hydroshare.create_group( 'Test group', members=[], owners=[self.user1] ) def tearDown(self): User.objects.all().delete() GenericResource.objects.all().delete() def test_get_resource_list(self): query = self.serialize({'user': self.username, 'keywords': ['a', 'b']}) resp = self.api_client.get('/hsapi/resources/', data=query) self.assertEqual(resp.status_code, 200)
def testCreatingAndAccessingGenesetWithCorrectLogin(self): client = TestApiClient() # Create the second user and log in client.post('/api/v1/user', format="json", data=self.post_user2_data) client.post('/api/v1/user/login', format="json", data=self.post_user2_data) # Create a geneset, check for '201 Created' response post_geneset_data = { # Does not need user info because the API automatically gathers that from the request 'title': 'TestGeneset2', 'organism': '/api/v1/organism/h**o-sapiens', 'abstract': 'Second test geneset created by user.', 'public': False, 'annotations': { 55982: [20671152, 19583951], 18091: [8887666], 67087: [], 22410: [] }, 'xrdb': 'Entrez', 'description': 'First version.', } r1 = client.post('/api/v1/geneset', format="json", data=post_geneset_data) self.assertHttpCreated(r1) # Check that the title for geneset we created matches r2 = client.get('/api/v1/geneset', format="json") self.assertValidJSONResponse(r2) self.assertEqual( self.deserialize(r2)['objects'][0]['title'], post_geneset_data['title']) # And finally, check that this user only has access to the geneset they created, not the first geneset (created in the setUp method by user1) self.assertEqual(len(self.deserialize(r2)['objects']), 1)
def get_user_config_from_api(api_auth, api_url=None, requested_userid=None, view=False): # safe way to talk to either the remote API or the in-process test server defaults = settings() api_url = api_url or defaults.OMEGA_RESTAPI_URL api_url += '/api/v1/config/' api_url = api_url.replace('//api', '/api') query = [] if requested_userid: query.append('user={}'.format(requested_userid)) if view: query.append('view={}'.format(int(view))) api_url += '?' + '&'.join(query) # -- setup appropriate client API if api_url.startswith('http'): import requests server = requests server_kwargs = dict(auth=api_auth) deserialize = lambda resp: resp.json() elif any('test' in v for v in sys.argv): # test support import json from tastypie.test import TestApiClient server = TestApiClient() server_kwargs = dict(authentication=api_auth.get_credentials()) deserialize = lambda resp: json.loads(resp.content.decode('utf-8')) else: raise ValueError('invalid api_url {}'.format(api_url)) # -- actual logic to get configs fail_msg = ("Not authenticated using userid {api_auth.username}" " apikey {api_auth.apikey}, error was {resp.status_code} " "using {api_url}\n{resp.content}") resp = server.get(api_url, **server_kwargs) assert resp.status_code == 200, fail_msg.format(**locals()) configs = deserialize(resp) return configs
def testCreateUserObj(self): """ Check that the end-user can create a user through the API. Check that: a) they have access to this user object they just created via the API if they are logged in (using the test-client login method), and b) the user object is what we expect. """ client = TestApiClient() resp = client.post('/api/v1/user', format="json", data=self.post_user_data) self.assertHttpCreated(resp) client.client.login(username=self.post_user_data['username'], password=self.post_user_data['password']) resp = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(resp) self.assertEqual( self.deserialize(resp)['objects'][0]['username'], self.post_user_data['username'])
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 EncounterParticipantResourceTest(ResourceTestCase): fixtures = ['testing_users.json', 'testing_data.json'] def setUp(self): super(EncounterParticipantResourceTest, self).setUp() self.api_client = TestApiClient() self.username = '******' self.password = '******' self.user = User.objects.create_superuser(self.username, '*****@*****.**', self.password) self.encounter_participant = EncounterParticipant.objects.get(id=1) def get_credentials(self): return self.api_client.client.login(username=self.username, password=self.password) def test_pc_initiative_save_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.patch('/dm/api/v1/encounter_participant/1/', format='json', data={'initiative': 5})) def test_pc_initiative_save(self): """ Should save initiative for PC """ resp = self.api_client.patch('/dm/api/v1/encounter_participant/1/', authorization=self.get_credentials(), format='json', data={'initiative': 5}) self.assertHttpAccepted(resp) resp = self.api_client.get('/dm/api/v1/encounter_participant/1/', format='json', authentication=self.get_credentials()) self.assertEqual(self.deserialize(resp)['initiative'], 5)
def testLoggingInWithAPICreatedUser(self): """ Check logging in through API with user created through API. Enforcing csrf checks through Django/Tastypie test client is not really possible. """ client = TestApiClient() # Create new user through API r1 = client.post('/api/v1/user', format="json", data=self.post_user2_data) self.assertHttpCreated(r1) # Login through API client.post('/api/v1/user/login', format="json", data=self.post_user2_data) resp = client.get('/api/v1/user', format="json") self.assertValidJSONResponse(resp) self.assertEqual( self.deserialize(resp)['objects'][0]['username'], self.post_user2_data['username'])
def testCreatingGenesetWithNewUser(self): client = TestApiClient() # Create user and log in client.post('/api/v1/user', format="json", data=self.post_user_data) client.client.login(username=self.post_user_data['username'], password=self.post_user_data['password']) post_geneset_data = { # Does not need user info because the API automatically gathers that from the request 'title': 'TestGeneset2', 'organism': '/api/v1/organism/h**o-sapiens', 'abstract': 'Second test geneset created by user.', 'public': False, 'annotations': { 55982: [20671152, 19583951], 18091: [8887666], 67087: [], 22410: [] }, 'xrdb': 'Entrez', 'description': 'First version.', } # Create a geneset, check for '201 Created' response r1 = client.post('/api/v1/geneset', format="json", data=post_geneset_data) self.assertHttpCreated(r1) # Check that the title for geneset we created matches r2 = client.get('/api/v1/geneset', format="json") self.assertValidJSONResponse(r2) self.assertEqual( self.deserialize(r2)['objects'][0]['title'], post_geneset_data['title'])
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 ApiTestCase(ResourceTestCase): fixtures = ['app/detective/fixtures/default_topics.json', 'app/detective/fixtures/search_terms.json',] def setUp(self): super(ApiTestCase, self).setUp() # Use custom api client self.api_client = TestApiClient() self.salt = SaltMixin.salt self.super_username = '******' self.super_password = '******' self.super_email = '*****@*****.**' self.contrib_username = '******' self.contrib_password = '******' self.contrib_email = '*****@*****.**' self.lambda_username = '******' self.lambda_password = '******' self.lambda_email = '*****@*****.**' contributors = Group.objects.get(name='energy_contributor') # Create the new user users super_user = User.objects.create( username=self.super_username, email=self.super_email, is_staff=True, is_superuser = True ) super_user.set_password(self.super_password) super_user.save() self.super_user = super_user contrib_user = User.objects.create( username=self.contrib_username, email=self.contrib_email, is_active=True ) contrib_user.groups.add(contributors) contrib_user.set_password(self.contrib_password) contrib_user.save() self.contrib_user = contrib_user lambda_user = User.objects.create( username=self.lambda_username, email=self.lambda_email, ) lambda_user.set_password(self.lambda_password) lambda_user.save() self.lambda_user = lambda_user # Create related objects self.jpp = Organization(name=u"Journalism++") self.jpp._author = [super_user.pk] self.jpp.founded = datetime(2011, 4, 3) self.jpp.website_url = 'http://jplusplus.com' self.jpp.save() self.jg = Organization(name=u"Journalism Grant") self.jg._author = [super_user.pk] self.jg.save() self.fra = Country(name=u"France", isoa3=u"FRA") self.fra.save() self.pr = Person(name=u"Pierre Roméra") self.pr.based_in.add(self.fra) self.pr.activity_in_organization.add(self.jpp) self.pr.save() self.pb = Person(name=u"Pierre Bellon") self.pb.based_in.add(self.fra) self.pb.activity_in_organization.add(self.jpp) self.pb.save() # Creates Christmas topic ontology = File(open(settings.DATA_ROOT + "/ontology-v5.7.owl")) self.christmas = Topic(slug=u"christmas", title="It's christmas!", ontology_as_owl=ontology, author=super_user) self.christmas.save() # Creates Thanksgiving topic self.thanksgiving = Topic(slug=u"thanksgiving", title="It's thanksgiving!", ontology_as_owl=ontology, author=super_user) self.thanksgiving.save() self.post_data_simple = { "name": "Lorem ispum TEST", "twitter_handle": "loremipsum" } self.post_data_related = { "name": "Lorem ispum TEST RELATED", "owner": [ { "id": self.jpp.id }, { "id": self.jg.id } ], "activity_in_country": [ { "id": self.fra.id } ] } self.rdf_jpp = { "label": u"Person that has activity in Journalism++", "object": { "id": self.jpp.id, "model": u"Organization", "name": u"Journalism++" }, "predicate": { "label": u"has activity in", "name": u"activity_in_organization", "subject": u"Person" }, "subject": { "label": u"Person", "name": u"Person" } } def cleanModel(self, model_instance): if model_instance: model_instance.delete() def tearDown(self): # Clean & delete generated data # individuals self.cleanModel(self.jpp) # organization self.cleanModel(self.jg) # organization self.cleanModel(self.fra) # country self.cleanModel(self.pr) # people self.cleanModel(self.pb) # people # Simply flush the database management.call_command('flush', verbosity=0, interactive=False) # Utility functions (Auth, operation etc.) def login(self, username, password): return self.api_client.client.login(username=username, password=password) def get_super_credentials(self): return self.login(self.super_username, self.super_password) def get_contrib_credentials(self): return self.login(self.contrib_username, self.contrib_password) def get_lambda_credentials(self): return self.login(self.lambda_username, self.lambda_password) def signup_user(self, user_dict): """ Utility method to signup through API """ return self.api_client.post('/api/common/v1/user/signup/', format='json', data=user_dict) def patch_individual(self, scope=None, model_name=None, model_id=None, patch_data=None, auth=None, skip_auth=False): if not skip_auth and not auth: auth = self.get_super_credentials() url = '/api/%s/v1/%s/%d/patch/' % (scope, model_name, model_id) return self.api_client.post(url, format='json', data=patch_data, authentication=auth) def check_permissions(self, permissions=None, user=None): user_permissions = list(user.get_all_permissions()) self.assertEqual(len(user_permissions), len(permissions)) for perm in user_permissions: self.assertTrue(perm in permissions) # All test functions def test_user_signup_succeed(self): """ Test with proper data to signup user Expected: HTTT 201 (Created) """ user_dict = dict(username=u"newuser", password=u"newuser", email=u"*****@*****.**") resp = self.signup_user(user_dict) self.assertHttpCreated(resp) def test_user_signup_empty_data(self): """ Test with empty data to signup user Expected: HTTP 400 (BadRequest) """ user_dict = dict(username=u"", password=u"", email=u"") resp = self.signup_user(user_dict) self.assertHttpBadRequest(resp) def test_user_signup_no_data(self): resp = self.api_client.post('/api/common/v1/user/signup/', format='json') self.assertHttpBadRequest(resp) def test_user_signup_existing_user(self): user_dict = dict(username=self.super_username, password=self.super_password, email=self.super_email) resp = self.signup_user(user_dict) self.assertHttpForbidden(resp) def test_user_activate_succeed(self): user_dict = dict(username='******', password='******', email='*****@*****.**') self.assertHttpCreated(self.signup_user(user_dict)) innactive_user = User.objects.get(email=user_dict.get('email')) activation_profile = RegistrationProfile.objects.get(user=innactive_user) activation_key = activation_profile.activation_key resp_activate = self.api_client.get('/api/common/v1/user/activate/?token=%s' % activation_key) self.assertHttpOK(resp_activate) user = User.objects.get(email=user_dict.get('email')) self.assertTrue(user.is_active) def test_user_activate_fake_token(self): resp = self.api_client.get('/api/common/v1/user/activate/?token=FAKE') self.assertHttpForbidden(resp) def test_user_activate_no_token(self): resp = self.api_client.get('/api/common/v1/user/activate/') self.assertHttpBadRequest(resp) def test_user_activate_empty_token(self): resp = self.api_client.get('/api/common/v1/user/activate/?token') self.assertHttpBadRequest(resp) def test_user_contrib_login_succeed(self): auth = dict(username=self.contrib_username, password=self.contrib_password) resp = self.api_client.post('/api/common/v1/user/login/', format='json', data=auth) self.assertValidJSON(resp.content) data = json.loads(resp.content) self.assertTrue(data["success"]) self.check_permissions(permissions=data.get("permissions"), user=self.contrib_user) def test_user_login_succeed(self): auth = dict(username=self.super_username, password=self.super_password) resp = self.api_client.post('/api/common/v1/user/login/', format='json', data=auth) self.assertValidJSON(resp.content) # Parse data to check the number of result data = json.loads(resp.content) self.assertEqual(data["success"], True) def test_user_login_failed(self): auth = dict(username=self.super_username, password=u"awrongpassword") resp = self.api_client.post('/api/common/v1/user/login/', format='json', data=auth) self.assertValidJSON(resp.content) # Parse data to check the number of result data = json.loads(resp.content) self.assertEqual(data["success"], False) def test_user_logout_succeed(self): # First login auth = dict(username=self.super_username, password=self.super_password) self.api_client.post('/api/common/v1/user/login/', format='json', data=auth) # Then logout resp = self.api_client.get('/api/common/v1/user/logout/', format='json') self.assertValidJSON(resp.content) # Parse data to check the number of result data = json.loads(resp.content) self.assertEqual(data["success"], True) def test_user_logout_failed(self): resp = self.api_client.get('/api/common/v1/user/logout/', format='json') self.assertValidJSON(resp.content) # Parse data to check the number of result data = json.loads(resp.content) self.assertEqual(data["success"], False) def test_user_permissions_is_logged(self): auth = dict(username=self.contrib_username, password=self.contrib_password) self.api_client.post('/api/common/v1/user/login/', format='json', data=auth) resp = self.api_client.get('/api/common/v1/user/permissions/', format='json') self.assertValidJSON(resp.content) data = json.loads(resp.content) self.check_permissions(permissions=data.get("permissions"), user=self.contrib_user) def test_user_permissions_isnt_logged(self): resp = self.api_client.get('/api/common/v1/user/permissions/', format='json') self.assertHttpUnauthorized(resp) def test_user_status_isnt_logged(self): resp = self.api_client.get('/api/common/v1/user/status/', format='json') self.assertValidJSON(resp.content) # Parse data to check the number of result data = json.loads(resp.content) self.assertEqual(data["is_logged"], False) def test_user_status_is_logged(self): # Log in auth = dict(username=self.super_username, password=self.super_password) resp = self.api_client.post('/api/common/v1/user/login/', format='json', data=auth) self.assertValidJSON(resp.content) data = json.loads(resp.content) self.assertTrue(data['success']) resp = self.api_client.get('/api/common/v1/user/status/', format='json') self.assertValidJSON(resp.content) # Parse data to check the number of result data = json.loads(resp.content) self.assertEqual(data["is_logged"], True) def test_contrib_user_status_is_logged(self): # Log in auth = dict(username=self.contrib_username, password=self.contrib_password, remember_me=True) resp = self.api_client.post('/api/common/v1/user/login/', format='json', data=auth) self.assertValidJSON(resp.content) data = json.loads(resp.content) self.assertTrue(data['success']) resp = self.api_client.get('/api/common/v1/user/status/', format='json') self.assertValidJSON(resp.content) # Parse data to check the number of result data = json.loads(resp.content) self.assertEqual(data["is_logged"], True) def test_reset_password_success(self): email = dict(email=self.super_email) resp = self.api_client.post('/api/common/v1/user/reset_password/', format='json', data=email) self.assertValidJSON(resp.content) # Parse data to check the number of result data = json.loads(resp.content) self.assertTrue(data['success']) def test_reset_password_wrong_email(self): email = dict(email="*****@*****.**") resp = self.api_client.post('/api/common/v1/user/reset_password/', format='json', data=email) self.assertEqual(resp.status_code in [302, 404], True) def test_reset_password_no_data(self): resp = self.api_client.post('/api/common/v1/user/reset_password/', format='json') self.assertHttpBadRequest(resp) def test_reset_password_empty_email(self): resp = self.api_client.post('/api/common/v1/user/reset_password/', format='json', data=dict(email='')) self.assertHttpBadRequest(resp) def test_reset_password_confirm_succes(self): """ Test to successfuly reset a password with a new one. Expected: HTTP 200 - OK """ token = signing.dumps(self.super_user.pk, salt=self.salt) password = "******" auth = dict(password=password, token=token) resp = self.api_client.post( '/api/common/v1/user/reset_password_confirm/', format='json', data=auth ) self.assertValidJSON(resp.content) data = json.loads(resp.content) self.assertTrue(data['success']) # we query users to get the latest user object (updated with password) user = User.objects.get(email=self.super_user.email) self.assertTrue(user.check_password(password)) def test_reset_password_confirm_no_data(self): """ Test on reset_password_confirm API endpoint without any data. Expected response: HTTP 400 (BadRequest). Explanation: Every request on /reset_password_confirm/ must have a JSON data payload. { password: ... // the password to reset" token: ... // the reset password token (received by emai) } """ resp = self.api_client.post('/api/common/v1/user/reset_password_confirm/', format='json') self.assertHttpBadRequest(resp) self.assertIsNotNone(resp.content) def test_reset_password_confirm_empty_data(self): """ Test on reset_password_confirm API endpoint with empty data: { password: "" token: "" } Expected result: HTTP 400 (BadRequest) Explanation: A reset_password_confirm request must have a password and should be authenticated with a token. """ auth = dict(password='', token='') resp = self.api_client.post('/api/common/v1/user/reset_password_confirm/', format='json', data=auth) self.assertHttpBadRequest(resp) def test_reset_password_confirm_fake_token(self): """ Test on reset_password_confirm API endpoint with empty data: { password: "" token: "" } Expected result: HTTP 403 (Forbidden) Explanation: A reset_password_confirm request should be authenticated with a valid token. """ fake_token = 'f4k:t0k3N' auth = dict(password='******', token=fake_token) resp = self.api_client.post( '/api/common/v1/user/reset_password_confirm/', format='json', data=auth ) self.assertHttpForbidden(resp) def test_get_list_json(self): resp = self.api_client.get('/api/energy/v1/energyproject/?limit=20', format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(resp) # Number of element on the first page count = min(20, EnergyProject.objects.count()) self.assertEqual( len(self.deserialize(resp)['objects']), count) def test_post_list_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.post('/api/energy/v1/energyproject/', format='json', data=self.post_data_simple)) def test_post_list_staff(self): # Check how many are there first. count = EnergyProject.objects.count() self.assertHttpCreated( self.api_client.post('/api/energy/v1/energyproject/', format='json', data=self.post_data_simple, authentication=self.get_super_credentials() ) ) # Verify a new one has been added. self.assertEqual(EnergyProject.objects.count(), count+1) def test_post_list_contributor(self): # Check how many are there first. count = EnergyProject.objects.count() self.assertHttpCreated( self.api_client.post('/api/energy/v1/energyproject/', format='json', data=self.post_data_simple, authentication=self.get_contrib_credentials() ) ) # Verify a new one has been added. self.assertEqual(EnergyProject.objects.count(), count+1) def test_post_list_lambda(self): self.assertHttpUnauthorized( self.api_client.post('/api/energy/v1/energyproject/', format='json', data=self.post_data_simple, authentication=self.get_lambda_credentials() ) ) def test_post_list_related(self): # Check how many are there first. count = EnergyProject.objects.count() # Record API response to extract data resp = self.api_client.post('/api/energy/v1/energyproject/', format='json', data=self.post_data_related, authentication=self.get_super_credentials() ) # Vertify the request status self.assertHttpCreated(resp) # Verify a new one has been added. self.assertEqual(EnergyProject.objects.count(), count+1) # Are the data readable? self.assertValidJSON(resp.content) # Parse data to verify relationship data = json.loads(resp.content) self.assertEqual(len(data["owner"]), len(self.post_data_related["owner"])) self.assertEqual(len(data["activity_in_country"]), len(self.post_data_related["activity_in_country"])) def test_mine(self): resp = self.api_client.get('/api/energy/v1/organization/mine/', format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(resp) # Parse data to check the number of result data = json.loads(resp.content) self.assertEqual( len(data["objects"]), 2) def test_mine_empty(self): resp = self.api_client.get('/api/energy/v1/organization/mine/', format='json') self.assertValidJSONResponse(resp) # Parse data to check the number of result data = json.loads(resp.content) self.assertEqual( len(data["objects"]), 0) def test_search_organization(self): resp = self.api_client.get('/api/energy/v1/organization/search/?q=Journalism', format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(resp) # Parse data to check the number of result data = json.loads(resp.content) # At least 2 results self.assertGreater( len(data.items()), 1 ) def test_search_organization_wrong_page(self): resp = self.api_client.get('/api/energy/v1/organization/search/?q=Roméra&page=10000', format='json', authentication=self.get_super_credentials()) self.assertEqual(resp.status_code in [302, 404], True) def test_cypher_detail(self): resp = self.api_client.get('/api/common/v1/cypher/111/', format='json', authentication=self.get_super_credentials()) self.assertTrue(resp.status_code in [302, 404]) def test_cypher_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.get('/api/common/v1/cypher/?q=START%20n=node%28*%29RETURN%20n;', format='json')) def test_cypher_unauthorized(self): # Ensure the user isn't authorized to process cypher request self.super_user.is_staff = True self.super_user.is_superuser = False self.super_user.save() self.assertHttpUnauthorized(self.api_client.get('/api/common/v1/cypher/?q=START%20n=node%28*%29RETURN%20n;', format='json', authentication=self.get_super_credentials())) def test_cypher_authorized(self): # Ensure the user IS authorized to process cypher request self.super_user.is_superuser = True self.super_user.save() self.assertValidJSONResponse(self.api_client.get('/api/common/v1/cypher/?q=START%20n=node%28*%29RETURN%20n;', format='json', authentication=self.get_super_credentials())) def test_summary_list(self): resp = self.api_client.get('/api/common/v1/summary/', format='json') self.assertEqual(resp.status_code in [302, 404], True) def test_summary_mine_success(self): resp = self.api_client.get('/api/energy/v1/summary/mine/', authentication=self.get_super_credentials(), format='json') self.assertValidJSONResponse(resp) # Parse data to check the number of result data = json.loads(resp.content) objects = data['objects'] self.assertIsNotNone(find(lambda x: x['label'] == self.jpp.name, objects)) self.assertIsNotNone(find(lambda x: x['label'] == self.jg.name, objects)) def test_summary_mine_unauthenticated(self): resp = self.api_client.get('/api/energy/v1/summary/mine/', format='json') self.assertValidJSONResponse(resp) # Parse data to check the number of result data = json.loads(resp.content) objects = data['objects'] self.assertEqual(len(objects), 0) def test_countries_summary(self): resp = self.api_client.get('/api/energy/v1/summary/countries/', format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(resp) # Parse data to check the number of result data = json.loads(resp.content) # Only France is present self.assertGreater(len(data), 0) # We added 1 relation to France self.assertEqual("count" in data["FRA"], True) def test_forms_summary(self): resp = self.api_client.get('/api/energy/v1/summary/forms/', format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(resp) # Parse data to check the number of result data = json.loads(resp.content) # As many descriptors as models self.assertEqual( 11, len(data.items()) ) def test_types_summary(self): resp = self.api_client.get('/api/energy/v1/summary/types/', format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(resp) def test_search_summary(self): resp = self.api_client.get('/api/energy/v1/summary/search/?q=Journalism', format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(resp) # Parse data to check the number of result data = json.loads(resp.content) # At least 2 results self.assertGreater( len(data.items()), 1 ) def test_search_summary_wrong_offset(self): resp = self.api_client.get('/api/energy/v1/summary/search/?q=Journalism&offset=-1', format='json', authentication=self.get_super_credentials()) self.assertEqual(resp.status_code in [302, 404], True) def test_summary_human_search(self): query = "Person activity in Journalism" resp = self.api_client.get('/api/energy/v1/summary/human/?q=%s' % query, format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(resp) data = json.loads(resp.content) self.assertGreater(len(data['objects']), 1) def test_rdf_search(self): # RDF object for persons that have activity in J++, we need to urlencode # the JSON string to avoid '+' loss rdf_str = urllib.quote(json.dumps(self.rdf_jpp)) url = '/api/energy/v1/summary/rdf_search/?limit=20&offset=0&q=%s' % rdf_str resp = self.api_client.get(url, format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(resp) data = json.loads(resp.content) objects = data['objects'] self.assertIsNotNone(find(lambda x: x['name'] == self.pr.name, objects)) self.assertIsNotNone(find(lambda x: x['name'] == self.pb.name, objects)) def test_patch_individual_date_staff(self): """ Test a patch request on an invidividual's date attribute. Request: /api/energy/v1/organization/ Expected: HTTP 200 (OK) """ # date are subject to special process with patch method. new_date = datetime(2011, 4, 1, 0, 0, 0, 0) data = { 'founded': new_date.strftime('%Y-%m-%dT%H:%M:%S.%fZ'), } args = { 'scope' : 'energy', 'model_id' : self.jpp.id, 'model_name' : 'organization', 'patch_data' : data } resp = self.patch_individual(**args) self.assertHttpOK(resp) self.assertValidJSONResponse(resp) updated_jpp = Organization.objects.get(name=self.jpp.name) self.assertEqual(timezone.make_naive(updated_jpp.founded), new_date) def test_patch_individual_website_staff(self): jpp_url = 'http://jplusplus.org' data = { 'website_url': jpp_url, } args = { 'scope' : 'energy', 'model_id' : self.jpp.id, 'model_name' : 'organization', 'patch_data' : data } resp = self.patch_individual(**args) self.assertHttpOK(resp) self.assertValidJSONResponse(resp) updated_jpp = Organization.objects.get(name=self.jpp.name) self.assertEqual(updated_jpp.website_url, jpp_url) def test_patch_individual_website_unauthenticated(self): jpp_url = 'http://jplusplus.org' data = { 'website_url': jpp_url, } args = { 'scope' : 'energy', 'model_id' : self.jpp.id, 'model_name' : 'organization', 'patch_data' : data, 'skip_auth' : True, } resp = self.patch_individual(**args) self.assertHttpUnauthorized(resp) def test_patch_individual_website_contributor(self): jpp_url = 'http://www.jplusplus.org' data = { 'website_url': jpp_url, } args = { 'scope' : 'energy', 'model_id' : self.jpp.id, 'model_name' : 'organization', 'patch_data' : data, 'auth' : self.get_contrib_credentials(), } resp = self.patch_individual(**args) self.assertHttpOK(resp) self.assertValidJSONResponse(resp) updated_jpp = Organization.objects.filter(name=self.jpp.name)[0] self.assertEqual(updated_jpp.website_url, jpp_url) def test_patch_individual_website_lambda(self): jpp_url = 'http://bam.jplusplus.org' data = { 'website_url': jpp_url, } args = { 'scope' : 'energy', 'model_id' : self.jpp.id, 'model_name' : 'organization', 'patch_data' : data, 'auth' : self.get_lambda_credentials(), } resp = self.patch_individual(**args) self.assertHttpUnauthorized(resp) def test_patch_individual_not_found(self): jpp_url = 'http://jplusplus.org' data = { 'website_url': jpp_url, } args = { 'scope' : 'energy', 'model_id' : 1337, 'model_name' : 'organization', 'patch_data' : data, } resp = self.patch_individual(**args) self.assertEqual(resp.status_code in [302, 404], True) def test_topic_endpoint_exists(self): resp = self.api_client.get('/api/common/v1/topic/?slug=christmas', follow=True, format='json') # Parse data to check the number of result data = json.loads(resp.content) # 1 result self.assertEqual( len( data["objects"] ), 1 ) def test_topic_api_exists(self): resp = self.api_client.get('/api/christmas/v1/', format='json') self.assertValidJSONResponse(resp) def test_topic_has_person(self): resp = self.api_client.get('/api/christmas/v1/', format='json') self.assertValidJSONResponse(resp) def test_topic_multiple_api(self): # API 1 resp = self.api_client.get('/api/christmas/v1/', format='json') self.assertValidJSONResponse(resp) # API 2 resp = self.api_client.get('/api/thanksgiving/v1/', format='json') self.assertValidJSONResponse(resp) def test_topic_has_summary_syntax_from_ontology(self): resp = self.api_client.get('/api/christmas/v1/summary/syntax/', format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(resp) def test_topic_has_summary_syntax_from_file(self): resp = self.api_client.get('/api/energy/v1/summary/syntax/', format='json', authentication=self.get_super_credentials()) self.assertValidJSONResponse(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 MessagesPerInstanceTestCase(ResourceTestCase): def setUp(self): super(MessagesPerInstanceTestCase, self).setUp() call_command('loaddata', 'example_data', verbosity=0) self.user = User.objects.get(id=1) self.writeitinstance = WriteItInstance.objects.create(name=u"a test", slug=u"a-test", owner=self.user) self.api_client = TestApiClient() self.data = {'format': 'json', 'username': self.user.username, 'api_key': self.user.api_key.key} # creating messages self.pedro = Person.objects.get(id=1) # Setting that the contact is related to self.writeitinstance rather than to the user self.contact = self.pedro.contact_set.all()[0] self.contact.writeitinstance = self.writeitinstance self.contact.save() self.message1 = Message.objects.create( content='Content 1', author_name='Felipe', author_email="*****@*****.**", subject='Fiera es una perra feroz', writeitinstance=self.writeitinstance, persons=[self.pedro], ) # Confirmating Confirmation.objects.create(message=self.message1) self.message1.recently_confirmated() # Confirmating self.marcel = Person.objects.get(id=2) self.message2 = Message.objects.create( content='Content 1', author_name='Felipe', author_email="*****@*****.**", subject='Fiera es una perra feroz', writeitinstance=self.writeitinstance, persons=[self.marcel], ) # Confirmating message 2 Confirmation.objects.create(message=self.message2) self.message2.recently_confirmated() # confirmating message 2 def test_get_list_of_messages_per_instance(self): url = '/api/v1/instance/{0}/messages/'.format(self.writeitinstance.id) response = self.api_client.get(url, data=self.data) self.assertValidJSONResponse(response) messages = self.deserialize(response)['objects'] self.assertGreater(len(messages), 0) filtered_messages = Message.objects.filter(writeitinstance=self.writeitinstance) self.assertEqual(len(messages), filtered_messages.count()) # All the instances self.assertTrue(filtered_messages.filter(id=messages[0]['id'])) # assert that answers come in the def test_filter_by_person(self): url = '/api/v1/instance/%(writeitinstance_id)i/messages/' % { 'writeitinstance_id': self.writeitinstance.id, } data = self.data data['person'] = self.pedro.id response = self.api_client.get(url, data=data) self.assertValidJSONResponse(response) messages = self.deserialize(response)['objects'] self.assertEquals(len(messages), 1) self.assertEquals(messages[0]['id'], self.message1.id) def test_filter_by_persons_popit_id(self): url = '/api/v1/instance/%(writeitinstance_id)i/messages/' % { 'writeitinstance_id': self.writeitinstance.id, } data = self.data data['person__popit_id'] = self.pedro.popit_id response = self.api_client.get(url, data=data) self.assertValidJSONResponse(response) messages = self.deserialize(response)['objects'] self.assertEquals(len(messages), 1) self.assertEquals(messages[0]['id'], self.message1.id) def test_it_raises_error_404_when_filtering_by_someone_that_doesnot_exist(self): url = '/api/v1/instance/%(writeitinstance_id)i/messages/' % { 'writeitinstance_id': self.writeitinstance.id } data = self.data data['person__popit_id'] = "this-thing-does-not-exist" response = self.api_client.get(url, data=data) self.assertEquals(response.status_code, 404) def test_it_raises_error_404_when_filtering_by_person_id(self): url = '/api/v1/instance/%(writeitinstance_id)i/messages/' % { 'writeitinstance_id': self.writeitinstance.id } data = self.data # person with id 42 does not exist data['person'] = 42 # person with id 42 does not exist response = self.api_client.get(url, data=data) self.assertEquals(response.status_code, 404)
class TaskResourceTest(ResourceTestCase): fixtures = ['group.json', 'group_permission.json', 'user_group.json', 'user.json', 'user_project.json', 'project_part.json', 'project.json', 'profile.json', 'task.json'] def setUp(self): self.api_client = TestApiClient() self.task_id = 1 self.project_part_id = 1 self.task = {'description': 'new Task', 'project_part': {'pk': self.project_part_id}, 'flag_finished': 0, 'weight': 20 } self.detail_url = '/api/v1/task/{0}/'.format(self.task_id) self.project_part_query = '='.join(['?project_part', str(self.project_part_id)]) self.list_url = '/api/v1/task/' self.serializer = Serializer() def get_credentials(self): result = self.api_client.client.login(email='*****@*****.**', password='******') def test_post_list(self): self.get_credentials() self.assertIn('_auth_user_id', self.api_client.client.session) self.assertEqual(self.api_client.client.session['_auth_user_id'], 1) self.assertEqual(Task.objects.count(), 2) resp = self.api_client.post(self.list_url, format='json', data=self.task) self.assertHttpCreated(resp) self.assertEqual(Task.objects.count(), 3) def test_get_list_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.get(''.join([self.list_url, self.project_part_query]), format='json')) def test_get_list_json(self): self.get_credentials() resp = self.api_client.get(''.join([self.list_url, self.project_part_query]), format='json') self.assertValidJSONResponse(resp) self.assertEqual(len(json.loads(resp.content)['objects']), 2) def test_get_detail_unauthenticated(self): resp = self.api_client.get(self.detail_url, format='json') self.assertHttpUnauthorized(resp) def test_get_detail_json(self): self.get_credentials() resp = self.api_client.get(self.detail_url, format='json') self.assertValidJSONResponse(resp) self.assertEqual(json.loads(resp.content)['description'], 'new task') # def test_post_list_unauthenticated(self): # self.assertHttpUnauthorized(self.api_client.post(self.list_url, format='json', # data=self.task)) def test_put_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.put(self.detail_url, format='json', data={})) def test_put_detail(self): self.get_credentials() original_data = json.loads(self.api_client.get(self.detail_url, format='json').content) new_data = original_data.copy() new_data['title'] = 'Updated: First Task' self.assertEqual(Task.objects.count(), 2) self.assertHttpAccepted(self.api_client.put(self.detail_url, format='json', data=new_data)) self.assertEqual(Task.objects.count(), 2) def test_delete_detail_unauthenticated(self): self.assertHttpUnauthorized(self.api_client.delete(self.detail_url, format='json')) def test_delete_detail(self): self.get_credentials() self.assertEqual(Task.objects.count(), 2) self.assertHttpAccepted(self.api_client.delete(self.detail_url, format='json')) self.assertEqual(Task.objects.count(), 1)
class TestCampaignResource(ResourceTestCase): def setUp(self): # Tastypie stuff super(TestCampaignResource, self).setUp() self.bob_api_client = TestApiClient() self.bill_api_client = TestApiClient() self.anon_api_client = TestApiClient() # Create a user bob. self.user_bob_username = "******" self.user_bob_password = "******" self.user_bob = User.objects.create_user(self.user_bob_username, "*****@*****.**", self.user_bob_password) # Create a user bob. self.user_bill_username = "******" self.user_bill_password = "******" self.user_bill = User.objects.create_user( self.user_bill_username, "*****@*****.**", self.user_bill_password ) self.bob_api_client.client.login(username="******", password="******") self.bill_api_client.client.login(username="******", password="******") # assign users to the Public group public_group, created = Group.objects.get_or_create(name="Public") self.user_bob.groups.add(public_group) self.user_bill.groups.add(public_group) guardian.utils.get_anonymous_user().groups.add(public_group) # make a couple of campaigns and save self.campaign_bobs = mommy.make_one("catamidb.Campaign") self.campaign_bills = mommy.make_one("catamidb.Campaign") # assign this one to bob authorization.apply_campaign_permissions(self.user_bob, self.campaign_bobs) # assign this one to bill authorization.apply_campaign_permissions(self.user_bill, self.campaign_bills) # the API url for campaigns self.campaign_url = "/api/dev/campaign/" # some post data for testing campaign creation self.post_data = { "short_name": "Blah", "description": "Blah", "associated_researchers": "Blah", "associated_publications": "Blah", "associated_research_grant": "Blah", "date_start": "2012-05-01", "date_end": "2012-05-01", "contact_person": "Blah", } # can only do GET at this stage def test_campaign_operations_disabled(self): # test that we are unauthorized to create self.assertHttpUnauthorized(self.anon_api_client.post(self.campaign_url, format="json", data=self.post_data)) # test that we can NOT modify self.assertHttpMethodNotAllowed( self.anon_api_client.put(self.campaign_url + self.campaign_bobs.id.__str__() + "/", format="json", data={}) ) # test that we can NOT delete self.assertHttpMethodNotAllowed( self.anon_api_client.delete(self.campaign_url + self.campaign_bobs.id.__str__() + "/", format="json") ) # test that we can NOT modify authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.put(self.campaign_url + self.campaign_bobs.id.__str__() + "/", format="json", data={}) ) # test that we can NOT delete authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.delete(self.campaign_url + self.campaign_bobs.id.__str__() + "/", format="json") ) # test can get a list of campaigns authorised def test_campaigns_operations_as_authorised_users(self): # create a campaign that only bill can see bills_campaign = mommy.make_one("catamidb.Campaign") assign("view_campaign", self.user_bill, bills_campaign) # check that bill can see via the API response = self.bill_api_client.get(self.campaign_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 3) # check that bill can get to the object itself response = self.bill_api_client.get(self.campaign_url + bills_campaign.id.__str__() + "/", format="json") self.assertValidJSONResponse(response) # check that bob can not see - now we know tastypie API has correct # permission validation response = self.bob_api_client.get(self.campaign_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 2) # check bob can NOT get to the hidden object response = self.bob_api_client.get(self.campaign_url + bills_campaign.id.__str__() + "/", format="json") self.assertHttpUnauthorized(response) # check that anonymous can see public ones as well response = self.anon_api_client.get(self.campaign_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 2) # check anonymous can NOT get to the hidden object response = self.anon_api_client.get(self.campaign_url + bills_campaign.id.__str__() + "/", format="json") self.assertHttpUnauthorized(response) # create via the API auth_post_data = { "short_name": "AuthBlah", "description": "AuthBlah", "associated_researchers": "AuthBlah", "associated_publications": "AuthBlah", "associated_research_grant": "AuthBlah", "date_start": "2012-05-01", "date_end": "2012-05-01", "contact_person": "AuthBlah", } # test that we can create authenticated self.assertHttpCreated(self.bob_api_client.post(self.campaign_url, format="json", data=auth_post_data)) # check that ones we created via API are there response = self.bill_api_client.get(self.campaign_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 4) # check public can see it too response = self.anon_api_client.get(self.campaign_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 3)
class TestCameraResource(ResourceTestCase): def setUp(self): # Tastypie stuff super(TestCameraResource, self).setUp() self.bob_api_client = TestApiClient() self.bill_api_client = TestApiClient() self.anon_api_client = TestApiClient() # Create a user bob. self.user_bob_username = "******" self.user_bob_password = "******" self.user_bob = User.objects.create_user(self.user_bob_username, "*****@*****.**", self.user_bob_password) # Create a user bob. self.user_bill_username = "******" self.user_bill_password = "******" self.user_bill = User.objects.create_user( self.user_bill_username, "*****@*****.**", self.user_bill_password ) self.bob_api_client.client.login(username="******", password="******") self.bill_api_client.client.login(username="******", password="******") # assign users to the Public group public_group, created = Group.objects.get_or_create(name="Public") self.user_bob.groups.add(public_group) self.user_bill.groups.add(public_group) guardian.utils.get_anonymous_user().groups.add(public_group) # make a couple of campaigns and save self.campaign_bobs = mommy.make_one("catamidb.Campaign", id=1) self.campaign_bills = mommy.make_one("catamidb.Campaign", id=2) # make a deployments self.deployment_bobs = mommy.make_recipe("catamidb.Deployment1", id=1, campaign=self.campaign_bobs) self.deployment_bills = mommy.make_recipe("catamidb.Deployment2", id=2, campaign=self.campaign_bills) # make images self.image_bobs = mommy.make_recipe("catamidb.Image1", id=1, deployment=self.deployment_bobs) self.image_bills = mommy.make_recipe("catamidb.Image2", id=2, deployment=self.deployment_bills) # make cameras self.camera_bobs = mommy.make_one("catamidb.Camera", id=1, image=self.image_bobs) self.camera_bills = mommy.make_one("catamidb.Camera", id=2, image=self.image_bills) # assign this one to bob authorization.apply_campaign_permissions(self.user_bob, self.campaign_bobs) # assign this one to bill authorization.apply_campaign_permissions(self.user_bill, self.campaign_bills) # the API url for deployments self.camera_url = "/api/dev/camera/" # some post data for testing camera creation self.post_data = [] def test_camera_operations_disabled(self): # test that we can NOT create self.assertHttpUnauthorized(self.anon_api_client.post(self.camera_url, format="json", data=self.post_data)) # test that we can NOT modify self.assertHttpUnauthorized( self.anon_api_client.put(self.camera_url + self.deployment_bobs.id.__str__() + "/", format="json", data={}) ) # test that we can NOT delete self.assertHttpMethodNotAllowed( self.anon_api_client.delete(self.camera_url + self.deployment_bobs.id.__str__() + "/", format="json") ) # test that we can NOT modify authenticated self.assertHttpUnauthorized( self.bob_api_client.put(self.camera_url + self.deployment_bobs.id.__str__() + "/", format="json", data={}) ) # test that we can NOT delete authenticated self.assertHttpMethodNotAllowed( self.bob_api_client.delete(self.camera_url + self.deployment_bobs.id.__str__() + "/", format="json") ) def test_camera_operations_as_authorised_users(self): # create a campaign & deployment that ONLY bill can see bills_campaign = mommy.make_one("catamidb.Campaign", id=3, short_name="cp_3") bills_deployment = mommy.make_recipe("catamidb.Deployment3", id=3, campaign=bills_campaign) assign("view_campaign", self.user_bill, bills_campaign) # make exclusive image for bill and assign this image to camera to image self.image_bill_exc = mommy.make_recipe( "catamidb.Image3", id=3, deployment=bills_deployment ) # IMPORTANT camera checks campaign which has reference to deployment. Image has reference to deployment and camera # make exclusive camera for bill self.camera_bill_exc = mommy.make_one("catamidb.Camera", id=3, image=self.image_bill_exc) # check that bill can see via the API response = self.bill_api_client.get(self.camera_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 3) # check that bill can get to the object itself response = self.bill_api_client.get(self.camera_url + "3/", format="json") self.assertValidJSONResponse(response) # check that bob can not see - now we know tastypie API has correct # permission validation response = self.bob_api_client.get(self.camera_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 2) # check bob can NOT get to the hidden object response = self.bob_api_client.get(self.camera_url + "3/", format="json") self.assertHttpUnauthorized(response) # check that anonymous can see public ones as well response = self.anon_api_client.get(self.camera_url, format="json") self.assertValidJSONResponse(response) self.assertEqual(len(self.deserialize(response)["objects"]), 2) # check anonymous can NOT get to the hidden object response = self.anon_api_client.get(self.camera_url + "3/", format="json") self.assertHttpUnauthorized(response)
class AnswersResourceTestCase(ResourceTestCase): def setUp(self): super(AnswersResourceTestCase,self).setUp() call_command('loaddata', 'example_data', verbosity=0) self.answer = Answer.objects.all()[0] self.writeitinstance = WriteItInstance.objects.all()[0] self.user = User.objects.all()[0] self.api_client = TestApiClient() self.data = {'format': 'json', 'username': self.user.username, 'api_key':self.user.api_key.key} def test_resource_get_all_answers(self): '''Get all answers through the API''' resource = AnswerResource() self.assertTrue(resource) request = HttpRequest() answers_json = self.deserialize(resource.get_list(request))['objects'] self.assertEquals(len(answers_json), Answer.objects.count()) self.assertEquals(answers_json[0]["id"], self.answer.id) def test_get_the_list_of_answers_per_instance(self): """Get the list of answers in an writetinstance instance""" url = '/api/v1/instance/%(writeitinstance_id)i/answers/' % { 'writeitinstance_id' : self.writeitinstance.id } response = self.api_client.get(url,data = self.data) self.assertValidJSONResponse(response) answers = self.deserialize(response)['objects'] answers_of_the_writeitinstance = Answer.objects.filter( message__writeitinstance=self.writeitinstance ) self.assertEquals(len(answers), len(answers_of_the_writeitinstance)) self.assertEquals(answers[0]['content'], self.answer.content) self.assertEquals(answers[0]['id'], self.answer.id) self.assertEquals(answers[0]['message_id'], self.answer.message.id) def test_get_only_answers_of_the_instance(self): """Show answers from the writeitinstance only""" the_other_instance = WriteItInstance.objects.all()[1] person = Person.objects.all()[0] message = the_other_instance.message_set.all()[0] answer = Answer.objects.create(message=message, \ content="hello this is an answer", \ person=person ) url = '/api/v1/instance/%(writeitinstance_id)i/answers/' % { 'writeitinstance_id' : the_other_instance.id } response = self.api_client.get(url,data = self.data) answers = self.deserialize(response)['objects'] answers_of_the_other_instance = Answer.objects.filter( message__writeitinstance=the_other_instance ) self.assertEquals(len(answers), len(answers_of_the_other_instance)) self.assertEquals(answers[0]['id'], answer.id) self.assertEquals(answers[0]['content'], answer.content) def test_get_the_person_that_answered(self): '''The API tells who answered the current answer''' resource = AnswerResource() request = HttpRequest() answers_json = self.deserialize(resource.get_list(request))['objects'] answer_json = answers_json[0] self.assertIn('person', answer_json) person = answer_json['person'] self.assertEquals(person["id"], self.answer.person.id) self.assertEquals(person["image"], self.answer.person.image) self.assertEquals(person["name"], self.answer.person.name) self.assertEquals(person["popit_id"], self.answer.person.popit_id) self.assertEquals(person["popit_url"], self.answer.person.popit_url) self.assertEquals(person["resource_uri"], self.answer.person.popit_url) self.assertEquals(person["summary"], self.answer.person.summary) def test_answer_ordering(self): """The answers are displayed from new to old""" Answer.objects.all().delete() answer2 = Answer.objects.create(message=self.answer.message, \ content="hello this is an answer", \ person=self.answer.person ) answer1 = Answer.objects.create(message=self.answer.message, \ content="hello this is an answer", \ person=self.answer.person ) answers_json = self.deserialize(AnswerResource().get_list(HttpRequest()))['objects'] for answer in answers_json: print answer['id'], answer['created'] self.assertEquals(answers_json[0]['id'], answer1.id) self.assertEquals(answers_json[1]['id'], answer2.id)
class InstanceResourceTestCase(ResourceTestCase): def setUp(self): super(InstanceResourceTestCase, self).setUp() call_command('loaddata', 'example_data', verbosity=0) self.user = User.objects.get(id=1) self.writeitinstance = WriteItInstance.objects.create(name=u"a test", slug=u"a-test", owner=self.user) self.api_client = TestApiClient() 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_api_exists(self): url = '/api/v1/' resp = self.api_client.get(url, data=self.data) self.assertValidJSONResponse(resp) def test_api_needs_authentication(self): url = '/api/v1/instance/' response = self.api_client.get(url) self.assertHttpUnauthorized(response) def test_get_list_of_instances(self): url = '/api/v1/instance/' response = self.api_client.get(url, data=self.data) self.assertValidJSONResponse(response) instances = self.deserialize(response)['objects'] self.assertEqual(len(instances), WriteItInstance.objects.count()) # All the instances first_instance = instances[0] self.assertEqual(first_instance['messages_uri'], '/api/v1/instance/{0}/messages/'.format(first_instance['id'])) def test_get_detail_of_an_instance(self): url = '/api/v1/instance/{0}/'.format(self.writeitinstance.id) response = self.api_client.get(url, data=self.data) self.assertValidJSONResponse(response) def test_get_persons_of_an_instance(self): writeitinstance = WriteItInstance.objects.get(id=1) url = '/api/v1/instance/{0}/'.format(writeitinstance.id) response = self.api_client.get(url, data=self.data) instance = self.deserialize(response) self.assertIn('persons', instance) pedro = Person.objects.get(id=1) self.assertIn(pedro.popit_url, instance['persons']) def test_create_a_new_instance(self): instance_data = { 'name': 'The instance', 'slug': 'the-instance', } url = '/api/v1/instance/' response = self.api_client.post(url, data=instance_data, format='json', authentication=self.get_credentials()) self.assertHttpCreated(response) match_id = re.match(r'^http://testserver/api/v1/instance/(?P<id>\d+)/?', response['Location']) self.assertIsNotNone(match_id) instance_id = match_id.group('id') instance = WriteItInstance.objects.get(id=instance_id) self.assertValidJSON(force_text(response.content)) instance_as_json = force_text(response.content) self.assertIn('resource_uri', instance_as_json) self.assertEquals(instance.name, instance_data['name']) self.assertEquals(instance.slug, instance_data['slug']) self.assertEquals(instance.owner, self.user) @skipUnless(settings.LOCAL_POPIT, "No local popit running") def test_create_a_new_instance_with_only_name(self): instance_data = { 'name': 'The instance', } url = '/api/v1/instance/' response = self.api_client.post(url, data=instance_data, format='json', authentication=self.get_credentials()) self.assertHttpCreated(response) match_id = re.match(r'^http://testserver/api/v1/instance/(?P<id>\d+)/?', response['Location']) self.assertIsNotNone(match_id) instance_id = match_id.group('id') instance = WriteItInstance.objects.get(id=instance_id) self.assertEquals(instance.name, instance_data['name']) self.assertEquals(instance.owner, self.user) self.assertTrue(instance.slug) def test_does_not_create_a_user_if_not_logged(self): instance_data = { 'name': 'The instance', 'slug': 'the-instance', } url = '/api/v1/instance/' response = self.api_client.post(url, data=instance_data, format='json') self.assertHttpUnauthorized(response) @skipUnless(settings.LOCAL_POPIT, "No local popit running") def test_create_and_pull_people_from_a_popit_api(self): # loading data into the popit-api popit_load_data() instance_data = { 'name': 'The instance', 'slug': 'the-instance', 'popit-api': settings.TEST_POPIT_API_URL, } url = '/api/v1/instance/' response = self.api_client.post(url, data=instance_data, format='json', authentication=self.get_credentials()) self.assertHttpCreated(response) match_id = re.match(r'^http://testserver/api/v1/instance/(?P<id>\d+)/?', response['Location']) instance = WriteItInstance.objects.get(id=match_id.group('id')) self.assertEquals(instance.persons.count(), 2) #this should not break raton = Person.objects.get(name=u'Ratón Inteligente') fiera = Person.objects.get(name=u"Fiera Feroz") self.assertIn(raton, [r for r in instance.persons.all()]) self.assertIn(fiera, [r for r in instance.persons.all()])
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 MessageResourceTestCase(ResourceTestCase): def setUp(self): super(MessageResourceTestCase, self).setUp() call_command('loaddata', 'example_data', verbosity=0) self.user = User.objects.get(id=1) self.writeitinstance = WriteItInstance.objects.create(name=u"a test", slug=u"a-test", owner=self.user) self.api_client = TestApiClient() 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_get_list_of_messages(self): url = '/api/v1/message/' response = self.api_client.get(url, data=self.data) self.assertValidJSONResponse(response) messages = self.deserialize(response)['objects'] # Only listing my messages expected_messages = Message.public_objects.filter(writeitinstance__in=self.user.writeitinstances.all()) self.assertEqual(len(messages), expected_messages.count()) # Only my instances first_message = messages[0] self.assertNotIn('author_email', first_message.keys()) def test_only_listing_my_messages(self): not_me = User.objects.create_user(username='******', password='******') writeitinstance = WriteItInstance.objects.create(name=u"a test", slug=u"a-test", owner=not_me) person1 = Person.objects.get(id=1) writeitinstance.add_person(person1) i_should_not_see_this_message = Message.objects.create( content='Content 1 Public message', author_name='Felipe', author_email="*****@*****.**", subject='Fiera es una perra feroz', writeitinstance=writeitinstance, persons=[person1], ) Confirmation.objects.create(message=i_should_not_see_this_message) i_should_not_see_this_message.recently_confirmated() self.assertTrue(i_should_not_see_this_message.public) expected_messages = Message.public_objects.filter(writeitinstance__in=self.user.writeitinstances.all()) self.assertNotIn(i_should_not_see_this_message, expected_messages) self.assertIn(i_should_not_see_this_message, Message.public_objects.all()) url = '/api/v1/message/' response = self.api_client.get(url, data=self.data) self.assertValidJSONResponse(response) messages = self.deserialize(response)['objects'] i_should_not_see_this_message_as_json = None # Seriously, this can be done in a more elegant way # I'll keep on working with this and I'll return to this test # later for message in messages: if message['id'] == i_should_not_see_this_message.id: i_should_not_see_this_message_as_json = message self.assertIsNone(i_should_not_see_this_message_as_json) # The detail of a message url = '/api/v1/message/{0}/'.format(i_should_not_see_this_message.id) response = self.api_client.get(url, data=self.data) self.assertHttpUnauthorized(response) def test_list_of_messages_is_ordered(self): """ The list of messages shown in the API is ordered by created date""" # Preparing the test Message.objects.all().delete() person1 = Person.objects.get(id=1) # cleaning up the database before message1 = Message.objects.create( content=u'Content 1', author_name=u'Felipe', author_email=u"*****@*****.**", subject=u'Fiera es una perra feroz 1', writeitinstance=self.writeitinstance, persons=[person1], ) Confirmation.objects.create(message=message1) message1.recently_confirmated() message2 = Message.objects.create( content=u'Content 2', author_name=u'Felipe', author_email=u"*****@*****.**", subject=u'Fiera es una perra feroz 2', writeitinstance=self.writeitinstance, persons=[person1], ) Confirmation.objects.create(message=message2) message2.recently_confirmated() url = '/api/v1/message/' response = self.api_client.get(url, data=self.data) self.assertValidJSONResponse(response) messages = self.deserialize(response)['objects'] self.assertEquals(messages[0]['id'], message2.id) self.assertEquals(messages[1]['id'], message1.id) def test_authentication(self): url = '/api/v1/message/' response = self.api_client.get(url) self.assertHttpUnauthorized(response) def test_a_list_of_messages_have_answers(self): url = '/api/v1/message/' response = self.api_client.get(url, data=self.data) self.assertValidJSONResponse(response) messages = self.deserialize(response)['objects'] self.assertTrue('answers' in messages[0]) def test_the_message_has_the_people_it_was_sent_to(self): url = '/api/v1/message/' response = self.api_client.get(url, data=self.data) self.assertValidJSONResponse(response) messages = self.deserialize(response)['objects'] self.assertTrue('persons' in messages[0]) message_from_the_api = messages[0] message = Message.objects.get(id=messages[0]['id']) for person in message_from_the_api['people']: self.assertIn('popit_url', person) self.assertIn( Person.objects.get(id=person['id']), message.people.all(), ) self.assertEquals(len(message_from_the_api['people']), message.people.count()) def test_create_a_new_message(self): writeitinstance = WriteItInstance.objects.get(id=1) message_data = { 'author_name': 'Felipipoo', 'subject': 'new message', 'content': 'the content thing', 'writeitinstance': '/api/v1/instance/{0}/'.format(writeitinstance.id), 'persons': [writeitinstance.persons.all()[0].popit_url], } url = '/api/v1/message/' previous_amount_of_messages = Message.objects.count() response = self.api_client.post(url, data=message_data, format='json', authentication=self.get_credentials()) self.assertHttpCreated(response) self.assertValidJSON(force_text(response.content)) message_as_json = force_text(response.content) self.assertIn('resource_uri', message_as_json) post_amount_of_messages = Message.objects.count() self.assertEquals(post_amount_of_messages, previous_amount_of_messages + 1) the_message = Message.objects.get(author_name='Felipipoo') outbound_messages = the_message.outboundmessage_set.all() self.assertTrue(outbound_messages.count() > 0) for outbound_message in outbound_messages: self.assertEquals(outbound_message.status, 'ready') def test_create_a_new_message_in_not_my_instance(self): not_me = User.objects.create_user(username='******', password='******') writeitinstance = WriteItInstance.objects.create(name=u"a test", slug=u"a-test", owner=not_me) person1 = Person.objects.get(id=1) writeitinstance.add_person(person1) message_data = { 'author_name': 'Felipipoo', 'subject': 'new message', 'content': 'the content thing', 'writeitinstance': '/api/v1/instance/{0}/'.format(writeitinstance.id), 'persons': [person1.popit_url], } url = '/api/v1/message/' response = self.api_client.post(url, data=message_data, format='json', authentication=self.get_credentials()) self.assertHttpUnauthorized(response) def test_create_a_new_message_with_a_non_existing_person(self): writeitinstance = WriteItInstance.objects.get(id=1) message_data = { 'author_name': 'Felipipoo', 'subject': 'new message', 'content': 'the content thing', 'writeitinstance': '/api/v1/instance/{0}/'.format(writeitinstance.id), 'persons': [ writeitinstance.persons.all()[0].popit_url, 'http://this.person.does.not.exist', ], } url = '/api/v1/message/' response = self.api_client.post(url, data=message_data, format='json', authentication=self.get_credentials()) self.assertHttpCreated(response) the_message = Message.objects.get(author_name='Felipipoo') outbound_messages = the_message.outboundmessage_set.all() self.assertEquals(outbound_messages.count(), 1) self.assertEquals(outbound_messages[0].contact.person, writeitinstance.persons.all()[0]) def test_create_a_new_message_confirmated(self): writeitinstance = WriteItInstance.objects.get(id=1) message_data = { 'author_name': 'Felipipoo', 'subject': 'new message', 'content': 'the content thing', 'writeitinstance': '/api/v1/instance/{0}/'.format(writeitinstance.id), 'persons': [writeitinstance.persons.all()[0].popit_url], } url = '/api/v1/message/' self.api_client.post(url, data=message_data, format='json', authentication=self.get_credentials()) the_message = Message.objects.get(author_name='Felipipoo') self.assertTrue(the_message.confirmated) def test_create_a_new_message_to_all_persons_in_the_instance(self): # here it is the thing I don't know yet how to do this and I'll go for # saying all in the persons array instead of having an array or an empty writeitinstance = WriteItInstance.objects.get(id=1) message_data = { 'author_name': 'Felipipoo', 'subject': 'new message', 'content': 'the content thing', 'writeitinstance': '/api/v1/instance/{0}/'.format(writeitinstance.id), 'persons': "all", } url = '/api/v1/message/' self.api_client.post(url, data=message_data, format='json', authentication=self.get_credentials()) the_message = Message.objects.get(author_name=u'Felipipoo') self.assertEquals(len(the_message.people), writeitinstance.persons.count()) self.assertQuerysetEqual( the_message.people.all(), [repr(r) for r in writeitinstance.persons.all()] ) def test_not_confirming_automatically_a_message(self): """Push a new message to an instance with no autoconfirm message""" writeitinstance = WriteItInstance.objects.get(id=1) writeitinstance.config.autoconfirm_api_messages = False writeitinstance.config.save() message_data = { 'author_name': 'Felipipoo', 'author_email': "*****@*****.**", 'subject': 'new message', 'content': 'the content thing', 'writeitinstance': '/api/v1/instance/{0}/'.format(writeitinstance.id), 'persons': "all", } url = '/api/v1/message/' self.api_client.post( url, data=message_data, format='json', authentication=self.get_credentials(), ) the_message = Message.objects.get(author_name='Felipipoo') self.assertFalse(the_message.confirmated) self.assertIsNotNone(the_message.confirmation) def test_not_including_email_in_non_auto_confrim_message(self): """Not Including email causes error 403 in a non auto confirm message""" writeitinstance = WriteItInstance.objects.get(id=1) writeitinstance.config.autoconfirm_api_messages = False writeitinstance.config.save() message_data = { 'author_name': 'Felipipoo', # 'author_email': "*****@*****.**", # this missing param will cause a 403 'subject': 'new message', 'content': 'the content thing', 'writeitinstance': '/api/v1/instance/{0}/'.format(writeitinstance.id), 'persons': "all", } url = '/api/v1/message/' response = self.api_client.post( url, data=message_data, format='json', authentication=self.get_credentials(), ) self.assertEquals(response.status_code, 400) self.assertFalse(Message.objects.filter(author_name='Felipipoo')) def test_including_a_non_email_in_the_author_email(self): """When it has an author_email it validates it""" writeitinstance = WriteItInstance.objects.get(id=1) message_data = { 'author_name': 'Felipipoo', 'author_email': "This is not an email", # this missing param will cause a 403 'subject': 'new message', 'content': 'the content thing', 'writeitinstance': '/api/v1/instance/{0}/'.format(writeitinstance.id), 'persons': "all" } url = '/api/v1/message/' response = self.api_client.post( url, data=message_data, format='json', authentication=self.get_credentials(), ) self.assertEquals(response.status_code, 400) self.assertFalse(Message.objects.filter(author_name='Felipipoo'))
class HelpResourceTest(ResourceTestCase): def setUp(self): super(HelpResourceTest, self).setUp() # TODO: If we end up supporting the PATCH method, use our # FixedTestApiClient instead of the default self.api_client = TestApiClient() self.username = '******' self.password = '******' self.user = User.objects.create_user(self.username, '*****@*****.**', self.password) def test_get_detail(self): help = create_help(title="Test Help Item", body="Test Help Item body") uri = '/api/0.1/help/%s/' % (help.help_id) resp = self.api_client.get(uri) self.assertValidJSONResponse(resp) self.assertEqual(self.deserialize(resp)['title'], "Test Help Item") self.assertEqual(self.deserialize(resp)['body'], "Test Help Item body") def test_get_detail_by_slug(self): help = create_help(title="Test Help Item", body="Test Help Item body", slug="test") uri = '/api/0.1/help/%s/' % (help.slug) resp = self.api_client.get(uri) self.assertValidJSONResponse(resp) self.assertEqual(self.deserialize(resp)['title'], "Test Help Item") self.assertEqual(self.deserialize(resp)['body'], "Test Help Item body") def test_get_list_for_section(self): section_help = create_help(title="Test section help item", body="Test section help item body") nonsection_help = create_help(title="Test non-section help item", body="Test non-section help item body", slug='test-nonsection') story = create_story(title="Test Story", summary="Test Summary", byline="Test Byline", status="published", language="en") section = create_section(title="Test Section 1", story=story, help=section_help) uri = '/api/0.1/help/sections/%s/' % (section.section_id) resp = self.api_client.get(uri) self.assertValidJSONResponse(resp) self.assertEqual(len(self.deserialize(resp)['objects']), 1) self.assertEqual( self.deserialize(resp)['objects'][0]['title'], "Test section help item") self.assertEqual( self.deserialize(resp)['objects'][0]['body'], "Test section help item body") def test_post_list_for_section(self): section_help = create_help(title="Test section help item", body="Test section help item body") story = create_story(title="Test Story", summary="Test Summary", byline="Test Byline", status="published", language="en", author=self.user) section = create_section(title="Test Section 1", story=story) self.assertEqual(section.help, None) post_data = {'help_id': section_help.help_id} uri = '/api/0.1/help/sections/%s/' % (section.section_id) self.api_client.client.login(username=self.username, password=self.password) resp = self.api_client.post(uri, format='json', data=post_data) self.assertHttpCreated(resp) updated_section = Section.objects.get(pk=section.pk) self.assertEqual(updated_section.help, section_help) def test_post_list_for_section_unauthorized_unauthenticated(self): """ Test that anonymous users cannot set the help item for a section """ section_help = create_help(title="Test section help item", body="Test section help item body") story = create_story(title="Test Story", summary="Test Summary", byline="Test Byline", status="published", language="en", author=self.user) section = create_section(title="Test Section 1", story=story) self.assertEqual(section.help, None) post_data = {'help_id': section_help.help_id} uri = '/api/0.1/help/sections/%s/' % (section.section_id) resp = self.api_client.post(uri, format='json', data=post_data) self.assertHttpUnauthorized(resp) def test_post_list_for_section_unauthorized_other_user(self): """ Test that a user can't set the help text for another user's section """ user2 = User.objects.create(username="******", email="*****@*****.**", password="******") section_help = create_help(title="Test section help item", body="Test section help item body") story = create_story(title="Test Story", summary="Test Summary", byline="Test Byline", status="published", language="en", author=user2) section = create_section(title="Test Section 1", story=story) self.assertEqual(section.help, None) post_data = {'help_id': section_help.help_id} self.api_client.client.login(username=self.username, password=self.password) uri = '/api/0.1/help/sections/%s/' % (section.section_id) resp = self.api_client.post(uri, format='json', data=post_data) self.assertHttpUnauthorized(resp)
class ResourceTest(ResourceTestCase): def setUp(self): self.logger = logging.getLogger(__name__) self.api_client = TestApiClient() self.username = "******" self.password = "******" # create a user to be used for creating the resource self.user_creator = hydroshare.create_account( "*****@*****.**", username=self.username, first_name="Creator_FirstName", last_name="Creator_LastName", superuser=False, password=self.password, groups=[], ) self.user_url = "/hsapi/accounts/{0}/".format(self.user_creator.username) self.api_client.client.login(username=self.username, password=self.password) # create a resource self.resource = hydroshare.create_resource( resource_type="GenericResource", title="My resource", owner=self.user_creator, last_changed_by=self.user_creator, ) self.resource_url_base = "/hsapi/resource/" self.resource_url = "{0}{1}/".format(self.resource_url_base, self.resource.short_id) self.post_data = {"title": "My REST API-created resource", "resource_type": "GenericResource"} def tearDown(self): User.objects.all().delete() GenericResource.objects.all().delete() def get_credentials(self): k = self.create_basic(username=self.username, password=self.password) print k return k def test_resource_get(self): resp = self.api_client.get(self.resource_url) self.assertTrue(resp["Location"].endswith(".zip")) def test_resource_post(self): resp = self.api_client.post(self.resource_url_base, data=self.post_data) self.assertIn(resp.status_code, [201, 200]) # PID comes back as body of response, but API client doesn't seem to be # parsing the response for us pid = str(resp).split("\n")[-1] new_resource_url = "{0}{1}/".format(self.resource_url_base, pid) # Fetch the newly created resource resp = self.api_client.get(new_resource_url) self.assertTrue(resp["Location"].endswith(".zip")) def test_resource_put(self): new_data = {} new_data["title"] = "My UPDATED REST API-created resource" resp = self.api_client.put(self.resource_url, data=new_data) self.assertIn(resp.status_code, ["202", "204"]) def test_resource_delete(self): x = self.api_client.delete(self.resource_url, format="json") self.assertIn(x.status_code, [202, 204, 301]) self.assertHttpNotFound(self.api_client.get(self.resource_url, format="json"))
class 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 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 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 ApiTestCase(ResourceTestCase): ''' Testing custom integrity checks for the Move model. ''' def setUp(self): self.api_client = TestApiClient() player_1 = Player.objects.create(name="Person1", is_human=True) player_2 = Player.objects.create(name="Person2", is_human=False) Game.objects.create(player_1=player_1, player_2=player_2) def move_dict(self, game_id, player_id, x, y): return {"game": { "id": game_id }, "player": { "id": player_id }, "position_x": x, "position_y": y} def test_winner_found(self): ''' Tests winner and is_over are updated on game when three coordinates in a row are one player's. Tests winner and is_over are not updated before that. ''' self.api_client.get('/api/v1/move/', format='json') game = Game.objects.get(id=1) player1 = Player.objects.get(id=1) player2 = Player.objects.get(id=2) Move(game=game, player=player1, position_x=1, position_y=1).save() Move(game=game, player=player2, position_x=0, position_y=0).save() Move(game=game, player=player1, position_x=1, position_y=0).save() move_post = self.move_dict(game.id, player2.id, 0, 2) self.api_client.post('/api/v1/move/', data=move_post) game = Game.objects.get(id=1) self.assertFalse(game.is_over or game.winner) move_post = self.move_dict(game.id, player1.id, 1, 2) self.api_client.post('/api/v1/move/', data=move_post) self.api_client.get('/api/v1/move/', format='json') resp = json.loads(self.api_client.get('/api/v1/game/1/', format='json').content) game = Game.objects.get(id=1) self.assertTrue(game.is_over) self.assertTrue(resp['is_over']) self.assertEqual(game.winner, player1) self.assertEqual(resp['winner']['name'], player1.name) def test_tie(self): ''' Tests is_over is updated on game when all coordinates have been taken. Tests is_over is not updated before that. Tests that winner is never set for this scenario. ''' self.api_client.get('/api/v1/move/', format='json') game = Game.objects.get(id=1) player1 = Player.objects.get(id=1) player2 = Player.objects.get(id=2) Move(game=game, player=player1, position_x=1, position_y=1).save() Move(game=game, player=player2, position_x=1, position_y=0).save() Move(game=game, player=player1, position_x=2, position_y=0).save() Move(game=game, player=player2, position_x=2, position_y=2).save() Move(game=game, player=player1, position_x=0, position_y=0).save() Move(game=game, player=player2, position_x=0, position_y=1).save() Move(game=game, player=player1, position_x=1, position_y=2).save() move_post = self.move_dict(game.id, player2.id, 0, 2) self.api_client.post('/api/v1/move/', data=move_post) game = Game.objects.get(id=1) self.assertFalse(game.is_over or game.winner) move_post = self.move_dict(game.id, player1.id, 2, 1) self.api_client.post('/api/v1/move/', data=move_post) resp = json.loads(self.api_client.get('/api/v1/game/1/', format='json').content) game = Game.objects.get(id=1) self.assertTrue(game.is_over) self.assertTrue(resp['is_over']) self.assertFalse(game.winner) self.assertFalse(resp['winner']) def test_computer_turn(self): ''' Tests that a computer turn is taken automatically when computer's turn is next and POST is made wtih Move object. ''' game = Game.objects.get(id=1) player1 = Player.objects.get(id=1) player2 = Player.objects.get(id=2) move_post = self.move_dict(game.id, player1.id, 0, 0) self.api_client.post('/api/v1/move/', data=move_post) computer_move = json.loads(self.api_client.get('/api/v1/move/2/', format='json').content) self.assertTrue(computer_move) self.assertEqual(computer_move['player']['name'], player2.name) def test_computer_turn_not_after_win(self): ''' Tests that after a human player wins a turn, the automatic play of the computer does not occur. ''' game = Game.objects.get(id=1) player1 = Player.objects.get(id=1) player2 = Player.objects.get(id=2) Move(game=game, player=player1, position_x=0, position_y=0).save() Move(game=game, player=player2, position_x=1, position_y=0).save() Move(game=game, player=player1, position_x=1, position_y=1).save() Move(game=game, player=player2, position_x=2, position_y=0).save() move_post = self.move_dict(game.id, player1.id, 2, 2) self.api_client.post('/api/v1/move/', data=move_post) moves = json.loads(self.api_client.get('/api/v1/move/', format='json').content) self.assertEquals(len(moves['objects']), 5) self.assertEquals(moves['objects'][0]['player']['name'], player1.name) def test_computer_selects_middle(self): ''' Tests that if available, computer selects middle coordinate. ''' game = Game.objects.get(id=1) player1 = Player.objects.get(id=1) player2 = Player.objects.get(id=2) move_post = self.move_dict(game.id, player1.id, 2, 2) self.api_client.post('/api/v1/move/', data=move_post) moves = json.loads(self.api_client.get('/api/v1/move/', format='json').content) self.assertEquals(len(moves['objects']), 2) x = moves['objects'][0]['position_x'] y = moves['objects'][0]['position_y'] self.assertEquals((x,y), (1,1)) def test_computer_wins_if_possible(self): ''' Tests that computer will make winning move if possible. ''' game = Game.objects.get(id=1) player1 = Player.objects.get(id=1) player2 = Player.objects.get(id=2) Move(game=game, player=player1, position_x=0, position_y=0).save() Move(game=game, player=player2, position_x=1, position_y=1).save() Move(game=game, player=player1, position_x=2, position_y=1).save() Move(game=game, player=player2, position_x=1, position_y=2).save() move_post = self.move_dict(game.id, player1.id, 0, 2) self.api_client.post('/api/v1/move/', data=move_post) moves = json.loads(self.api_client.get('/api/v1/move/', format='json').content) self.assertEquals(len(moves['objects']), 6) self.assertEquals(moves['objects'][0]['player']['name'], player2.name) x = moves['objects'][0]['position_x'] y = moves['objects'][0]['position_y'] self.assertEquals((x,y), (1,0)) game = Game.objects.get(id=1) self.assertTrue(game.is_over) self.assertEquals(game.winner.name, player2.name) def test_computer_prevents_user_win(self): ''' Tests that computer will prevent a user's win. ''' game = Game.objects.get(id=1) player1 = Player.objects.get(id=1) player2 = Player.objects.get(id=2) Move(game=game, player=player1, position_x=0, position_y=0).save() Move(game=game, player=player2, position_x=1, position_y=1).save() move_post = self.move_dict(game.id, player1.id, 0, 2) self.api_client.post('/api/v1/move/', data=move_post) moves = json.loads(self.api_client.get('/api/v1/move/', format='json').content) self.assertEquals(len(moves['objects']), 4) x = moves['objects'][0]['position_x'] y = moves['objects'][0]['position_y'] self.assertEquals((x,y), (0,1)) def test_computer_finishes_tie(self): ''' Tests that computer makes selections until the game is over. ''' game = Game.objects.get(id=1) player1 = Player.objects.get(id=1) player2 = Player.objects.get(id=2) Move(game=game, player=player1, position_x=0, position_y=0).save() Move(game=game, player=player2, position_x=1, position_y=1).save() Move(game=game, player=player1, position_x=2, position_y=2).save() Move(game=game, player=player2, position_x=1, position_y=0).save() Move(game=game, player=player1, position_x=1, position_y=2).save() Move(game=game, player=player2, position_x=0, position_y=2).save() move_post = self.move_dict(game.id, player1.id, 2, 0) self.api_client.post('/api/v1/move/', data=move_post) moves = json.loads(self.api_client.get('/api/v1/move/', format='json').content) self.assertEquals(len(moves['objects']), 8)