class UserRepoSyncTest(TestCase): # # These are kind of terrible now. They test for a forbidden response is # legit, but we're short circuiting the POST to sync as to not make # an external request to GitHub. # fixtures = ['gitspatial/fixtures/test_data.json'] def setUp(self): self.sal = User.objects.get(id=6) self.jason = User.objects.get(id=5) self.factory = RequestFactory() def test_user_can_sync_own_repo(self): request = self.factory.post('/user/repo/22/sync?testing=1') request.user = self.jason response = user_repo_sync(request, repo_id=22) self.assertEqual(response.status_code, 201) def test_user_cannot_sync_others_repo(self): request = self.factory.post('/user/repo/22/sync') request.user = self.sal response = user_repo_sync(request, repo_id=22) self.assertEqual(response.status_code, 403) def test_user_can_unsync_own_repo(self): request = self.factory.delete('/user/repo/22/sync?testing=1') request.user = self.jason response = user_repo_sync(request, repo_id=22) self.assertEqual(response.status_code, 204) def test_user_cannot_unsync_others_repo(self): request = self.factory.delete('/user/repo/22/sync') request.user = self.sal response = user_repo_sync(request, repo_id=22) self.assertEqual(response.status_code, 403) def test_invalid_method_put(self): request = self.factory.put('/user/repo/22/sync?testing=1') request.user = self.jason response = user_repo_sync(request, repo_id=22) self.assertEqual(response.status_code, 405) def test_invalid_method_get(self): request = self.factory.get('/user/repo/22/sync?testing=1') request.user = self.jason response = user_repo_sync(request, repo_id=22) self.assertEqual(response.status_code, 405) def test_user_repo_sync_dne(self): request = self.factory.post('/user/repo/99999/sync') request.user = self.jason try: response = user_repo_sync(request, repo_id=99999) except Exception as exc: pass self.assertTrue(isinstance(exc, Http404))
def create_request(method="get", **kwargs): resource_link_id = kwargs.pop( "resource_link_id", "2a8b2d3fa51ea413d19e480fb6c2eb085b7866a9" ) session = {"LTI_LAUNCH": {}} session["LTI_LAUNCH"][resource_link_id] = kwargs.pop("session") params = kwargs.pop("params", {}) body = kwargs.pop("data", {}) url = kwargs.pop("url", "/foo") request_factory = RequestFactory() if method == "get": request = request_factory.get(url, data=params, content_type="application/json") elif method == "post": request = request_factory.post( url, data=json.dumps(body), content_type="application/json" ) elif method == "put": request = request_factory.put( url, data=json.dumps(body), content_type="application/json" ) elif method == "delete": request = request_factory.delete( url, data=json.dumps(body), content_type="application/json" ) else: raise Exception("invalid method: %s" % method) request.session = session setattr(request, "LTI", session.get("LTI_LAUNCH", {}).get(resource_link_id)) return request
class CRUDViewTest(TestCase): names = ['John', 'Anne', 'Chris', 'Beatrice', 'Matt'] def setUp(self): self.factory = RequestFactory() for name in self.names: DummyModel(name=name).save() def test_ng_query(self): request = self.factory.get('/crud/') response = CRUDTestView.as_view()(request) data = json.loads(response.content) for obj in data: db_obj = DummyModel.objects.get(pk=obj['pk']) self.assertEqual(obj['name'], db_obj.name) def test_ng_get(self): request = self.factory.get('/crud/?pk=1') response = CRUDTestView.as_view()(request) data = json.loads(response.content) self.assertEqual(self.names[0], data['name']) def test_ng_save_create(self): request = self.factory.post('/crud/', data=json.dumps({'name': 'Leonard'}), content_type='application/json') response = CRUDTestView.as_view()(request) data = json.loads(response.content) pk = data['pk'] request2 = self.factory.get('/crud/?pk=%d' % pk) response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content) self.assertEqual(data2['name'], 'Leonard') def test_ng_save_update(self): request = self.factory.post('/crud/?pk=1', data=json.dumps({'pk': 1, 'name': 'John2'}), content_type='application/json') response = CRUDTestView.as_view()(request) data = json.loads(response.content) self.assertEqual(data['name'], 'John2') request2 = self.factory.get('/crud/?pk=1') response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content) self.assertEqual(data2['name'], 'John2') def test_ng_delete(self): request = self.factory.delete('/crud/?pk=1') response = CRUDTestView.as_view()(request) data = json.loads(response.content) deleted_name = data['name'] request2 = self.factory.get('/crud/') response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content) for obj in data2: self.assertTrue(deleted_name != obj['name'])
class LoginUserTest(MockedCloudTestCase): def setUp(self): super(LoginUserTest, self).setUp() self.factory = RequestFactory() # Create an user to check login attempts against self.existing_user = User.objects.create_user(username='******', cloud_fqdn='existingserver') def tearDown(self): self.existing_user.delete() def test_login_good_credentials(self): good_creds={'username': '******', 'password': '******', 'cloud_fqdn': 'existingserver',} request = self.factory.post(reverse(login_user), data=good_creds) self.do_session_middleware_stuff(request) resp = login_user(request) self.assertEqual(resp.status_code, 200) def test_login_bad_credentials(self): bad_creds={'username': '******', 'password': '******', 'cloud_fqdn': 'existingserver',} request = self.factory.post(reverse(login_user), data=bad_creds) self.do_session_middleware_stuff(request) # Set mocked backend to fail authentication self.set_auth_result(False) resp = login_user(request) self.assertEqual(resp.status_code, 401) def test_login_missing_credentials(self): missing_creds={'username': '******', 'cloud_fqdn': 'existingserver',} request = self.factory.post(reverse(login_user), data=missing_creds) resp = login_user(request) self.assertEqual(resp.status_code, 400) def test_login_bad_methods(self): get_request = self.factory.get(reverse(login_user)) resp = login_user(get_request) self.assertEqual(resp.status_code, 405) put_request = self.factory.put(reverse(login_user)) resp = login_user(put_request) self.assertEqual(resp.status_code, 405) delete_request = self.factory.delete(reverse(login_user)) resp = login_user(delete_request) self.assertEqual(resp.status_code, 405) def test_login_no_persistent_session(self): good_creds={'username': '******', 'password': '******', 'cloud_fqdn': 'existingserver', 'persistent_session': 'False'} resp = self.client.post(reverse(login_user), good_creds) self.assertEqual(resp.status_code, 200) session_cookie = self.client.cookies['sessionid'] self.assertEqual(session_cookie['expires'], "")
class PatientTestCase(TestCase): def setUp(self): self.factory = RequestFactory() Patient.objects.create(name="Kazim", lastname="Kazim", age=34) Patient.objects.create(name="Tahm", lastname="Kench", age=91) def test_get_method(self): request = self.factory.get('/hospital/patient/') response = patient_single(request, 1) self.assertEqual(response.status_code, 200) self.assertEqual( response.content, JsonResponse({ "name": "Kazim", "lastname": "Kazim", "age": 34 }).content) def test_put_method(self): request = self.factory.put('/hospital/patient/', json.dumps({"name": "Salih"}), content_type='application/json') response = patient_single(request, 1) self.assertEqual(response.status_code, 200) patient = Patient.objects.filter(id=int(1)).first() self.assertEqual("Salih", patient.name) def test_post_method(self): request = self.factory.post('/hospital/patient', json.dumps({ "name": "Muhittin", "lastname": "Yilmaz", "age": 50 }), content_type='application/json') response = patient(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.content, JsonResponse({ "status": "OK", "message": "" }).content) def test_delete_method(self): request = self.factory.delete('/hospital/patient', json.dumps({"name": "Kazim"}), content_type='application/json') response = patient_single(request, 1) self.assertEqual(response.status_code, 200) patient = Patient.objects.filter(id=int(1)).first() self.assertEqual(response.content, JsonResponse({ "status": "OK", "message": "" }).content) def tearDown(self): Patient.objects.all().delete()
class CRUDViewTest(TestCase): names = ["John", "Anne", "Chris", "Beatrice", "Matt"] def setUp(self): self.factory = RequestFactory() for name in self.names: DummyModel(name=name).save() def test_ng_query(self): request = self.factory.get("/crud/") response = CRUDTestView.as_view()(request) data = json.loads(response.content) for obj in data: db_obj = DummyModel.objects.get(pk=obj["pk"]) self.assertEqual(obj["name"], db_obj.name) def test_ng_get(self): request = self.factory.get("/crud/?pk=1") response = CRUDTestView.as_view()(request) data = json.loads(response.content) self.assertEqual(self.names[0], data["name"]) def test_ng_save_create(self): request = self.factory.post("/crud/", data=json.dumps({"name": "Leonard"}), content_type="application/json") response = CRUDTestView.as_view()(request) data = json.loads(response.content) pk = data["pk"] request2 = self.factory.get("/crud/?pk=%d" % pk) response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content) self.assertEqual(data2["name"], "Leonard") def test_ng_save_update(self): request = self.factory.post( "/crud/?pk=1", data=json.dumps({"pk": 1, "name": "John2"}), content_type="application/json" ) response = CRUDTestView.as_view()(request) data = json.loads(response.content) self.assertEqual(data["name"], "John2") request2 = self.factory.get("/crud/?pk=1") response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content) self.assertEqual(data2["name"], "John2") def test_ng_delete(self): request = self.factory.delete("/crud/?pk=1") response = CRUDTestView.as_view()(request) data = json.loads(response.content) deleted_name = data["name"] request2 = self.factory.get("/crud/") response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content) for obj in data2: self.assertTrue(deleted_name != obj["name"])
class MyTests(TestCase): def setUp(self): # Every test needs access to the request factory. self.factory = RequestFactory() def test_delete(self): request = self.factory.delete('/thisfile') response = views.delete(request, 'thisfile') self.assertEqual(response.status_code, 204)
class MyTests(TestCase): def setUp(self): # Every test needs access to the request factory. self.factory = RequestFactory() def test_delete(self): request = self.factory.delete("/thisfile") response = views.delete(request, "thisfile") self.assertEqual(response.status_code, 204)
class CBVTestCase(TestCase): def setUp(self): self.factory = RequestFactory() dict_response = dict(foo='bar') self.dict_response = dict_response @jsonp class DictResponse(View): def get(self, request): return dict_response @jsonp class InvalidResponseFormat(View): def get(self, request): return [] self.simple_dict_view = DictResponse.as_view() self.invalid_view = InvalidResponseFormat.as_view() def assert_content_and_content_type(self, response, callback): self.assertContains(response, callback) self.assertContains(response, json.dumps(self.dict_response)) self.assertEqual(response['Content-Type'], APPLICATION_JS) def test_correct_response(self): callback = 'isThereASpoon' response = self.simple_dict_view( request=self.factory.get('/fake.json?jsonp={0}'.format(callback))) self.assert_content_and_content_type(response, callback) def test_method_not_allowed(self): callback = 'isThereASpoon' put_response = self.simple_dict_view( request=self.factory.put('/fake.json?jsonp={0}'.format(callback))) post_response = self.simple_dict_view( request=self.factory.post('/fake.json?jsonp={0}'.format(callback))) delete_response = self.simple_dict_view(request=self.factory.delete( '/fake.json?jsonp={0}'.format(callback))) for r in [put_response, post_response, delete_response]: self.assertIsInstance(r, HttpResponseNotAllowed) def test_invalid_response_format(self): callback = 'howMuchIsTheFish' self.assertRaises( NotImplementedError, lambda: self.invalid_view(request=self.factory.get( '/fake.json?jsonp={0}'.format(callback)))) def test_no_callback(self): response = self.simple_dict_view( request=self.factory.get('/fake.json?')) self.assertIsInstance(response, HttpResponseBadRequest)
class FBVTestCase(TestCase): def setUp(self): self.factory = RequestFactory() self.dict_response = dict(foo='bar') @jsonp def simple_dict_view(request): return self.dict_response @jsonp def simple_http_response_view(request): return HttpResponse(json.dumps(self.dict_response)) self.simple_dict_view = simple_dict_view self.simple_http_response_view = simple_http_response_view def assert_content_and_content_type(self, response, callback): self.assertContains(response, callback) self.assertContains(response, json.dumps(self.dict_response)) self.assertEqual(response['Content-Type'], APPLICATION_JS) def test_response_correct_format_from_dict(self): callback = 'showMeTheMoney' request = self.factory.get('/fake.json?callback={0}'.format(callback)) response = self.simple_dict_view(request) self.assertContains( response, '{0}({1})'.format(callback, json.dumps(self.dict_response))) self.assertEqual(APPLICATION_JS, response['Content-Type']) def test_response_correct_from_http_response(self): callback = 'whatsMyAgeAgain' response = self.simple_http_response_view( self.factory.get('/fake.json?callback={0}'.format(callback))) self.assert_content_and_content_type(response, callback) def test_with_different_callback_param_name(self): callback = 'giveMeNovocaine' response = self.simple_http_response_view( request=self.factory.get('/fake.json?jsonp={0}'.format(callback))) self.assert_content_and_content_type(response, callback) def test_method_not_allowed(self): callback = 'isThereASpoon' put_response = self.simple_dict_view( request=self.factory.put('/fake.json?jsonp={0}'.format(callback))) post_response = self.simple_dict_view( request=self.factory.post('/fake.json?jsonp={0}'.format(callback))) delete_response = self.simple_dict_view(request=self.factory.delete( '/fake.json?jsonp={0}'.format(callback))) for r in [put_response, post_response, delete_response]: self.assertIsInstance(r, HttpResponseNotAllowed)
def test_staff_can_set_editor(self): """ Ensure that a staff user can set itself as an editor to any paper and a regular user can't. """ request_factory = RequestFactory() staff_user = User.objects.create_user('staffuser', '*****@*****.**', 'testpassword', is_staff=True) paper = Paper.objects.create(user=self.test_user) # Authenticate the staff user data = { 'username': '******', 'password': '******' } response = self.client.post(self.get_token, data) staff_token = "JWT {}".format(response.data["token"]) request = request_factory.post(reverse('api:api-papers-editor-add', kwargs={'pk': 1}), HTTP_AUTHORIZATION=staff_token) # Set staff user as an editor on the test user's paper. self.assertEqual(paper.editor, None) response = journal.set_editor(request, paper.pk) self.assertEqual(response.status_code, status.HTTP_200_OK) paper = Paper.objects.get(user=self.test_user) self.assertEqual(paper.editor.pk, staff_user.pk) # Staff user can delete itself as an editor request = request_factory.delete(reverse('api:api-papers-editor-add', kwargs={'pk': 1}), HTTP_AUTHORIZATION=staff_token) response = journal.set_editor(request, paper.pk) self.assertEqual(response.status_code, status.HTTP_200_OK) paper = Paper.objects.get(user=self.test_user) self.assertEqual(paper.editor, None) # Non-staff user cannot set itself as an editor request = request_factory.delete(reverse('api:api-papers-editor-add', kwargs={'pk': 1}), HTTP_AUTHORIZATION=self.authorization_header) response = journal.set_editor(request, paper.pk) self.assertNotEqual(response.status_code, status.HTTP_200_OK)
class FBVTestCase(TestCase): def setUp(self): self.factory = RequestFactory() self.dict_response = dict(foo='bar') @jsonp def simple_dict_view(request): return self.dict_response @jsonp def simple_http_response_view(request): return HttpResponse(json.dumps(self.dict_response)) self.simple_dict_view = simple_dict_view self.simple_http_response_view = simple_http_response_view def assert_content_and_content_type(self, response, callback): self.assertContains(response, callback) self.assertContains(response, json.dumps(self.dict_response)) self.assertEqual(response['Content-Type'], APPLICATION_JS) def test_response_correct_format_from_dict(self): callback = 'showMeTheMoney' request = self.factory.get('/fake.json?callback={0}'.format(callback)) response = self.simple_dict_view(request) self.assertContains(response, '{0}({1})'.format(callback, json.dumps(self.dict_response))) self.assertEqual(APPLICATION_JS, response['Content-Type']) def test_response_correct_from_http_response(self): callback = 'whatsMyAgeAgain' response = self.simple_http_response_view(self.factory.get('/fake.json?callback={0}'.format(callback))) self.assert_content_and_content_type(response, callback) def test_with_different_callback_param_name(self): callback = 'giveMeNovocaine' response = self.simple_http_response_view(request=self.factory.get('/fake.json?jsonp={0}'.format(callback))) self.assert_content_and_content_type(response, callback) def test_method_not_allowed(self): callback = 'isThereASpoon' put_response = self.simple_dict_view(request=self.factory.put('/fake.json?jsonp={0}'.format(callback))) post_response = self.simple_dict_view(request=self.factory.post('/fake.json?jsonp={0}'.format(callback))) delete_response = self.simple_dict_view(request=self.factory.delete('/fake.json?jsonp={0}'.format(callback))) for r in [put_response, post_response, delete_response]: self.assertIsInstance(r, HttpResponseNotAllowed)
class CBVTestCase(TestCase): def setUp(self): self.factory = RequestFactory() dict_response = dict(foo='bar') self.dict_response = dict_response @jsonp class DictResponse(View): def get(self, request): return dict_response @jsonp class InvalidResponseFormat(View): def get(self, request): return [] self.simple_dict_view = DictResponse.as_view() self.invalid_view = InvalidResponseFormat.as_view() def assert_content_and_content_type(self, response, callback): self.assertContains(response, callback) self.assertContains(response, json.dumps(self.dict_response)) self.assertEqual(response['Content-Type'], APPLICATION_JS) def test_correct_response(self): callback = 'isThereASpoon' response = self.simple_dict_view(request=self.factory.get('/fake.json?jsonp={0}'.format(callback))) self.assert_content_and_content_type(response, callback) def test_method_not_allowed(self): callback = 'isThereASpoon' put_response = self.simple_dict_view(request=self.factory.put('/fake.json?jsonp={0}'.format(callback))) post_response = self.simple_dict_view(request=self.factory.post('/fake.json?jsonp={0}'.format(callback))) delete_response = self.simple_dict_view(request=self.factory.delete('/fake.json?jsonp={0}'.format(callback))) for r in [put_response, post_response, delete_response]: self.assertIsInstance(r, HttpResponseNotAllowed) def test_invalid_response_format(self): callback = 'howMuchIsTheFish' self.assertRaises(NotImplementedError, lambda: self.invalid_view(request=self.factory.get('/fake.json?jsonp={0}'.format(callback)))) def test_no_callback(self): response = self.simple_dict_view(request=self.factory.get('/fake.json?')) self.assertIsInstance(response, HttpResponseBadRequest)
class testcasetwo(unittest.TestCase): def setUp(self) -> None: self.factory = RequestFactory() def test_one(self): request = self.factory.get('') response = read_file(request, 'file') self.assertEqual(response.status_code, 200) def test_two(self): request = self.factory.get('') response = read_file(request, 'file_two') self.assertNotEqual(response, HttpResponse('no such file found')) def test_three(self): request = self.factory.delete('') response = delete_file(request, 'file_two') self.assertEqual(response, HttpResponse('file deleted successfully'))
def create_request(method='get', **kwargs): resource_link_id = kwargs.pop('resource_link_id', "2a8b2d3fa51ea413d19e480fb6c2eb085b7866a9") session = {"LTI_LAUNCH": {}} session['LTI_LAUNCH'][resource_link_id] = kwargs.pop('session') params = kwargs.pop('params', {}) body = kwargs.pop('data', {}) url = kwargs.pop('url', '/foo') request_factory = RequestFactory() if method == 'get': request = request_factory.get(url, data=params, content_type='application/json') elif method == 'post': request = request_factory.post(url, data=json.dumps(body), content_type='application/json') elif method == 'put': request = request_factory.put(url, data=json.dumps(body), content_type='application/json') elif method == 'delete': request = request_factory.delete(url, data=json.dumps(body), content_type='application/json') else: raise Exception("invalid method: %s" % method) request.session = session setattr(request, 'LTI', session.get('LTI_LAUNCH', {}).get(resource_link_id)) return request
class ComplexTest(unittest.TestCase): def setUp(self) -> None: self.factory = RequestFactory() def test_one(self): """will pass if a file named 'file' exist otherwise fail""" request = self.factory.get('') response = function_one(request, 'file') self.assertEqual(response.status_code, 200) def test_two(self): """Will pass as no file_two exists""" request = self.factory.get('') response = function_one(request, 'file_two') self.assertNotEqual( response, HttpResponse('no such file found') ) # what the function returns, comparing it with response def test_three(self): """Will fail""" request = self.factory.delete('') response = function_one(request, 'file_two') self.assertEqual(response, HttpResponse('file deleted successfully'))
class TestRatingResource(BaseSegmentsTest): """Tests on RatingResource""" def setUp(self): super(TestRatingResource, self).setUp() self.req = RequestFactory() def test_parsers(self): from project.resources import RatingInstanceView, RatingJSONParser from djangorestframework.parsers import JSONParser from StringIO import StringIO self.assertEqual(len(RatingInstanceView.parsers), 4) self.assertNotIn(JSONParser, RatingInstanceView.parsers) self.assertIn(RatingJSONParser, RatingInstanceView.parsers) parser = RatingJSONParser(None) # None for the view json_string = StringIO('{"criterion":3,"question":"How much do you like it?","score":"4","segment":456,"block_index":5239,"url":"http://localhost:8000/ratings/13","id":13}') self.assertNotIn(u'id', parser.parse(json_string)) def test_read(self): from project.models import Rating, Criterion, Segment criterion = Criterion.objects.create(prompt='Hello?') segment = Segment.objects.create(id=123) rating = Rating.objects.create(criterion=criterion, segment1=segment, block1_index=2, segment2=segment, block2_index=2, score=5) from project.resources import RatingInstanceView request = self.req.get('/ratings/{}'.format(rating.id)) view = RatingInstanceView() response = view.get(request, rating.id) self.assertEquals(rating, response) def test_delete(self): from project.models import Rating, Criterion, Segment criterion = Criterion.objects.create(prompt='Hello?') segment = Segment.objects.create(id=123) Rating.objects.all().delete() rating = Rating.objects.create(criterion=criterion, segment1=segment, block1_index=2, segment2=segment, block2_index=2, score=5) from project.resources import RatingInstanceView request = self.req.delete('/ratings/{}'.format(rating.id)) view = RatingInstanceView() response = view.delete(request, rating.id) assert_equal(Rating.objects.count(), 0) def test_update(self): from project.models import Rating, Criterion, Segment criterion1 = Criterion.objects.create(prompt='Hello?') criterion2 = Criterion.objects.create(prompt='Goodbye!') segment1 = Segment.objects.create(id=123) segment2 = Segment.objects.create(id=456) rating = Rating.objects.create(criterion=criterion1, segment1=segment1, block1_index=2, segment2=segment1, block2_index=2, score=5) from project.resources import RatingInstanceView request = self.req.put('/ratings/{}'.format(rating.id), data={ 'segment2': segment2.id, 'block2_index': 14, 'segment1': segment2.id, 'block1_index': 14, 'criterion': criterion2.id, 'score': 2}) view = RatingInstanceView() view.request = request response = view.put(request, rating.id) self.assertEquals(rating, response) self.assertEqual(response.criterion, criterion2) self.assertEqual(response.segment2, segment2) self.assertEqual(response.block2_index, 14) self.assertEqual(response.score, 2) def test_create(self): from project.models import Rating, Criterion, Segment criterion = Criterion.objects.create(prompt='Hello?') segment1 = Segment.objects.create(id=123) segment2 = Segment.objects.create(id=456) Rating.objects.all().delete() from project.resources import RatingListView request = self.req.post('/ratings/', data={ 'segment1': segment1.id, 'block1_index': 7, 'segment2': segment2.id, 'block2_index': 14, 'criterion': criterion.id, 'score': 2}) view = RatingListView() view.request = request response = view.post(request) self.assertEquals(Rating.objects.count(), 1) self.assertEqual(response.cleaned_content.criterion, criterion) self.assertEqual(response.cleaned_content.segment1, segment1) self.assertEqual(response.cleaned_content.block1_index, 7) self.assertEqual(response.cleaned_content.score, 2)
class UserApiTestCase(TestCase): def setUp(self): # Set up a Request Factory self.factory = RequestFactory() # Set up some Users self.john = User.create_new_user( u = 'John', p = 'hehehe', zip_c = '00413', e = '*****@*****.**', pn = '4134131996', pa = 'mailbox', ) self.john.save() # Mock session, where applicable self.mock_session = \ { "user" : api.user_to_json(self.john) } # Session with no data self.empty_session = { } # Accurate login credentials self.good_login = \ { 'username' : self.john.username, 'password' : "hehehe", } # New user form self.add_jade = \ { 'username' : "Jade", 'password' : "tanglebuddies", 'confirm_password' : "tanglebuddies", 'zip_code' : '00413', 'email' : "*****@*****.**", 'phone_number' : "4131211995", 'default_pickup_arrangements' : "time shenanigans", } # Change user form self.edit_john = \ { 'zip_code' : '00612', 'email' : "*****@*****.**", 'phone_number' : '4134132009', 'default_pickup_arrangements' : "parcel pixys", } def test_getSelf(self): # Generate the request request = self.factory.get('/api/user/') request.session = self.mock_session response = api.user(request) # Did we get a clean response? self.assertEqual(response.status_code, 200) # Did we get the right data? response_data = json.loads(response.content.decode("utf-8")) self.assertEqual(response_data["id"], self.john.id) self.assertEqual(response_data["username"], self.john.username) self.assertEqual(response_data["zip_code"], self.john.zip_code) self.assertEqual(response_data["email"], self.john.email) self.assertEqual(response_data["phone_number"], self.john.phone_number) self.assertEqual(response_data["default_pickup_arrangements"], self.john.default_pickup_arrangements) self.assertEqual(response_data["is_shed_coordinator"], self.john.is_shed_coordinator) self.assertEqual(response_data["is_admin"], self.john.is_admin) def test_login(self): # Generate the request request = self.factory.post( path = '/api/login/', data = json.dumps(self.good_login), content_type = "application/json", ) request.session = self.empty_session response = api.login(request) # Did we get a clean response? self.assertEqual(response.status_code, 200) # Did we get the right data? response_data = json.loads(response.content.decode("utf-8")) self.assertEqual(response_data["id"], self.john.id) self.assertEqual(response_data["username"], self.john.username) self.assertEqual(response_data["zip_code"], self.john.zip_code) self.assertEqual(response_data["email"], self.john.email) self.assertEqual(response_data["phone_number"], self.john.phone_number) self.assertEqual(response_data["default_pickup_arrangements"], self.john.default_pickup_arrangements) self.assertEqual(response_data["is_shed_coordinator"], self.john.is_shed_coordinator) self.assertEqual(response_data["is_admin"], self.john.is_admin) def test_createNewUser(self): # Generate the request request = self.factory.post( path = '/api/user/', data = json.dumps(self.add_jade), content_type = "application/json", ) request.session = self.empty_session response = api.user(request) # Did we get a clean response? self.assertEqual(response.status_code, 200) # Did we get the right data? response_data = json.loads(response.content.decode("utf-8")) self.assertEqual(response_data['username'], self.add_jade['username']) self.assertEqual(response_data['zip_code'], self.add_jade['zip_code']) self.assertEqual(response_data['email'], self.add_jade['email']) self.assertEqual(response_data['phone_number'], self.add_jade['phone_number']) self.assertEqual(response_data['default_pickup_arrangements'], self.add_jade['default_pickup_arrangements']) # We don't know the ID, but we know it has to be different. self.assertNotEqual(response_data['id'], self.john.id) # Only the first user in each zone should be the coordinator. self.assertNotEqual(response_data['is_shed_coordinator'], self.john.is_shed_coordinator) # New users should not be admins by default. self.assertEqual(response_data['is_admin'], False) def test_userProfileEdit(self): # Generate the request request = self.factory.put( path = '/api/user/', data = json.dumps(self.edit_john), content_type = "application/json", ) request.session = self.mock_session response = api.userById(request, self.john.id) # Did we get a clean response? self.assertIsNotNone(response) self.assertEqual(response.status_code, 200) # Did the data change? response_data = json.loads(response.content.decode("utf-8")) self.assertEqual(response_data["id"], self.john.id) self.assertEqual(response_data["username"], self.john.username) self.assertNotEqual(response_data["zip_code"], self.john.zip_code) self.assertNotEqual(response_data["email"], self.john.email) self.assertNotEqual(response_data["phone_number"], self.john.phone_number) self.assertNotEqual(response_data["default_pickup_arrangements"], self.john.default_pickup_arrangements) #self.assertEqual(response_data["is_shed_coordinator"], # self.john.is_shed_coordinator) self.assertEqual(response_data["is_admin"], self.john.is_admin) @unittest.skip #not ready yet def test_deleteUserProfile(self): request = self.factory.delete('/api/user/:id') @unittest.skip #not ready yet def test_getUsersInZipcode(self): request = self.factory.get('/api/user/zip/:zip_code') @unittest.skip #not ready yet def test_changePassword(self): request = self.factory.put('/api/changePassword') @unittest.skip #not ready yet def test_logout(self): request = self.factory.get('/api/user/logout') @unittest.skip #not ready yet def test_getAdmins(self): request = self.factory.get('/api/admins') @unittest.skip #not ready yet def test_changeShedCoordinator(self): request = self.factory.put('/api/admin/shedCoordinator')
class CRUDViewTest(TestCase): names = ['John', 'Anne', 'Chris', 'Beatrice', 'Matt'] def setUp(self): self.factory = RequestFactory() model2 = DummyModel2(name="Model2 name") model2.save() for name in self.names: DummyModel(name=name, model2=model2).save() def test_ng_query(self): request = self.factory.get('/crud/') response = CRUDTestViewWithFK.as_view()(request) data = json.loads(response.content) for obj in data: db_obj = DummyModel.objects.get(pk=obj['pk']) self.assertEqual(obj['name'], db_obj.name) def test_ng_get(self): request = self.factory.get('/crud/?pk=1') response = CRUDTestViewWithFK.as_view()(request) data = json.loads(response.content) self.assertEqual(self.names[0], data['name']) def test_ng_save_create(self): request = self.factory.post('/crud/', data=json.dumps({'name': 'Leonard'}), content_type='application/json') response = CRUDTestView.as_view()(request) data = json.loads(response.content) pk = data['pk'] request2 = self.factory.get('/crud/?pk=%d' % pk) response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content) self.assertEqual(data2['name'], 'Leonard') def test_ng_save_update(self): request = self.factory.post('/crud/?pk=1', data=json.dumps({ 'pk': 1, 'name': 'John2' }), content_type='application/json') response = CRUDTestView.as_view()(request) data = json.loads(response.content) self.assertEqual(data['name'], 'John2') request2 = self.factory.get('/crud/?pk=1') response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content) self.assertEqual(data2['name'], 'John2') def test_ng_delete(self): request = self.factory.delete('/crud/?pk=1') response = CRUDTestViewWithFK.as_view()(request) data = json.loads(response.content) deleted_name = data['name'] request2 = self.factory.get('/crud/') response2 = CRUDTestViewWithFK.as_view()(request2) data2 = json.loads(response2.content) for obj in data2: self.assertTrue(deleted_name != obj['name'])
class ResourceEntryTestCase(TestCase): tags = ('offering-api',) def setUp(self): # Create request factory self.factory = RequestFactory() # Create testing user self.user = User.objects.create_user(username='******', email='', password='******') self.user.userprofile.get_current_roles = MagicMock(name='get_current_roles') self.user.userprofile.get_current_roles.return_value = ['provider', 'customer'] self.user.userprofile.save() # Create resource model mock self.resource = MagicMock() self.resource.provider = self.user.userprofile.current_organization views.OfferingResource = MagicMock() views.OfferingResource.objects.get.return_value = self.resource @classmethod def tearDownClass(cls): from wstore.offerings import offerings_management reload(offerings_management) reload(views) super(ResourceEntryTestCase, cls).tearDownClass() def tearDown(self): views.json = json def _not_found(self): views.OfferingResource.objects.get.side_effect = Exception('Not found') def _no_provider(self): self.user.userprofile.get_current_roles.return_value = ['customer'] def _exception_update(self): views.update_resource.side_effect = Exception('Exception in call') def _exception_upgrade(self): views.upgrade_resource.side_effect = Exception('Exception in call') def _exception_delete(self): views.delete_resource.side_effect = Exception('Exception in call') def _invalid_json(self): views.json = MagicMock() views.json.loads.side_effect = Exception('Invalid content') @parameterized.expand([ (RESOURCE_DATA, 200, 'OK'), (RESOURCE_DATA, 400, 'Invalid content', _invalid_json, 'error'), (RESOURCE_DATA, 403, 'Forbidden', _no_provider, 'error'), (RESOURCE_DATA, 400, 'Exception in call', _exception_update, 'error') ]) def test_resource_update_api(self, data, code, msg, side_effect=None, status='correct'): views.update_resource = MagicMock(name='update_resource') if side_effect: side_effect(self) request = self.factory.put( '/api/offering/resources/test_user/test_resource/1.0', json.dumps(data), content_type='application/json', HTTP_ACCEPT='application/json' ) request.user = self.user res_entry = views.ResourceEntry(permitted_methods=('PUT', 'POST', 'DELETE')) response = res_entry.update(request, 'test_user', 'test_resource', '1.0') self.assertEqual(response.status_code, code) self.assertEqual(response.get('Content-type'), 'application/json; charset=utf-8') body_response = json.loads(response.content) self.assertEquals(type(body_response), dict) self.assertEquals(body_response['message'], msg) self.assertEquals(body_response['result'], status) # Check call to update method if needed if status != 'error': views.update_resource.assert_called_once_with(self.resource, self.user, data) @parameterized.expand([ (RESOURCE_DATA, 200, 'OK'), (RESOURCE_DATA, 200, 'OK', True), (RESOURCE_DATA, 400, 'Invalid content', False, _invalid_json, True), (RESOURCE_DATA, 400, 'Invalid content', True, _invalid_json, True), (RESOURCE_DATA, 404, 'Resource not found', False, _not_found, True), (RESOURCE_DATA, 403, 'Forbidden', False, _no_provider, True), (RESOURCE_DATA, 400, 'Exception in call', False, _exception_upgrade, True) ]) def test_resource_upgrade_api(self, data, code, msg, file_=False, side_effect=None, error=False): # Mock update method views.upgrade_resource = MagicMock(name='upgrade_resource') if side_effect: side_effect(self) content = json.dumps(data) content_type = 'application/json' if file_: f = StringIO() f.name = 'test_file.txt' f.write('test file') content = { 'json': json.dumps(data), 'file': f } content_type = MULTIPART_CONTENT request = self.factory.post( '/api/offering/resources/test_user/test_resource/1.0', content, content_type=content_type, HTTP_ACCEPT='application/json' ) request.user = self.user res_entry = views.ResourceEntry(permitted_methods=('PUT', 'POST', 'DELETE')) response = res_entry.create(request, 'test_user', 'test_resource', '1.0') self.assertEqual(response.status_code, code) self.assertEqual(response.get('Content-type'), 'application/json; charset=utf-8') body_response = json.loads(response.content) self.assertEqual(type(body_response), dict) self.assertEqual(body_response['message'], msg) if not error: if not file_: views.upgrade_resource.assert_called_once_with(self.resource, self.user, data) else: expected_file = request.FILES['file'] # The type change when loaded views.upgrade_resource.assert_called_once_with(self.resource, self.user, data, expected_file) self.assertEqual(body_response['result'], 'correct') else: self.assertEqual(body_response['result'], 'error') @parameterized.expand([ (204, 'No Content'), (404, 'Resource not found', _not_found, True), (403, 'Forbidden', _no_provider, True), (400, 'Exception in call', _exception_delete, True) ]) def test_resource_deletion_api(self, code, msg, side_effect=None, error=False): # Mock delete resource method views.delete_resource = MagicMock(name='delete_resource') if side_effect: side_effect(self) request = self.factory.delete( '/api/offering/resources/test_user/test_resource/1.0', HTTP_ACCEPT='application/json' ) request.user = self.user res_entry = views.ResourceEntry(permitted_methods=('POST', 'DELETE')) response = res_entry.delete(request, 'test_user', 'test_resource', '1.0') self.assertEqual(response.status_code, code) self.assertEqual(response.get('Content-type'), 'application/json; charset=utf-8') body_response = json.loads(response.content) self.assertEqual(type(body_response), dict) self.assertEqual(body_response['message'], msg) if not error: views.delete_resource.assert_called_once_with(self.resource, self.user) self.assertEqual(body_response['result'], 'correct') else: self.assertEqual(body_response['result'], 'error')
class ViewTest(unittest.TestCase): """ Tests for BackboneAPIView. Note that django.contrib.auth must be in INSTALLED_APPS for these to work. """ def setUp(self): self.factory = RequestFactory() self.view = ReadOnlyView.as_view() self.writable_view = FullView.as_view() self.user1 = User.objects.create(username='******', first_name='Test', last_name='One') def tearDown(self): User.objects.all().delete() def add_two_more_users(self): self.user2 = User.objects.create(username='******', first_name='Test', last_name='Two') self.user3 = User.objects.create(username='******', first_name='Test', last_name='Three') def test_collection_get(self): request = self.factory.get('/users/') response = self.view(request) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) # Ensure response json deserializes to a 1-item list: self.assert_(isinstance(response_data, list)) self.assertEqual(len(response_data), 1) self.assertEqual(response_data[0]['username'], self.user1.username) # Try again with a few more users in the database: self.add_two_more_users() response = self.view(request) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) self.assert_(isinstance(response_data, list)) self.assertEqual(len(response_data), 3) # With User model's default ordering (by id), user3 should be last: self.assertEqual(response_data[2]['username'], self.user3.username) # Test pagination: response = self.writable_view(request) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) self.assert_(isinstance(response_data, list)) self.assertEqual(len(response_data), 2) # Page 2 should only have one item: request = self.factory.get('/users/?p=2') response = self.writable_view(request) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) self.assert_(isinstance(response_data, list)) self.assertEqual(len(response_data), 1) def test_single_item_get(self): request = self.factory.get('/users/1') response = self.view( request, id='1') # Simulate a urlconf passing in the 'id' kwarg self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) self.assert_(isinstance(response_data, dict)) self.assertEqual(response_data['username'], self.user1.username) # Ensure 404s are raised for non-existent items: request = self.factory.get('/users/7') self.assertRaises(Http404, lambda: self.view(request, id='7')) def test_post(self): request = self.factory.post('/users') response = self.view(request) self.assertEqual( response.status_code, 405) # "Method not supported" if no add_form_class specified # Testing BackboneAPIView subclasses that support POST via add_form_class: # If no JSON provided in POST body, return HTTP 400: response = self.writable_view(request) self.assertEqual(response.status_code, 400) # Test the case where invalid input is given (leading to form errors): request = self.factory.post('/users', '{"wrong_field": "xyz"}', content_type='application/json') response = self.writable_view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.content, 'ERROR: validation failed') # If valid JSON was provided, a new instance should be created: request = self.factory.post('/users', '{"username": "******"}', content_type='application/json') response = self.writable_view(request) self.assertEqual(response.status_code, 200) self.assert_(User.objects.get(username='******')) response_json = json.loads(response.content) self.assertEqual(response_json['username'], 'post_test') def test_put(self): request = self.factory.put('/users/1') response = self.view(request, id='1') self.assertEqual( response.status_code, 405) # "Method not supported" if no edit_form_class specified # PUT is also not supported for collections (when no id is provided): request = self.factory.put('/users') response = self.writable_view(request) self.assertEqual(response.status_code, 405) # If no JSON in PUT body, return HTTP 400: response = self.writable_view(request, id='1') self.assertEqual(response.status_code, 400) # Raise 404 if an object with the given id doesn't exist: request = self.factory.put('/users/27', '{"username": "******"}', content_type='application/json') self.assertRaises(Http404, lambda: self.writable_view(request, id='27')) # If the object exists and an edit_form_class is supplied, it actually does something: request = self.factory.put('/users/1', '{"username": "******"}', content_type='application/json') response = self.writable_view(request, id='1') self.assertEqual(response.status_code, 200) self.assertEqual(User.objects.get(id=1).username, 'put_test') response_json = json.loads(response.content) self.assertEqual(response_json['username'], 'put_test') # Test the case where invalid input is given (leading to form errors): request = self.factory.put('/users/1', '{"wrong_field": "xyz"}', content_type='application/json') response = self.writable_view(request, id='1') self.assertEqual(response.status_code, 200) self.assertEqual(response.content, 'ERROR: validation failed') def test_delete(self): # Delete is not supported for collections: request = self.factory.delete('/users') response = self.view(request) self.assertEqual(response.status_code, 405) self.assertEqual(User.objects.filter(id=1).count(), 1) # But it is supported for single items (specified by id): request = self.factory.delete('/users/1') response = self.view(request, id='1') self.assertEqual(response.status_code, 200) self.assertEqual(User.objects.filter(id=1).count(), 0) # Should raise 404 if we try to access a deleted resource again: request = self.factory.delete('/users/1') self.assertRaises(Http404, lambda: self.view(request, id='1'))
class DRYRestPermissionsTests(TestCase): def setUp(self): self.action_set = [ 'retrieve', 'list', 'create', 'destroy', 'update', 'partial_update', 'custom_action1', 'custom_action2' ] self.factory = RequestFactory() self.request_retrieve = Request(self.factory.get('/dummy/1')) self.request_list = Request(self.factory.get('/dummy')) self.request_create = Request(self.factory.post('/dummy'), {}) self.request_destroy = Request(self.factory.delete('/dummy/1')) self.request_update = Request(self.factory.put('/dummy/1', {})) self.request_partial_update = Request( self.factory.patch('/dummy/1', {})) self.request_custom_action1 = Request( self.factory.get('/dummy/custom_action1')) self.request_custom_action2 = Request( self.factory.post('/dummy/custom_action2', {})) def _run_permission_checks(self, view, obj, assert_value): for action in self.action_set: view.action = action request_name = "request_{action}".format(action=action) result = view.dummy_check_permission(getattr(self, request_name), obj) self.assertEqual(result, assert_value) def _run_dry_permission_field_checks(self, view, obj, assert_specific, assert_base): serializer = view.get_serializer_class()() # dummy request serializer.context['request'] = self.request_retrieve representation = serializer.to_representation(obj) for action in [ action for action in self.action_set if action not in ['partial_update', 'list'] ]: has_permission = representation['permissions'].get(action, None) self.assertEqual( has_permission, assert_specific, "Action '%s' %s != %s" % (action, has_permission, assert_specific)) for action in ['read', 'write']: has_permission = representation['permissions'].get(action, None) self.assertEqual( has_permission, assert_base, "Action '%s' %s != %s" % (action, has_permission, assert_base)) def test_true_base_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin): pass class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), True) self._run_dry_permission_field_checks(view, TestModel(), None, True) def test_false_base_object_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin): base_object_allowed = False class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), False) self._run_dry_permission_field_checks(view, TestModel(), None, False) def test_false_base_global_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin): base_global_allowed = False class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), False) self._run_dry_permission_field_checks(view, TestModel(), None, False) def test_true_specific_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin, SpecificObjectMixin, SpecificGlobalMixin): base_global_allowed = False base_object_allowed = False class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), True) self._run_dry_permission_field_checks(view, TestModel(), True, False) def test_true_base_not_defined_permissions(self): class TestModel(DummyModel, SpecificObjectMixin, SpecificGlobalMixin): pass class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), True) self._run_dry_permission_field_checks(view, TestModel(), True, None) def test_false_specific_object_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin, SpecificObjectMixin, SpecificGlobalMixin): specific_object_allowed = False class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), False) self._run_dry_permission_field_checks(view, TestModel(), False, True) def test_false_specific_global_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin, SpecificObjectMixin, SpecificGlobalMixin): specific_global_allowed = False class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), False) self._run_dry_permission_field_checks(view, TestModel(), False, True) def test_true_no_global_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin, SpecificObjectMixin, SpecificGlobalMixin): base_global_allowed = False specific_global_allowed = False class TestSerializer(DummySerializer): permissions = DRYPermissionsField( object_only=True, additional_actions=['custom_action1', 'custom_action2']) class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer permission_classes = (DRYObjectPermissions, ) view = TestViewSet() self._run_permission_checks(view, TestModel(), True) self._run_dry_permission_field_checks(view, TestModel(), True, True) def test_true_no_object_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin, SpecificObjectMixin, SpecificGlobalMixin): base_object_allowed = False specific_object_allowed = False class TestSerializer(DummySerializer): permissions = DRYPermissionsField( global_only=True, additional_actions=['custom_action1', 'custom_action2']) class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer permission_classes = (DRYGlobalPermissions, ) view = TestViewSet() self._run_permission_checks(view, TestModel(), True) self._run_dry_permission_field_checks(view, TestModel(), True, True) def test_list_filter_backend(self): class DummyFilter(object): pass class TestModel(DummyModel): pass class TestSerializer(DummySerializer): class Meta: model = TestModel class TestFilterBackend(DRYPermissionFiltersBase): def filter_list_queryset(self, request, queryset, view): return DummyFilter() class TestViewSet(DummyViewSet): serializer_class = TestSerializer queryset = TestModel.objects.all() filter_backends = (TestFilterBackend, ) view = TestViewSet() view.request = self.request_list view.action = 'list' view.kwargs = [] query_set = view.filter_queryset(view.get_queryset()) self.assertEqual(query_set.__class__, DummyFilter) def test_action_filter_backend(self): class DummyFilter(object): pass class TestModel(DummyModel): pass class TestSerializer(DummySerializer): class Meta: model = TestModel class TestFilterBackend(DRYPermissionFiltersBase): action_routing = True def filter_list_queryset(self, request, queryset, view): return None def filter_custom_action1_queryset(self, request, queryset, view): return DummyFilter() class TestViewSet(DummyViewSet): serializer_class = TestSerializer queryset = TestModel.objects.all() filter_backends = (TestFilterBackend, ) view = TestViewSet() view.request = self.request_custom_action1 view.action = 'custom_action1' view.kwargs = [] query_set = view.filter_queryset(view.get_queryset()) self.assertEqual(query_set.__class__, DummyFilter)
class TestGames(TestCase): def setUp(self): self.factory = RequestFactory() def test_POST_game(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) response_content = literal_eval(response.content.decode('utf-8')) db_query = literal_eval( serializers.serialize("json", [Game.objects.get(pk=1)])) self.assertEqual(response.status_code, 201) self.assertEqual(response_content, id_1) self.assertEqual(db_query[0]["fields"], base_game_output) def test_POST_game_with_no_image_key(self): setup_db_for_game() game_data = base_game_input.copy() game_data.pop("images") request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_empty_image(self): setup_db_for_game() game_data = base_game_input.copy() game_data["images"] = [] request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_no_name(self): setup_db_for_game() game_data = base_game_input.copy() game_data.pop("name") request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_empty_name(self): setup_db_for_game() game_data = base_game_input.copy() game_data["name"] = " " request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_no_video(self): setup_db_for_game() game_data = base_game_input.copy() game_data.pop("videos") request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_empty_video(self): setup_db_for_game() game_data = base_game_input.copy() game_data["videos"] = [] request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_no_company(self): setup_db_for_game() game_data = base_game_input.copy() game_data.pop("company") request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_empty_company(self): setup_db_for_game() game_data = base_game_input.copy() game_data["company"] = None request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_invalid_company(self): setup_db_for_game() game_data = base_game_input.copy() game_data["company"] = 2 request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_POST_game_with_no_people(self): setup_db_for_game() game_data = base_game_input.copy() game_data.pop("people") request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_empty_people(self): setup_db_for_game() game_data = base_game_input.copy() game_data["people"] = [] request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_invalid_people(self): setup_db_for_game() game_data = base_game_input.copy() game_data["people"] = [2] request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_POST_game_with_no_genre(self): setup_db_for_game() game_data = base_game_input.copy() game_data.pop("genre") request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_empty_genre(self): setup_db_for_game() game_data = base_game_input.copy() game_data["genre"] = [] request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_invalid_genre(self): setup_db_for_game() game_data = base_game_input.copy() game_data["genre"] = [2] request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_POST_game_with_no_system(self): setup_db_for_game() game_data = base_game_input.copy() game_data.pop("system") request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_empty_system(self): setup_db_for_game() game_data = base_game_input.copy() game_data["system"] = None request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_game_with_invalid_system(self): setup_db_for_game() game_data = base_game_input.copy() game_data["system"] = 3 request = self.factory.post('api/games/', game_data, content_type='application/json') response = api_games(request) self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_GET_all_games(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) request = self.factory.get('api/games/') response = api_games(request) response_content = literal_eval(response.content.decode('utf-8')) db_query = literal_eval( serializers.serialize("json", Game.objects.all(), fields=("name"))) db_query[0]["fields"]["images"] = ["http://image.com"] db_query[1]["fields"]["images"] = ["http://image.com"] self.assertEqual(response.status_code, 200) self.assertEqual(db_query, response_content) def test_PUT_game(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) request = self.factory.put('api/games/1/', updated_game_input, content_type='application/json') response = api_games_id(request, 1) response_content = response.content.decode('utf-8') game_object = Game.objects.get(pk=1) db_query = literal_eval(serializers.serialize("json", [game_object])) self.assertEqual(response.status_code, 204) self.assertEqual(db_query[0]["fields"], updated_game) self.assertEqual(game_object.images()[0].link, updated_game_input["images"][0]) self.assertEqual(game_object.videos()[0].link, updated_game_input["videos"][0]) def test_PUT_game_with_empty_image(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["images"] = [] request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_PUT_game_with_empty_name(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["name"] = [] request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_PUT_game_with_empty_video(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["videos"] = [] request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_PUT_game_with_empty_company(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["company"] = None request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_PUT_game_with_invalid_company(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["company"] = 2 request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_PUT_game_with_empty_people(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["people"] = [] request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_PUT_game_with_invalid_people(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["people"] = [2] request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_PUT_game_with_empty_genre(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["genre"] = [] request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_PUT_game_with_invalid_genre(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["people"] = [2] request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_PUT_game_with_empty_system(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["system"] = None request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_PUT_game_with_invalid_system(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) game_data = base_game_input.copy() game_data["system"] = "mitch" request = self.factory.put('api/games/1/', game_data, content_type='application/json') response = api_games_id(request, 1) self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_GET_game(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) request = self.factory.get('api/games/1/') response = api_games_id(request, '1') game_object = Game.objects.get(pk=1) db_query = literal_eval(serializers.serialize("json", [game_object])) response_content = literal_eval(response.content.decode('utf-8')) image_list = response_content[0]["fields"].pop("images") video_list = response_content[0]["fields"].pop("videos") response_content[0]["fields"]["genre"] = [1] response_content[0]["fields"]["system"] = 1 self.assertEqual(response.status_code, 200) self.assertEqual(db_query, response_content) self.assertEqual(game_object.images()[0].link, image_list[0]) self.assertEqual(game_object.videos()[0].link, video_list[0]) def test_GET_game_with_bad_id(self): request = self.factory.get('api/games/1/') response = api_companies_id(request, '1') self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_DELETE_games(self): setup_db_for_game() request = self.factory.post('api/games/', base_game_input, content_type='application/json') response = api_games(request) request = self.factory.delete('api/games/1/') response = api_games_id(request, '1') self.assertEqual( len(Images.objects.filter(other_id=1, other_type='GM')), 0) self.assertEqual( len(Images.objects.filter(other_id=1, other_type='GM')), 0) self.assertEqual(len(Game.objects.filter(pk=1)), 0) self.assertEqual(response.status_code, 204) def test_DELETE_game_with_bad_id(self): request = self.factory.delete('api/games/1/') response = api_companies_id(request, '1') self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_GET_intersection_games_people(self): setup_db_for_game() new_game = Game(**base_game) new_game.save() new_game.genre.add(1) new_game.people.add(1) request = self.factory.get('api/games/1/people/') response = api_games_people(request, 1) response_content = response.content.decode('utf-8') db_query = serializers.serialize("json", Game.objects.get(pk=1).people.all(), fields=("name")) self.assertEqual(response.status_code, 200) self.assertEqual(response_content, db_query) def test_GET_intersection_games_people_with_bad_id(self): request = self.factory.get('api/games/1/people/') response = api_games_people(request, '1') self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_GET_intersection_games_companies(self): setup_db_for_game() new_game = Game(**base_game) new_game.save() new_game.genre.add(1) new_game.people.add(1) request = self.factory.get('api/games/1/companies/') response = api_games_companies(request, 1) response_content = response.content.decode('utf-8') db_query = serializers.serialize("json", [Game.objects.get(pk=1).company], fields=("name")) self.assertEqual(response.status_code, 200) self.assertEqual(response_content, db_query) def test_GET_intersection_games_companies_with_bad_id(self): request = self.factory.get('api/games/1/companies/') response = api_games_people(request, '1') self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'')
class FilesViewTest(TestCase): def setUp(self): self.factory = RequestFactory() self.user = create_user() # The various files views are a little tricky to invoke. We would # like to just use self.client.get() but we can't because we need # to install a custom HTTP_X_AUTH_TOKEN header. So, instead we use # RequestFactory to assemble the request and then we pass that # request directly into the account() view function. # # Here are some helper functions to make that more convenient def account_view_get(self, use_invalid_token=False, query=''): url = reverse('account', kwargs={'account_id': self.user.account.id}) url += query request = self.factory.get(url) if (use_invalid_token): request.META['HTTP_X_AUTH_TOKEN'] = 'bogus' else: request.META['HTTP_X_AUTH_TOKEN'] = self.user.token return account(request, self.user.account.id) def container_view_put(self, container_name): url = reverse('container', kwargs={'account_id': self.user.account.id, 'container_name': container_name}) request = self.factory.put(url) request.META['HTTP_X_AUTH_TOKEN'] = self.user.token return container(request, self.user.account.id, container_name) def container_view_get(self, container_name, use_invalid_token=False): request = self.factory.get( reverse('container', kwargs={'account_id': self.user.account.id, 'container_name': container_name})) if (use_invalid_token): request.META['HTTP_X_AUTH_TOKEN'] = 'bogus' else: request.META['HTTP_X_AUTH_TOKEN'] = self.user.token return container(request, self.user.account.id, container_name) def file_view_put(self, container_name, path): url = reverse('file', kwargs={'account_id': self.user.account.id, 'container_name': container_name, 'path': path}) request = self.factory.put(url) request.META['HTTP_X_AUTH_TOKEN'] = self.user.token return container(request, self.user.account.id, container_name, path) def file_view_delete(self, container_name, path): url = reverse('file', kwargs={'account_id': self.user.account.id, 'container_name': container_name, 'path': path}) request = self.factory.delete(url) request.META['HTTP_X_AUTH_TOKEN'] = self.user.token return container(request, self.user.account.id, container_name, path) def file_view_get(self, container_name, path='', query=''): url = reverse('file', kwargs={'account_id': self.user.account.id, 'container_name': container_name, 'path': path}) url += query request = self.factory.get(url) request.META['HTTP_X_AUTH_TOKEN'] = self.user.token return container(request, self.user.account.id, container_name, path) def test_account_authorized(self): """Verify that the account view requires a valid token.""" # First attempt to connect with an invalid token. This should fail. response = self.account_view_get(use_invalid_token=True) self.assertEquals(response.status_code, 401) # Then, try again with the correct token, which should work response = self.account_view_get() self.assertEquals(response.status_code, 200) self.assertJSONEqual(response.content, "[]") def test_account_ordered(self): """Ensure that containers are listed in alphabetical order.""" acc = self.user.account SlowishContainer.objects.create(account=acc, name='foo') SlowishContainer.objects.create(account=acc, name='bar') SlowishContainer.objects.create(account=acc, name='baz') response = self.account_view_get() self.assertJSONEqual( response.content, '[{"count": 0, "bytes": 0, "name": "bar"},' '{"count": 0, "bytes": 0, "name": "baz"},' '{"count": 0, "bytes": 0, "name": "foo"}]') def test_account_range(self): """Test marker and end_marker parameters when listing containers.""" account = self.user.account names = ['this', 'is', 'a', 'collection', 'of', 'container', 'names', 'in', 'no', 'particular', 'order'] for name in names: SlowishContainer.objects.create(account=account, name=name) response = self.account_view_get(query="?marker=order") self.assertJSONEqual( response.content, '[{"count": 0, "bytes": 0, "name": "particular"},' '{"count": 0, "bytes": 0, "name": "this"}]') response = self.account_view_get(query="?end_marker=container") self.assertJSONEqual( response.content, '[{"count": 0, "bytes": 0, "name": "a"},' '{"count": 0, "bytes": 0, "name": "collection"}]') response = self.account_view_get( query="?marker=container&end_marker=names") self.assertJSONEqual( response.content, '[{"count": 0, "bytes": 0, "name": "in"},' '{"count": 0, "bytes": 0, "name": "is"}]') def test_account_content(self): """Verify the json response content from the account view.""" # With no containers, we expect an empty list response = self.account_view_get() self.assertJSONEqual(response.content, "[]") def test_container_authorized(self): """Verify that the container view requires a valid token.""" SlowishContainer.objects.create( account=self.user.account, name='test') # First attempt to connect with an invalid token. This should fail. response = self.container_view_get('test', use_invalid_token=True) self.assertEquals(response.status_code, 401) # Then, try again with the correct token, which should work response = self.container_view_get('test') self.assertEquals(response.status_code, 200) def test_container_create(self): """Verify we can create a new container.""" # Prior to creation, there shold be an empty list of containers response = self.account_view_get() self.assertJSONEqual(response.content, "[]") # Issue a PUT request to create a new container (returns a # status of 201==Created) response = self.container_view_put('new_container') self.assertEquals(response.status_code, 201) # Trying to create again is fine and gives a 200==OK status response = self.container_view_put('new_container') self.assertEquals(response.status_code, 200) # Verify that the newly created container now appears in the # list of containers response = self.account_view_get() self.assertJSONEqual( response.content, '[{"count": 0, "bytes": 0, "name": "new_container"}]') # Test the __unicode__ method within SlowishContainer container = SlowishContainer.objects.get(name="new_container") self.assertEquals(str(container), "new_container (in account 1234)") def test_file_create(self): """Verify we can create a file within a container.""" # Create a container self.container_view_put('container') # Create a file within that container (returns status of # 201==Created) response = self.file_view_put('container', 'path/to/file') self.assertEquals(response.status_code, 201) # Trying to create again is fine and gives a 200=OK status response = self.file_view_put('container', 'path/to/file') self.assertEquals(response.status_code, 200) # Test the __unicode__ method within SlowishFile file = SlowishFile.objects.get(path="path/to/file") self.assertEquals( str(file), "path/to/file (in container container (in account 1234))") # Create a couple of more files self.file_view_put("container", "another/file") self.file_view_put("container", "and/yet/one/more") # Query list of files in container response = self.file_view_get("container") self.assertEquals(response.status_code, 200) self.assertJSONEqual( response.content, '[{"bytes": 0, "content_type": "application/directory",' '"name": "and/yet/one/more"},' '{"bytes": 0, "content_type": "application/directory",' '"name": "another/file"},' '{"bytes": 0, "content_type": "application/directory",' '"name": "path/to/file"}]') def test_files_range(self): """Verify marker and end_marker parameters for file list.""" container = SlowishContainer.objects.create( account=self.user.account, name="blob") names = ['this', 'is', 'a', 'collection', 'of', 'file', 'names', 'in', 'no', 'particular', 'order'] for name in names: SlowishFile.objects.create( container=container, path=name) response = self.file_view_get("blob", query="?marker=order") self.assertJSONEqual( response.content, '[{"bytes": 0, "content_type": "application/directory",' '"name": "particular"},' '{"bytes": 0, "content_type": "application/directory",' '"name": "this"}]') response = self.file_view_get("blob", query="?end_marker=file") self.assertJSONEqual( response.content, '[{"bytes": 0, "content_type": "application/directory",' '"name": "a"},' '{"bytes": 0, "content_type": "application/directory",' '"name": "collection"}]') response = self.file_view_get( "blob", query="?marker=file&end_marker=names") self.assertJSONEqual( response.content, '[{"bytes": 0, "content_type": "application/directory",' '"name": "in"},' '{"bytes": 0, "content_type": "application/directory",' '"name": "is"}]') def test_files_prefix(self): """Verify query of files matching a prefix.""" # Create several files in a container self.container_view_put("containter") self.file_view_put("container", "this/file/is/your/file") self.file_view_put("container", "this/file/is/my/file") self.file_view_put("container", "from/california") self.file_view_put("container", "to/the/new/york/island") self.file_view_put("container", "this/file/is/made/for/you/and/me") # List only those files matching a prefix response = self.file_view_get("container", query="?prefix=this/file") self.assertJSONEqual( response.content, '[{"bytes": 0, "content_type": "application/directory",' '"name": "this/file/is/made/for/you/and/me"},' '{"bytes": 0, "content_type": "application/directory",' '"name": "this/file/is/my/file"},' '{"bytes": 0, "content_type": "application/directory",' '"name": "this/file/is/your/file"}]') # We don't yet support getting file contents, but we can at least # ask about directory objects that we have stored as files within # a container. def test_directory_get(self): """Verify that a specific file in a container can be queried.""" self.container_view_put('container') self.file_view_put('container', 'path/to/file') # Verify file query returns successful status response = self.file_view_get("container", "path/to/file") self.assertEquals(response.status_code, 200) # And a non-existent file should fail response = self.file_view_get("container", "does/not/exist") self.assertEquals(response.status_code, 404) def test_file_delete(self): """Verify we can delete a file from a container.""" # Create some files in a container self.container_view_put("crew") self.file_view_put("crew", "one_shirt") self.file_view_put("crew", "two_shirt") self.file_view_put("crew", "red_shirt") self.file_view_put("crew", "blue_shirt") # Verify presence of added files response = self.file_view_get("crew", "red_shirt") self.assertEquals(response.status_code, 200) response = self.file_view_get("crew", "blue_shirt") self.assertEquals(response.status_code, 200) # Delete a file (I know you saw this coming) response = self.file_view_delete("crew", "red_shirt") self.assertEquals(response.status_code, 204) # Verify deletion only of the single file response = self.file_view_get("crew", "red_shirt") self.assertEquals(response.status_code, 404) response = self.file_view_get("crew", "blue_shirt") self.assertEquals(response.status_code, 200) # Attempt to delete again should fail response = self.file_view_delete("crew", "red_shirt") self.assertEquals(response.status_code, 404) def test_container_does_not_exist(self): """Verify a 404 status for a non-existent container.""" with self.assertRaises(Http404): self.container_view_get('does_not_exist')
class NotificationViewDeviceTokenReceiveTest(TestCase): def setUp(self): self.factory = RequestFactory() self.device_token = '8a0d7cba3ffad34bd3dcb37728080a95d6ee78a83a68ead033614acbab9b7e76' self.uuid = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' def tearDown(self): DeviceToken.objects.all().delete() def test_device_token_receive_with_all_parameter(self): parameter = { 'device_token': self.device_token, 'uuid': self.uuid, 'sandbox': True } request = self.factory.put('/receive/', json.dumps(parameter)) request.content_type = 'application/json' response = device_token_receive(request) self.assertEqual(response.status_code, 200) self.assertEqual(json.loads(response.content.decode('utf-8')), {'result': 'success'}) def test_device_token_receive_with_only_device_token(self): parameter = {'device_token': self.device_token} request = self.factory.put('/receive/', json.dumps(parameter)) request.content_type = 'application/json' response = device_token_receive(request) self.assertEqual(response.status_code, 400) self.assertEqual(json.loads(response.content.decode('utf-8')), {'error': 'Bad Request'}) def test_device_token_receive_with_only_uuid(self): parameter = {'uuid': self.uuid} request = self.factory.put('/receive/', json.dumps(parameter)) request.content_type = 'application/json' response = device_token_receive(request) self.assertEqual(response.status_code, 400) self.assertEqual(json.loads(response.content.decode('utf-8')), {'error': 'Bad Request'}) def test_device_token_receive_with_only_sandbox(self): parameter = {'sandbox': True} request = self.factory.put('/receive/', json.dumps(parameter)) request.content_type = 'application/json' response = device_token_receive(request) self.assertEqual(response.status_code, 400) self.assertEqual(json.loads(response.content.decode('utf-8')), {'error': 'Bad Request'}) def test_device_token_receive_without_parameter(self): request = self.factory.put('/receive/') response = device_token_receive(request) self.assertEqual(response.status_code, 400) self.assertEqual(json.loads(response.content.decode('utf-8')), {'error': 'Bad Request'}) def test_device_token_receive_with_twice(self): device_token = DeviceToken() device_token.device_token = '8a0d7cba3ffad34bd3dcb37728080a95d6ee78a83a68ead033614acbab9b7e76' device_token.uuid = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' device_token.save() parameter = { 'device_token': 'ec203ae05072eaa39474fd4bd06c3b36344602295078615cef67fcbdb7e94aef', 'uuid': 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', 'sandbox': True } request = self.factory.put('/receive/', json.dumps(parameter)) request.content_type = 'application/json' response = device_token_receive(request) self.assertEqual(response.status_code, 200) get_device_token = DeviceToken.objects.get( uuid='XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX') self.assertNotEqual(device_token.device_token, get_device_token.device_token) self.assertEqual( get_device_token.device_token, 'ec203ae05072eaa39474fd4bd06c3b36344602295078615cef67fcbdb7e94aef') self.assertEqual(get_device_token.uuid, 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX') def test_device_token_receive_method_get(self): request = self.factory.get('/receive/') response = device_token_receive(request) self.assertEqual(response.status_code, 405) def test_device_token_receive_method_post(self): request = self.factory.post('/receive/') response = device_token_receive(request) self.assertEqual(response.status_code, 405) def test_device_token_receive_method_delete(self): request = self.factory.delete('/receive/') response = device_token_receive(request) self.assertEqual(response.status_code, 405)
class TestRatingResource(BaseSegmentsTest): """Tests on RatingResource""" def setUp(self): super(TestRatingResource, self).setUp() self.req = RequestFactory() def test_parsers(self): from project.resources import RatingInstanceView, RatingJSONParser from djangorestframework.parsers import JSONParser from StringIO import StringIO self.assertEqual(len(RatingInstanceView.parsers), 4) self.assertNotIn(JSONParser, RatingInstanceView.parsers) self.assertIn(RatingJSONParser, RatingInstanceView.parsers) parser = RatingJSONParser(None) # None for the view json_string = StringIO( '{"criterion":3,"question":"How much do you like it?","score":"4","segment":456,"block_index":5239,"url":"http://localhost:8000/ratings/13","id":13}' ) self.assertNotIn(u'id', parser.parse(json_string)) def test_read(self): from project.models import Rating, Criterion, Segment criterion = Criterion.objects.create(prompt='Hello?') segment = Segment.objects.create(id=123) rating = Rating.objects.create(criterion=criterion, segment1=segment, block1_index=2, segment2=segment, block2_index=2, score=5) from project.resources import RatingInstanceView request = self.req.get('/ratings/{}'.format(rating.id)) view = RatingInstanceView() response = view.get(request, rating.id) self.assertEquals(rating, response) def test_delete(self): from project.models import Rating, Criterion, Segment criterion = Criterion.objects.create(prompt='Hello?') segment = Segment.objects.create(id=123) Rating.objects.all().delete() rating = Rating.objects.create(criterion=criterion, segment1=segment, block1_index=2, segment2=segment, block2_index=2, score=5) from project.resources import RatingInstanceView request = self.req.delete('/ratings/{}'.format(rating.id)) view = RatingInstanceView() response = view.delete(request, rating.id) assert_equal(Rating.objects.count(), 0) def test_update(self): from project.models import Rating, Criterion, Segment criterion1 = Criterion.objects.create(prompt='Hello?') criterion2 = Criterion.objects.create(prompt='Goodbye!') segment1 = Segment.objects.create(id=123) segment2 = Segment.objects.create(id=456) rating = Rating.objects.create(criterion=criterion1, segment1=segment1, block1_index=2, segment2=segment1, block2_index=2, score=5) from project.resources import RatingInstanceView request = self.req.put('/ratings/{}'.format(rating.id), data={ 'segment2': segment2.id, 'block2_index': 14, 'segment1': segment2.id, 'block1_index': 14, 'criterion': criterion2.id, 'score': 2 }) view = RatingInstanceView() view.request = request response = view.put(request, rating.id) self.assertEquals(rating, response) self.assertEqual(response.criterion, criterion2) self.assertEqual(response.segment2, segment2) self.assertEqual(response.block2_index, 14) self.assertEqual(response.score, 2) def test_create(self): from project.models import Rating, Criterion, Segment criterion = Criterion.objects.create(prompt='Hello?') segment1 = Segment.objects.create(id=123) segment2 = Segment.objects.create(id=456) Rating.objects.all().delete() from project.resources import RatingListView request = self.req.post('/ratings/', data={ 'segment1': segment1.id, 'block1_index': 7, 'segment2': segment2.id, 'block2_index': 14, 'criterion': criterion.id, 'score': 2 }) view = RatingListView() view.request = request response = view.post(request) self.assertEquals(Rating.objects.count(), 1) self.assertEqual(response.cleaned_content.criterion, criterion) self.assertEqual(response.cleaned_content.segment1, segment1) self.assertEqual(response.cleaned_content.block1_index, 7) self.assertEqual(response.cleaned_content.score, 2)
class ResourceEntryTestCase(TestCase): tags = ('offering-api', ) def setUp(self): # Create request factory self.factory = RequestFactory() # Create testing user self.user = User.objects.create_user(username='******', email='', password='******') self.user.userprofile.get_current_roles = MagicMock( name='get_current_roles') self.user.userprofile.get_current_roles.return_value = [ 'provider', 'customer' ] self.user.userprofile.save() # Create resource model mock self.resource = MagicMock() self.resource.provider = self.user.userprofile.current_organization views.OfferingResource = MagicMock() views.OfferingResource.objects.get.return_value = self.resource @classmethod def tearDownClass(cls): from wstore.offerings import offerings_management reload(offerings_management) reload(views) super(ResourceEntryTestCase, cls).tearDownClass() def tearDown(self): views.json = json def _not_found(self): views.OfferingResource.objects.get.side_effect = Exception('Not found') def _no_provider(self): self.user.userprofile.get_current_roles.return_value = ['customer'] def _exception_update(self): views.update_resource.side_effect = Exception('Exception in call') def _exception_upgrade(self): views.upgrade_resource.side_effect = Exception('Exception in call') def _exception_delete(self): views.delete_resource.side_effect = Exception('Exception in call') def _invalid_json(self): views.json = MagicMock() views.json.loads.side_effect = Exception('Invalid content') @parameterized.expand([ (RESOURCE_DATA, 200, 'OK'), (RESOURCE_DATA, 400, 'Invalid content', _invalid_json, 'error'), (RESOURCE_DATA, 403, 'Forbidden', _no_provider, 'error'), (RESOURCE_DATA, 400, 'Exception in call', _exception_update, 'error') ]) def test_resource_update_api(self, data, code, msg, side_effect=None, status='correct'): views.update_resource = MagicMock(name='update_resource') if side_effect: side_effect(self) request = self.factory.put( '/api/offering/resources/test_user/test_resource/1.0', json.dumps(data), content_type='application/json', HTTP_ACCEPT='application/json') request.user = self.user res_entry = views.ResourceEntry(permitted_methods=('PUT', 'POST', 'DELETE')) response = res_entry.update(request, 'test_user', 'test_resource', '1.0') self.assertEqual(response.status_code, code) self.assertEqual(response.get('Content-type'), 'application/json; charset=utf-8') body_response = json.loads(response.content) self.assertEquals(type(body_response), dict) self.assertEquals(body_response['message'], msg) self.assertEquals(body_response['result'], status) # Check call to update method if needed if status != 'error': views.update_resource.assert_called_once_with( self.resource, self.user, data) @parameterized.expand([ (RESOURCE_DATA, 200, 'OK'), (RESOURCE_DATA, 200, 'OK', True), (RESOURCE_DATA, 400, 'Invalid content', False, _invalid_json, True), (RESOURCE_DATA, 400, 'Invalid content', True, _invalid_json, True), (RESOURCE_DATA, 404, 'Resource not found', False, _not_found, True), (RESOURCE_DATA, 403, 'Forbidden', False, _no_provider, True), (RESOURCE_DATA, 400, 'Exception in call', False, _exception_upgrade, True) ]) def test_resource_upgrade_api(self, data, code, msg, file_=False, side_effect=None, error=False): # Mock update method views.upgrade_resource = MagicMock(name='upgrade_resource') if side_effect: side_effect(self) content = json.dumps(data) content_type = 'application/json' if file_: f = StringIO() f.name = 'test_file.txt' f.write('test file') content = {'json': json.dumps(data), 'file': f} content_type = MULTIPART_CONTENT request = self.factory.post( '/api/offering/resources/test_user/test_resource/1.0', content, content_type=content_type, HTTP_ACCEPT='application/json') request.user = self.user res_entry = views.ResourceEntry(permitted_methods=('PUT', 'POST', 'DELETE')) response = res_entry.create(request, 'test_user', 'test_resource', '1.0') self.assertEqual(response.status_code, code) self.assertEqual(response.get('Content-type'), 'application/json; charset=utf-8') body_response = json.loads(response.content) self.assertEqual(type(body_response), dict) self.assertEqual(body_response['message'], msg) if not error: if not file_: views.upgrade_resource.assert_called_once_with( self.resource, self.user, data) else: expected_file = request.FILES[ 'file'] # The type change when loaded views.upgrade_resource.assert_called_once_with( self.resource, self.user, data, expected_file) self.assertEqual(body_response['result'], 'correct') else: self.assertEqual(body_response['result'], 'error') @parameterized.expand([(204, 'No Content'), (404, 'Resource not found', _not_found, True), (403, 'Forbidden', _no_provider, True), (400, 'Exception in call', _exception_delete, True)] ) def test_resource_deletion_api(self, code, msg, side_effect=None, error=False): # Mock delete resource method views.delete_resource = MagicMock(name='delete_resource') if side_effect: side_effect(self) request = self.factory.delete( '/api/offering/resources/test_user/test_resource/1.0', HTTP_ACCEPT='application/json') request.user = self.user res_entry = views.ResourceEntry(permitted_methods=('POST', 'DELETE')) response = res_entry.delete(request, 'test_user', 'test_resource', '1.0') self.assertEqual(response.status_code, code) self.assertEqual(response.get('Content-type'), 'application/json; charset=utf-8') body_response = json.loads(response.content) self.assertEqual(type(body_response), dict) self.assertEqual(body_response['message'], msg) if not error: views.delete_resource.assert_called_once_with( self.resource, self.user) self.assertEqual(body_response['result'], 'correct') else: self.assertEqual(body_response['result'], 'error')
class TestCompany(TestCase): def setUp(self): self.factory = RequestFactory() def test_POST_company(self): request = self.factory.post('api/companies/', base_company_input, content_type='application/json') response = api_companies(request) response_content = literal_eval(response.content.decode('utf-8')) db_query = literal_eval( serializers.serialize("json", [Company.objects.get(pk=1)])) self.assertEqual(response.status_code, 201) self.assertEqual(response_content, id_1) self.assertEqual(db_query[0]["fields"], base_company) def test_POST_company_with_no_image_key(self): request = self.factory.post('api/companies/', base_company, content_type='application/json') response = api_companies(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_company_with_empty_image(self): company_data = base_company_input.copy() company_data["images"] = [] request = self.factory.post('api/companies/', company_data, content_type='application/json') response = api_companies(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_company_with_no_name(self): company_data = base_company_input.copy() company_data.pop("name") request = self.factory.post('api/companies/', company_data, content_type='application/json') response = api_companies(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_POST_company_with_empty_name(self): company_data = base_company_input.copy() company_data["name"] = " " request = self.factory.post('api/companies/', company_data, content_type='application/json') response = api_companies(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_GET_all_companies(self): new_company = Company(**base_company).save() new_company = Company(**base_company).save() request = self.factory.get('api/companies/') response = api_companies(request) response_content = literal_eval(response.content.decode('utf-8')) db_query = literal_eval( serializers.serialize("json", Company.objects.all(), fields=("name"))) db_query[0]["fields"]["images"] = [] db_query[1]["fields"]["images"] = [] self.assertEqual(response.status_code, 200) self.assertEqual(db_query, response_content) def test_PUT_company(self): request = self.factory.post('api/companies/', base_company_input, content_type='application/json') response = api_companies(request) request = self.factory.put('api/companies/1/', updated_company_input, content_type='application/json') response = api_companies_id(request, '1') response_content = response.content.decode('utf-8') company_object = Company.objects.get(pk=1) db_query = literal_eval(serializers.serialize("json", [company_object])) self.assertEqual(response.status_code, 204) self.assertEqual(db_query[0]["fields"], updated_company) self.assertEqual(company_object.images()[0].link, updated_company_input["images"][0]) def test_PUT_company_with_bad_id(self): request = self.factory.put('api/companies/1/', updated_company_input, content_type='application/json') response = api_companies_id(request, '1') self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_PUT_company_with_no_image_key(self): request = self.factory.post('api/companies/', base_company_input, content_type='application/json') response = api_companies(request) request = self.factory.put('api/companies/1/', updated_company, content_type='application/json') response = api_companies_id(request, '1') self.assertEqual(response.status_code, 204) self.assertEqual(response.content, b'') def test_PUT_company_with_empty_image(self): request = self.factory.post('api/companies/', base_company_input, content_type='application/json') response = api_companies(request) company_data = base_company_input.copy() company_data["images"] = [] request = self.factory.put('api/companies/1/', company_data, content_type='application/json') response = api_companies_id(request, '1') self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_PUT_company_with_empty_name(self): request = self.factory.post('api/companies/', base_company_input, content_type='application/json') response = api_companies(request) company_data = base_company_input.copy() company_data["name"] = " " request = self.factory.put('api/companies/1/', company_data, content_type='application/json') response = api_companies_id(request, '1') self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b'') def test_GET_company(self): request = self.factory.post('api/companies/', base_company_input, content_type='application/json') response = api_companies(request) request = self.factory.get('api/companies/1/') response = api_companies_id(request, '1') company_object = Company.objects.get(pk=1) db_query = literal_eval(serializers.serialize("json", [company_object])) response_content = literal_eval(response.content.decode('utf-8')) image_link = response_content[0]["fields"].pop("images") self.assertEqual(response.status_code, 200) self.assertEqual(db_query, response_content) self.assertEqual(company_object.images()[0].link, image_link[0]) def test_GET_with_bad_id(self): request = self.factory.get('api/companies/1/') response = api_companies_id(request, '1') self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_DELETE_company(self): request = self.factory.post('api/companies/', base_company_input, content_type='application/json') response = api_companies(request) request = self.factory.delete('api/companies/1/') response = api_companies_id(request, '1') self.assertEqual( len(Images.objects.filter(other_id=1, other_type='CP')), 0) self.assertEqual(len(Company.objects.filter(pk=1)), 0) self.assertEqual(response.status_code, 204) def test_DELETE_with_bad_id(self): request = self.factory.delete('api/companies/1/') response = api_companies_id(request, '1') self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_GET_intersection_company_games(self): new_company = Company(**base_company).save() new_person = Person(**base_person) new_person.save() new_person.companies.add(1) System(**base_system).save() Genre(**base_genre).save() new_game = Game(**base_game) new_game.save() new_game.genre.add(1) new_game.people.add(1) request = self.factory.get('api/companies/1/games/') response = api_companies_games(request, 1) response_content = response.content.decode('utf-8') db_query = serializers.serialize("json", Game.objects.filter(company=1), fields=("name")) self.assertEqual(response.status_code, 200) self.assertEqual(response_content, db_query) def test_GET_intersection_company_games_with_bad_id(self): request = self.factory.get('api/companies/1/games/') response = api_companies_games(request, '1') self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'') def test_GET_intersection_company_people(self): new_company = Company(**base_company).save() new_person = Person(**base_person) new_person.save() new_person.companies.add(1) request = self.factory.get('api/companies/1/people/') response = api_companies_people(request, 1) response_content = response.content.decode('utf-8') db_query = serializers.serialize("json", Person.objects.filter(companies=1), fields=("name")) self.assertEqual(response.status_code, 200) self.assertEqual(response_content, db_query) def test_GET_intersection_company_people_with_bad_id(self): request = self.factory.get('api/companies/1/people/') response = api_companies_people(request, '1') self.assertEqual(response.status_code, 404) self.assertEqual(response.content, b'')
class TestBulkAPIMixins(TestCase): lang1 = {"id": "en-us", "lang_code": "en", "lang_subcode": "us"} lang2 = {"id": "fr-fr", "lang_code": "fr", "lang_subcode": "fr"} def setUp(self): super(TestBulkAPIMixins, self).setUp() self.request = RequestFactory() def test_get(self): """ Test that GET request is successful on bulk create view. """ view = BulkCreateView.as_view({"get": "list"}) response = view(self.request.get("")) self.assertEqual(response.status_code, status.HTTP_200_OK) def test_post_single(self): """ Test that POST request with single resource only creates a single resource. """ view = BulkCreateView.as_view({"post": "create"}) response = view( self.request.post("", json.dumps(self.lang1), content_type="application/json")) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Language.objects.count(), 1) self.assertEqual(Language.objects.get().id, self.lang1["id"]) def test_post_bulk(self): """ Test that POST request with multiple resources creates all posted resources. """ view = BulkCreateView.as_view({"post": "create"}) response = view( self.request.post( "", json.dumps([self.lang1, self.lang2]), content_type="application/json", )) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Language.objects.count(), 2) self.assertEqual( list(Language.objects.all().values_list("id", flat=True)), [self.lang1["id"], self.lang2["id"]], ) def test_delete_not_filtered(self): """ Test that DELETE is not allowed when results are not filtered. """ view = BulkDeleteView.as_view({"delete": "bulk_destroy"}) Language.objects.create(**self.lang1) Language.objects.create(**self.lang2) response = view(self.request.delete("")) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_delete_filtered(self): """ Test that DELETE removes all filtered resources. """ view = BulkDeleteView.as_view({"delete": "bulk_destroy"}) Language.objects.create(**self.lang1) Language.objects.create(**self.lang2) response = view(self.request.delete("?id=" + self.lang1["id"])) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(Language.objects.count(), 1) self.assertEqual(Language.objects.get().id, self.lang2["id"])
class BorrowTransactionApiTestCase(TestCase): def setUp(self): # Set up a Request Factory self.factory = RequestFactory() # Make some basic objects to play with. self.parrot = User.create_new_user("Parrot", "password", "03545", "*****@*****.**", "1234567890", "Pining for the fjords.") self.penguin = User.create_new_user('Penguin', 'password', '03545', '*****@*****.**', '5555551234', 'It\'s on the telly.') self.polarbear = User.create_new_user('Polarbear', 'password', '00000', '*****@*****.**', '5555551234', 'Pick it up at the north pole') self.nail = Tool.create_new_tool( "Rusty Nail", toolownerID=self.parrot.id, tooldescription="Holding up a stuffed parrot", tooltype="nail", toolshed=False, pickup_info="Rip it out of the cage.", tool_available=True) self.zilly = Tool.create_new_tool( "Warhammer of Zillyhoo", toolownerID=self.parrot.id, tooldescription="Its majesty makes you weep.", tooltype="hammer", toolshed=False, pickup_info="Some time travel required.", tool_available=True) self.scraper = Tool.create_new_tool( "Ice Scraper", toolownerID=self.penguin.id, tooldescription="An ice scraper for your car", tooltype="ice scraper", toolshed=False, pickup_info="Pick it up at the south pole.", tool_available=True) #cutting this out in case we lose points for that dumb runtime warning @unittest.skip def test_requestBorrowTransaction(self): # Penguin borrows nail from parrot jsondata = { 'toolId': self.nail.id, 'borrower_message': "i need dis", # NOTE: Python throws a nasty runtime error here because it # can't tell whether the milliseconds are timezone-aware. # Nothing I can do about this, just ignore the warning. 'date': dt_to_milliseconds(timezone.datetime( year=3000, month=4, day=13, )), } request = self.factory.post( path='/api/borrowTransaction', data=json.dumps(jsondata), content_type="application/json", ) request.session = {'user': {'id': self.penguin.id}} response = api.borrowTransaction(request) #print(response.content) self.assertEqual(response.status_code, 200) """ @unittest.skip # this is not actually required behavior def test_requestBorrowTransaction_differentzones(self): # Polar bear borrows ice scraper from penguin # note that polar bears and penguins do not live in the same # place jsondata = { 'toolId' : self.scraper.id, 'borrower_message' : "i need dis", 'date' : dt_to_milliseconds(timezone.datetime( tzinfo = timezone.UTC, year = 3000, month = 4, day = 13, )), } request = self.factory.post( path = '/api/borrowTransaction', data = json.dumps(jsondata), content_type = "application/json", ) request.session = { 'user' : { 'id' : self.polarbear.id } } response = api.borrowTransaction(request) #print(response.content) self.assertNotEqual(response.status_code, 200) """ @unittest.skip #not ready yet def test_getUnresolvedBorrowTransactions(self): request = self.factory.get( path='/api/borrowTransaction/requestPending') @unittest.skip #not ready yet def test_resolveBorrowRequest(self): request = self.factory.post('/api/borrowTransaction/resolve') @unittest.skip #not ready yet def test_getRejectedRequests(self): request = self.factory.get(path='/api/borrowTransaction/rejected/:id') @unittest.skip #not ready yet def test_requestEndBorrowTransaction(self): request = self.factory.put('/api/borrowTransaction') @unittest.skip #not ready yet def test_getEndBorrowTransactionRequests(self): request = self.factory.get(path='/api/borrowTransaction/endRequests') @unittest.skip #not ready yet def test_resolveEndBorrowTransaction(self): request = self.factory.delete( path='/api/borrowTransaction/:transactionId') @unittest.skip #not ready yet def test_getToolsUserIsBorrowing(self): request = self.factory.put( path='/api/borrowTransaction/borrowing/:userId') @unittest.skip #not ready yet def test_getToolsUserIsLending(self): request = self.factory.get( path='/api/borrowTransaction/borrowed/:userId') @unittest.skip #not ready yet def test_getAllCommunityHistory(self): request = self.factory.get( path='/api/borrowTransaction/community/:zip') @unittest.skip #not ready yet def test_getAllReturnPendingBorrowTransactionsInCommunityShed(self): request = self.factory.get( path='/api/borrowTransaction/pendingCommunity')
class DRYRestPermissionsTests(TestCase): def setUp(self): self.action_set = ['retrieve', 'list', 'create', 'destroy', 'update', 'partial_update', 'custom_action1', 'custom_action2'] self.factory = RequestFactory() self.request_retrieve = Request(self.factory.get('/dummy/1')) self.request_list = Request(self.factory.get('/dummy')) self.request_create = Request(self.factory.post('/dummy'), {}) self.request_destroy = Request(self.factory.delete('/dummy/1')) self.request_update = Request(self.factory.put('/dummy/1', {})) self.request_partial_update = Request(self.factory.patch('/dummy/1', {})) self.request_custom_action1 = Request(self.factory.get('/dummy/custom_action1')) self.request_custom_action2 = Request(self.factory.post('/dummy/custom_action2', {})) def _run_permission_checks(self, view, obj, assert_value): for action in self.action_set: view.action = action request_name = "request_{action}".format(action=action) result = view.dummy_check_permission(getattr(self, request_name), obj) self.assertEqual(result, assert_value) def _run_dry_permission_field_checks(self, view, obj, assert_specific, assert_base): serializer = view.get_serializer_class()() # dummy request serializer.context['request'] = self.request_retrieve representation = serializer.to_representation(obj) for action in [action for action in self.action_set if action not in ['partial_update', 'list']]: has_permission = representation['permissions'].get(action, None) self.assertEqual(has_permission, assert_specific, "Action '%s' %s != %s" % (action, has_permission, assert_specific)) for action in ['read', 'write']: has_permission = representation['permissions'].get(action, None) self.assertEqual(has_permission, assert_base, "Action '%s' %s != %s" % (action, has_permission, assert_base)) def test_true_base_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin): pass class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), True) self._run_dry_permission_field_checks(view, TestModel(), None, True) def test_false_base_object_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin): base_object_allowed = False class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), False) self._run_dry_permission_field_checks(view, TestModel(), None, False) def test_false_base_global_permissions(self): class TestModel(DummyModel, BaseObjectMixin, BaseGlobalMixin): base_global_allowed = False class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), False) self._run_dry_permission_field_checks(view, TestModel(), None, False) def test_true_specific_permissions(self): class TestModel( DummyModel, BaseObjectMixin, BaseGlobalMixin, SpecificObjectMixin, SpecificGlobalMixin): base_global_allowed = False base_object_allowed = False class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), True) self._run_dry_permission_field_checks(view, TestModel(), True, False) def test_true_base_not_defined_permissions(self): class TestModel(DummyModel, SpecificObjectMixin, SpecificGlobalMixin): pass class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), True) self._run_dry_permission_field_checks(view, TestModel(), True, None) def test_false_specific_object_permissions(self): class TestModel( DummyModel, BaseObjectMixin, BaseGlobalMixin, SpecificObjectMixin, SpecificGlobalMixin): specific_object_allowed = False class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), False) self._run_dry_permission_field_checks(view, TestModel(), False, True) def test_false_specific_global_permissions(self): class TestModel( DummyModel, BaseObjectMixin, BaseGlobalMixin, SpecificObjectMixin, SpecificGlobalMixin): specific_global_allowed = False class TestSerializer(DummySerializer): class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer view = TestViewSet() self._run_permission_checks(view, TestModel(), False) self._run_dry_permission_field_checks(view, TestModel(), False, True) def test_true_no_global_permissions(self): class TestModel( DummyModel, BaseObjectMixin, BaseGlobalMixin, SpecificObjectMixin, SpecificGlobalMixin): base_global_allowed = False specific_global_allowed = False class TestSerializer(DummySerializer): permissions = DRYPermissionsField(object_only=True, additional_actions=['custom_action1', 'custom_action2']) class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer permission_classes = (DRYObjectPermissions, ) view = TestViewSet() self._run_permission_checks(view, TestModel(), True) self._run_dry_permission_field_checks(view, TestModel(), True, True) def test_true_no_object_permissions(self): class TestModel( DummyModel, BaseObjectMixin, BaseGlobalMixin, SpecificObjectMixin, SpecificGlobalMixin): base_object_allowed = False specific_object_allowed = False class TestSerializer(DummySerializer): permissions = DRYPermissionsField(global_only=True, additional_actions=['custom_action1', 'custom_action2']) class Meta: model = TestModel class TestViewSet(DummyViewSet): serializer_class = TestSerializer permission_classes = (DRYGlobalPermissions, ) view = TestViewSet() self._run_permission_checks(view, TestModel(), True) self._run_dry_permission_field_checks(view, TestModel(), True, True) def test_list_filter_backend(self): class DummyFilter(object): pass class TestModel(DummyModel): pass class TestSerializer(DummySerializer): class Meta: model = TestModel class TestFilterBackend(DRYPermissionFiltersBase): def filter_list_queryset(self, request, queryset, view): return DummyFilter() class TestViewSet(DummyViewSet): serializer_class = TestSerializer queryset = TestModel.objects.all() filter_backends = (TestFilterBackend,) view = TestViewSet() view.request = self.request_list view.action = 'list' view.kwargs = [] query_set = view.filter_queryset(view.get_queryset()) self.assertEqual(query_set.__class__, DummyFilter) def test_action_filter_backend(self): class DummyFilter(object): pass class TestModel(DummyModel): pass class TestSerializer(DummySerializer): class Meta: model = TestModel class TestFilterBackend(DRYPermissionFiltersBase): action_routing = True def filter_list_queryset(self, request, queryset, view): return None def filter_custom_action1_queryset(self, request, queryset, view): return DummyFilter() class TestViewSet(DummyViewSet): serializer_class = TestSerializer queryset = TestModel.objects.all() filter_backends = (TestFilterBackend,) view = TestViewSet() view.request = self.request_custom_action1 view.action = 'custom_action1' view.kwargs = [] query_set = view.filter_queryset(view.get_queryset()) self.assertEqual(query_set.__class__, DummyFilter)
class commentsTest(TestCase): c = Client() user1 = {'email':'*****@*****.**', 'username':'******', 'password':'******'} user2 = {'email':'*****@*****.**', 'username':'******', 'password':'******'} activity = {"user_id":"1", "access_token":'testaccess', "keyword":"food", "access":0} comments1 = {"activity_id":1, "user_id":1, "contents":"user1's comments", "access_token":'testaccess', } comments2 = {"activity_id":1, "user_id":2, "contents":"user2's comments", "access_token":'testaccess', } getcomments = {"activity_id":1, "user_id":1, "access_token":'testaccess', "offset":0, "number":50 } deletecomment = {"activity_id":1, "user_id":1, "access_token":'testaccess', "comment_id":1, "number":50 } def setUp(self): self.c.post(API_REGISTER_URL, data=json.dumps(self.user1),content_type='application/json') self.c.post(API_REGISTER_URL, data=json.dumps(self.user2),content_type='application/json') models.user_auth.objects.all().update(access_token='testaccess') self.c.post(API_ACTIVITY_URL, data=json.dumps(self.activity),content_type='application/json') activity = models.activities.objects.all() self.assertEqual(activity.count(),1) self.factory = RequestFactory() def test_createComment(self): response = self.c.post(API_COMMENT_URL, data=json.dumps(self.comments1), content_type='application/json') print '\n commentTest: createComment - post '+ str(response) self.assertEqual(response.status_code, 200) response = json.loads(response.content) comment = models.comments.objects.all() self.assertEqual(comment.count(),1) self.assertEqual(comment[0].creator_id,1) self.assertEqual(comment[0].contents,"user1's comments") self.assertEqual(comment[0].activity_id,1) activity = models.activities.objects.get(pk=1) self.assertEqual(activity.num_of_comments, 1) self.c.post(API_COMMENT_URL, data=json.dumps(self.comments2), content_type='application/json') activity = models.activities.objects.get(pk=1) self.assertEqual(activity.num_of_comments, 2) def test_getComments(self): self.c.post(API_COMMENT_URL,data=json.dumps(self.comments1),content_type='application/json') self.c.post(API_COMMENT_URL,data=json.dumps(self.comments2),content_type='application/json') response = self.c.get(API_COMMENT_URL, data=self.getcomments) print '\n commentTest: getComments - get '+ str(response) self.assertEqual(response.status_code, 200) response = json.loads(response.content) self.assertEqual(len(response['comments']), 2) self.assertEqual(response['comments'][0]['contents'], self.comments2['contents']) self.assertEqual(response['comments'][0]['creator_id'], self.comments2['user_id']) self.assertEqual(response['comments'][0]['activity_id'], self.comments2['activity_id']) self.assertEqual(response['comments'][1]['contents'], self.comments1['contents']) self.assertEqual(response['comments'][1]['creator_id'], self.comments1['user_id']) self.assertEqual(response['comments'][1]['activity_id'], self.comments1['activity_id']) def test_deleteComments(self): self.c.post(API_COMMENT_URL,data=json.dumps(self.comments1),content_type='application/json') self.c.post(API_COMMENT_URL,data=json.dumps(self.comments2),content_type='application/json') request = self.factory.delete(API_COMMENT_URL, self.deletecomment, content_type='application/json') request.GET = self.deletecomment response = apis.comments(request) print '\n commentTest: delete Comments - delete '+ str(response) self.assertEqual(response.status_code, 200) response = json.loads(response.content) comments = models.comments.objects.filter(activity_id=1) self.assertEqual(comments.count(), 1) self.assertEqual(comments[0].creator_id, 2)
class CRUDViewTest(TestCase): names = ['John', 'Anne', 'Chris', 'Beatrice', 'Matt'] emails = ["@".join((name, "example.com")) for name in names] def setUp(self): self.factory = RequestFactory() # DummyModel2 and DummyModel / CRUDTestViewWithFK model2 = DummyModel2(name="Model2 name") model2.save() for name in self.names: DummyModel(name=name, model2=model2).save() # SimpleModel / CRUDTestViewWithSlug for name, email in zip(self.names, self.emails): SimpleModel(name=name, email=email).save() # model with m2m relationship dummy_model2 = DummyModel2(name="Mathilde") dummy_model2.save() self.m2m_model = M2MModel() self.m2m_model.save() self.m2m_model.dummy_models.add(dummy_model2) self.m2m_model.save() def test_get_allowed_methods(self): allowed_methods = CRUDTestView().get_allowed_methods() self.assertEqual(allowed_methods, ['GET', 'POST', 'DELETE']) allowed_methods = CRUDTestViewWithFewAllowedMethod( ).get_allowed_methods() self.assertEqual(allowed_methods, ['POST']) def test_ng_query(self): # CRUDTestViewWithFK request = self.factory.get('/crud/') response = CRUDTestViewWithFK.as_view()(request) data = json.loads(response.content.decode('utf-8')) for obj in data: db_obj = DummyModel.objects.get(pk=obj['pk']) self.assertEqual(obj['name'], db_obj.name) # CRUDTestViewWithSlug request2 = self.factory.get('/crud/') response2 = CRUDTestViewWithSlug.as_view()(request2) data2 = json.loads(response2.content.decode('utf-8')) for obj in data2: db_obj = SimpleModel.objects.get(email=obj['email']) self.assertEqual(obj['name'], db_obj.name) def test_ng_get(self): # CRUDTestViewWithFK request = self.factory.get('/crud/?pk=1') response = CRUDTestViewWithFK.as_view()(request) data = json.loads(response.content.decode('utf-8')) self.assertEqual(self.names[0], data['name']) # CRUDTestViewWithSlug request2 = self.factory.get('/crud/?email={0}'.format(self.emails[0])) response2 = CRUDTestViewWithSlug.as_view()(request2) data2 = json.loads(response2.content.decode('utf-8')) self.assertEqual(self.names[0], data2['name']) def test_ng_save_create(self): # CRUDTestViewWithFK request = self.factory.post('/crud/', data=json.dumps({'name': 'Leonard'}), content_type='application/json') response = CRUDTestView.as_view()(request) data = json.loads(response.content.decode('utf-8')) pk = data['pk'] request2 = self.factory.get('/crud/?pk={0}'.format(pk)) response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content.decode('utf-8')) self.assertEqual(data2['name'], 'Leonard') # CRUDTestViewWithSlug request3 = self.factory.post('/crud/', data=json.dumps({ 'name': 'Leonard', 'email': '*****@*****.**' }), content_type='application/json') CRUDTestViewWithSlug.as_view()(request3) request4 = self.factory.get( '/crud/?email={0}'.format('*****@*****.**')) response4 = CRUDTestViewWithSlug.as_view()(request4) data4 = json.loads(response4.content.decode('utf-8')) self.assertEqual(data4['name'], 'Leonard') request5 = self.factory.post('/crud/', data=json.dumps({ 'name': 'Leonard2', 'email': '*****@*****.**' }), content_type='application/json') response5 = CRUDTestViewWithSlug.as_view()(request5) self.assertGreaterEqual(response5.status_code, 400) data5 = json.loads(response5.content.decode('utf-8')) self.assertTrue('detail' in data5 and 'email' in data5['detail'] and len(data5['detail']['email']) > 0) def test_ng_save_update(self): # CRUDTestViewWithFK request = self.factory.post('/crud/?pk=1', data=json.dumps({ 'pk': 1, 'name': 'John2' }), content_type='application/json') response = CRUDTestView.as_view()(request) data = json.loads(response.content.decode('utf-8')) self.assertEqual(data['name'], 'John2') request2 = self.factory.get('/crud/?pk=1') response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content.decode('utf-8')) self.assertEqual(data2['name'], 'John2') # CRUDTestViewWithSlug request3 = self.factory.post('/crud/?pk=1', data=json.dumps({ 'name': 'John', 'email': '*****@*****.**' }), content_type='application/json') response3 = CRUDTestViewWithSlug.as_view()(request3) data3 = json.loads(response3.content.decode('utf-8')) self.assertEqual(data3['name'], 'John') self.assertEqual(data3['email'], '*****@*****.**') request4 = self.factory.get('/crud/[email protected]') response4 = CRUDTestViewWithSlug.as_view()(request4) data4 = json.loads(response4.content.decode('utf-8')) self.assertEqual(data4['name'], 'John') request5 = self.factory.post( '/crud/?pk=3', # Modifying "Chris" data=json.dumps({ 'pk': 4, 'name': 'John2', 'email': '*****@*****.**' }), content_type='application/json') response5 = CRUDTestViewWithSlug.as_view()(request5) self.assertGreaterEqual(response5.status_code, 400) data5 = json.loads(response5.content.decode('utf-8')) self.assertTrue('detail' in data5 and 'email' in data5['detail'] and len(data5['detail']['email']) > 0) def test_ng_delete(self): # CRUDTestViewWithFK request = self.factory.delete('/crud/?pk=1') response = CRUDTestViewWithFK.as_view()(request) data = json.loads(response.content.decode('utf-8')) deleted_name = data['name'] request2 = self.factory.get('/crud/') response2 = CRUDTestViewWithFK.as_view()(request2) data2 = json.loads(response2.content.decode('utf-8')) for obj in data2: self.assertTrue(deleted_name != obj['name']) # CRUDTestViewWithSlug delete is not different from CRUDTestViewWithFK only testing error status codes request3 = self.factory.delete( '/crud/[email protected]') # Missing pk response3 = CRUDTestViewWithSlug.as_view()(request3) self.assertEqual(response3.status_code, 400) request4 = self.factory.delete('/crud/?pk=100') # Invalid pk response4 = CRUDTestViewWithSlug.as_view()(request4) self.assertEqual(response4.status_code, 404) # Testing with m2m relationship request5 = self.factory.delete('/crud/?pk=%s' % self.m2m_model.pk) response5 = CRUDTestViewWithM2M.as_view()(request5) self.assertEqual(response5.status_code, 200) def test_method_not_supported(self): # CRUDTestViewWithFewAllowedMethod request = self.factory.get('/crud/') response = CRUDTestViewWithFewAllowedMethod.as_view()(request) self.assertEqual(response.status_code, 405) request = self.factory.post('/crud/', data=json.dumps({'name': 'Leonard'}), content_type='application/json') response = CRUDTestViewWithFewAllowedMethod.as_view()(request) self.assertEqual(response.status_code, 200)
class LoginUserTest(MockedCloudTestCase): def setUp(self): super(LoginUserTest, self).setUp() self.factory = RequestFactory() # Create an user to check login attempts against self.existing_user = User.objects.create_user( username='******', cloud_fqdn='existingserver') def tearDown(self): self.existing_user.delete() def test_login_good_credentials(self): good_creds = { 'username': '******', 'password': '******', 'cloud_fqdn': 'existingserver', } request = self.factory.post(reverse(login_user), data=good_creds) self.do_session_middleware_stuff(request) resp = login_user(request) self.assertEqual(resp.status_code, 200) def test_login_bad_credentials(self): bad_creds = { 'username': '******', 'password': '******', 'cloud_fqdn': 'existingserver', } request = self.factory.post(reverse(login_user), data=bad_creds) self.do_session_middleware_stuff(request) # Set mocked backend to fail authentication self.set_auth_result(False) resp = login_user(request) self.assertEqual(resp.status_code, 401) def test_login_missing_credentials(self): missing_creds = { 'username': '******', 'cloud_fqdn': 'existingserver', } request = self.factory.post(reverse(login_user), data=missing_creds) resp = login_user(request) self.assertEqual(resp.status_code, 400) def test_login_bad_methods(self): get_request = self.factory.get(reverse(login_user)) resp = login_user(get_request) self.assertEqual(resp.status_code, 405) put_request = self.factory.put(reverse(login_user)) resp = login_user(put_request) self.assertEqual(resp.status_code, 405) delete_request = self.factory.delete(reverse(login_user)) resp = login_user(delete_request) self.assertEqual(resp.status_code, 405) def test_login_no_persistent_session(self): good_creds = { 'username': '******', 'password': '******', 'cloud_fqdn': 'existingserver', 'persistent_session': 'False' } resp = self.client.post(reverse(login_user), good_creds) self.assertEqual(resp.status_code, 200) session_cookie = self.client.cookies['sessionid'] self.assertEqual(session_cookie['expires'], "")
class ResourceTestCase(TestCase): def setUp(self): self.factory = RequestFactory() def test_default(self): "Tests for the default Resource which is very limited." # Default resource resource = Resource() # Populated implicitly via the metaclass.. self.assertEqual(resource.allowed_methods, ("OPTIONS",)) # OPTIONS is successful, default response with no content is a 204 request = self.factory.options("/") response = resource(request) self.assertEqual(response.status_code, codes.no_content) # Try another non-default method request = self.factory.get("/") response = resource(request) self.assertEqual(response.status_code, codes.method_not_allowed) self.assertEqual(response["Allow"], "OPTIONS") def test_default_head(self): class GetResource(Resource): def get(self, request): return {} resource = GetResource() request = self.factory.head("/") response = resource(request) self.assertEqual(response.status_code, codes.ok) self.assertEqual(response["Content-Type"], "application/json") self.assertEqual(response.content, b"") def test_default_patch(self): # Resources supporting PATCH requests should have an additional # header in the response from an OPTIONS request class PatchResource(Resource): def patch(self, request): pass resource = PatchResource() request = self.factory.options("/") response = resource(request) self.assertEqual(response.status_code, codes.no_content) self.assertEqual(response["Accept-Patch"], "application/json") self.assertEqual(response["Content-Type"], "application/json") def test_service_unavailable(self): "Test service unavailability." class IndefiniteUnavailableResource(Resource): unavailable = True resource = IndefiniteUnavailableResource() # Simply setting `unavailable` to True will provide a 'Retry-After' # header request = self.factory.request() response = resource(request) self.assertEqual(response.status_code, codes.service_unavailable) self.assertTrue("Retry-After" not in response) self.assertEqual(response["Content-Type"], "application/json") def test_service_unavailable_retry_seconds(self): "Test service unavailability with seconds." class DeltaUnavailableResource(Resource): unavailable = 20 resource = DeltaUnavailableResource() # Set unavailable, but with a specific number of seconds to retry # after request = self.factory.request() response = resource(request) self.assertEqual(response.status_code, codes.service_unavailable) self.assertEqual(response["Retry-After"], "20") self.assertEqual(response["Content-Type"], "application/json") def test_service_unavailable_retry_date(self): "Test service unavailability with date." from datetime import datetime, timedelta from django.utils.http import http_date future = datetime.now() + timedelta(seconds=20) class DatetimeUnavailableResource(Resource): unavailable = future resource = DatetimeUnavailableResource() request = self.factory.request() response = resource(request) self.assertEqual(response.status_code, codes.service_unavailable) self.assertEqual(response["Retry-After"], http_date(timegm(future.utctimetuple()))) self.assertEqual(response["Content-Type"], "application/json") def test_unsupported_media_type(self): "Test various Content-* combinations." class NoOpResource(Resource): def post(self, request, *args, **kwargs): pass resource = NoOpResource() # Works.. default accept-type is application/json request = self.factory.post("/", data=b'{"message": "hello w\xc3\xb6"}', content_type="application/json") response = resource(request) self.assertEqual(response.status_code, codes.no_content) self.assertEqual(response["Content-Type"], "application/json") # Does not work.. XML not accepted by default request = self.factory.post("/", data="<message>hello world</message>", content_type="application/xml") response = resource(request) self.assertEqual(response.status_code, codes.unsupported_media_type) self.assertEqual(response["Content-Type"], "application/json") def test_not_acceptable(self): "Test Accept header." class ReadOnlyResource(Resource): def get(self, request, *args, **kwargs): return {} resource = ReadOnlyResource() # No accept-type is specified, defaults to highest priority one # for resource request = self.factory.request() response = resource(request) self.assertEqual(response.status_code, codes.ok) self.assertEqual(response["Content-Type"], "application/json") # Explicit accept header, application/json wins since it's equal # priority and supported request = self.factory.request(HTTP_ACCEPT="application/json,application/xml;q=0.9,*/*;q=0.8") response = resource(request) self.assertEqual(response.status_code, codes.ok) self.assertEqual(response["Content-Type"], "application/json") # No acceptable type list, */* has an explicit quality of 0 which # does not allow the server to use an alternate content-type request = self.factory.request(HTTP_ACCEPT="text/html,application/xhtml+xml," "application/xml;q=0.9,*/*;q=0") response = resource(request) self.assertEqual(response.status_code, codes.not_acceptable) self.assertEqual(response["Content-Type"], "application/json") # Like the first one, but an explicit "anything goes" request = self.factory.request(HTTP_ACCEPT="*/*") response = resource(request) self.assertEqual(response.status_code, codes.ok) self.assertEqual(response["Content-Type"], "application/json") def test_request_entity_too_large(self): "Test request entity too large." class TinyResource(Resource): max_request_entity_length = 20 def post(self, request, *args, **kwargs): pass resource = TinyResource() # No problem.. request = self.factory.post("/", data='{"message": "hello"}', content_type="application/json") response = resource(request) self.assertEqual(response.status_code, codes.no_content) self.assertEqual(response["Content-Type"], "application/json") # Too large request = self.factory.post("/", data='{"message": "hello world"}', content_type="application/json") response = resource(request) self.assertEqual(response.status_code, codes.request_entity_too_large) self.assertEqual(response["Content-Type"], "application/json") def test_too_many_requests(self): """Test a global rate limiting implementation. This test will take 3 seconds to run to mimic request handling over time. """ import time from datetime import datetime class RateLimitResource(Resource): # Maximum of 10 requests within a 2 second window rate_limit_count = 10 rate_limit_seconds = 2 # Keep track of requests globally for the resource.. only for test # purposes, not thread-safe request_frame_start = datetime.now() request_count = 0 # Implement rate-limiting logic def is_too_many_requests(self, request, *args, **kwargs): # Since the start of the frame, calculate the amount of time # that has passed interval = (datetime.now() - self.request_frame_start).seconds # Increment the request count self.request_count += 1 # Reset frame if the interval is greater than the rate limit # seconds, i.e on the 3rd second in this test if interval > self.rate_limit_seconds: self.request_frame_start = datetime.now() self.request_count = 1 # ..otherwise throttle if the count is greater than the limit elif self.request_count > self.rate_limit_count: return True return False resource = RateLimitResource() request = self.factory.request(REQUEST_METHOD="OPTIONS") # First ten requests are ok for _ in range(0, 10): response = resource(request) self.assertEqual(response.status_code, codes.no_content) self.assertEqual(response["Content-Type"], "application/json") # Mimic a slight delay time.sleep(1) # Another 10 all get throttled.. for _ in range(0, 10): response = resource(request) self.assertEqual(response.status_code, codes.too_many_requests) self.assertEqual(response["Content-Type"], "application/json") # Another two seconds exceeds the frame, should be good to go time.sleep(2) for _ in range(0, 10): response = resource(request) self.assertEqual(response.status_code, codes.no_content) self.assertEqual(response["Content-Type"], "application/json") def test_precondition_required(self): """"Reject non-idempotent requests without the use of a conditional header.""" class PreconditionResource(Resource): # Either etags or last-modified must be used otherwise it # is not enforced use_etags = True require_conditional_request = True def patch(self, request): pass def put(self, request): pass def delete(self, request): pass def get_etag(self, request, *args, **kwargs): return "abc123" resource = PreconditionResource() # Non-idempotent requests fail without a conditional header, these # responses should not be cached request = self.factory.put("/", data='{"message": "hello world"}', content_type="application/json") response = resource(request) self.assertEqual(response.status_code, codes.precondition_required) self.assertEqual(response["Content-Type"], "application/json") self.assertTrue("no-cache" in response["Cache-Control"]) self.assertTrue("must-revalidate" in response["Cache-Control"]) self.assertTrue("max-age=0" in response["Cache-Control"]) # Add the correct header for testing the Etag request = self.factory.put( "/", data='{"message": "hello world"}', content_type="application/json", HTTP_IF_MATCH="abc123" ) response = resource(request) self.assertEqual(response.status_code, codes.no_content) self.assertEqual(response["Content-Type"], "application/json") # Idempotent requests, such as DELETE, succeed.. request = self.factory.delete("/") response = resource(request) self.assertEqual(response.status_code, codes.no_content) self.assertEqual(response["Content-Type"], "application/json") def test_precondition_failed_etag(self): "Test precondition using etags." class PreconditionResource(Resource): use_etags = True def put(self, request): pass def get(self, request): return {} def get_etag(self, request, *args, **kwargs): return "abc123" resource = PreconditionResource() # Send a non-safe request with an incorrect Etag.. fail request = self.factory.put( "/", data='{"message": "hello world"}', content_type="application/json", HTTP_IF_MATCH='"def456"' ) response = resource(request) self.assertEqual(response.status_code, codes.precondition_failed) self.assertEqual(response["Content-Type"], "application/json") self.assertTrue("no-cache" in response["Cache-Control"]) self.assertTrue("must-revalidate" in response["Cache-Control"]) self.assertTrue("max-age=0" in response["Cache-Control"]) # Incorrect Etag match on GET, updated content is returned request = self.factory.get("/", HTTP_IF_NONE_MATCH='"def456"') response = resource(request) self.assertEqual(response.status_code, codes.ok) self.assertEqual(response["Content-Type"], "application/json") # Successful Etag match on GET, resource not modified request = self.factory.get("/", HTTP_IF_NONE_MATCH='"abc123"') response = resource(request) self.assertEqual(response.status_code, codes.not_modified) self.assertEqual(response["Content-Type"], "application/json") def test_precondition_failed_last_modified(self): "Test precondition using last-modified dates." from datetime import datetime, timedelta from django.utils.http import http_date last_modified_date = datetime.now() class PreconditionResource(Resource): use_etags = False use_last_modified = True def put(self, request): pass def get(self, request): return {} def get_last_modified(self, request, *args, **kwargs): return last_modified_date resource = PreconditionResource() # Send non-safe request with a old last-modified date.. fail if_modified_since = http_date(timegm((last_modified_date - timedelta(seconds=10)).utctimetuple())) request = self.factory.put( "/", data='{"message": "hello world"}', content_type="application/json", HTTP_IF_UNMODIFIED_SINCE=if_modified_since, ) response = resource(request) self.assertEqual(response.status_code, codes.precondition_failed) self.assertEqual(response["Content-Type"], "application/json") self.assertTrue("no-cache" in response["Cache-Control"]) self.assertTrue("must-revalidate" in response["Cache-Control"]) self.assertTrue("max-age=0" in response["Cache-Control"]) # Old last-modified on GET, updated content is returned if_modified_since = http_date(timegm((last_modified_date - timedelta(seconds=10)).utctimetuple())) request = self.factory.get("/", HTTP_IF_MODIFIED_SINCE=if_modified_since) response = resource(request) self.assertEqual(response.status_code, codes.ok) self.assertEqual(response["Content-Type"], "application/json") # Mimic future request on GET, resource not modified if_modified_since = http_date(timegm((last_modified_date + timedelta(seconds=20)).utctimetuple())) request = self.factory.get("/", HTTP_IF_MODIFIED_SINCE=if_modified_since) response = resource(request) self.assertEqual(response.status_code, codes.not_modified) self.assertEqual(response["Content-Type"], "application/json") def test_cache_control_default(self): class CacheableResource(Resource): def get(self, request): return {} resource = CacheableResource() request = self.factory.get("/") response = resource(request) self.assertFalse("Cache-Control" in response) self.assertEqual(response["Content-Type"], "application/json") def test_cache_control_seconds(self): class CacheableResource(Resource): cache_max_age = 60 * 60 # 1 hour def get(self, request): return {} resource = CacheableResource() request = self.factory.get("/") response = resource(request) self.assertEqual(response["Cache-Control"], "max-age=3600") self.assertEqual(response["Content-Type"], "application/json") def test_cache_control_date(self): from datetime import datetime, timedelta from django.utils.http import http_date class CacheableResource(Resource): cache_type = "private" cache_max_age = timedelta(seconds=60 * 60) # 1 hour def get(self, request): return {} resource = CacheableResource() request = self.factory.get("/") response = resource(request) self.assertEqual(response["Cache-Control"], "private") self.assertEqual(response["Expires"], http_date(timegm((datetime.now() + timedelta(hours=1)).utctimetuple()))) self.assertEqual(response["Content-Type"], "application/json")
class TestRatingResource(TestCase): """Tests on RatingResource""" def setUp(self): super(TestRatingResource, self).setUp() # Create the segments table manually, since we're not managing it with # the ORM. This SQL comes from running ``manage.py sqlall project`` at # the command line. segments_table_sql = """ CREATE TABLE "philly_street_osm_line" ( "osm_id" integer NOT NULL PRIMARY KEY ) ; SELECT AddGeometryColumn('philly_street_osm_line', 'way', 900913, 'LINESTRING', 2); CREATE INDEX "philly_street_osm_line_way_id" ON "philly_street_osm_line" USING GIST ( "way" GIST_GEOMETRY_OPS ); COMMIT; """ from django.db import connection cursor = connection.cursor() cursor.execute(segments_table_sql) from project.models import Segment Segment.objects.all().delete() self.req = RequestFactory() def tearDown(self): super(TestRatingResource, self).tearDown() from django.db import connection cursor = connection.cursor() cursor.execute(""" DROP TABLE philly_street_osm_line; COMMIT; """) def test_parsers(self): from project.resources import RatingInstanceView, RatingJSONParser from djangorestframework.parsers import JSONParser from StringIO import StringIO self.assertEqual(len(RatingInstanceView.parsers), 4) self.assertNotIn(JSONParser, RatingInstanceView.parsers) self.assertIn(RatingJSONParser, RatingInstanceView.parsers) parser = RatingJSONParser(None) # None for the view json_string = StringIO('{"criterion":3,"question":"How much do you like it?","score":"4","segment":456,"block_index":5239,"url":"http://localhost:8000/ratings/13","id":13}') self.assertNotIn(u'id', parser.parse(json_string)) def test_read(self): from project.models import Rating, Criterion, Segment criterion = Criterion.objects.create(prompt='Hello?') segment = Segment.objects.create(id=123) rating = Rating.objects.create(criterion=criterion, segment1=segment, block1_index=2, segment2=segment, block2_index=2, score=5) from project.resources import RatingInstanceView request = self.req.get('/ratings/{}'.format(rating.id)) view = RatingInstanceView() response = view.get(request, rating.id) self.assertEquals(rating, response) def test_delete(self): from project.models import Rating, Criterion, Segment criterion = Criterion.objects.create(prompt='Hello?') segment = Segment.objects.create(id=123) rating = Rating.objects.create(criterion=criterion, segment1=segment, block1_index=2, segment2=segment, block2_index=2, score=5) assert_equal(Rating.objects.count(), 1) from project.resources import RatingInstanceView request = self.req.delete('/ratings/{}'.format(rating.id)) view = RatingInstanceView() response = view.delete(request, rating.id) assert_equal(Rating.objects.count(), 0) def test_update(self): from project.models import Rating, Criterion, Segment criterion1 = Criterion.objects.create(prompt='Hello?') criterion2 = Criterion.objects.create(prompt='Goodbye!') segment1 = Segment.objects.create(id=123) segment2 = Segment.objects.create(id=456) rating = Rating.objects.create(criterion=criterion1, segment1=segment1, block1_index=2, segment2=segment1, block2_index=2, score=5) from project.resources import RatingInstanceView request = self.req.put('/ratings/{}'.format(rating.id), data={ 'segment2': segment2.id, 'block2_index': 14, 'segment1': segment2.id, 'block1_index': 14, 'criterion': criterion2.id, 'score': 2}) view = RatingInstanceView() view.request = request response = view.put(request, rating.id) self.assertEquals(rating, response) self.assertEqual(response.criterion, criterion2) self.assertEqual(response.segment2, segment2) self.assertEqual(response.block2_index, 14) self.assertEqual(response.score, 2) def test_create(self): from project.models import Rating, Criterion, Segment criterion = Criterion.objects.create(prompt='Hello?') segment1 = Segment.objects.create(id=123) segment2 = Segment.objects.create(id=456) assert_equal(Rating.objects.count(), 0) from project.resources import RatingListView request = self.req.post('/ratings/', data={ 'segment1': segment1.id, 'block1_index': 7, 'segment2': segment2.id, 'block2_index': 14, 'criterion': criterion.id, 'score': 2}) view = RatingListView() view.request = request response = view.post(request) self.assertEquals(Rating.objects.count(), 1) self.assertEqual(response.cleaned_content.criterion, criterion) self.assertEqual(response.cleaned_content.segment1, segment1) self.assertEqual(response.cleaned_content.block1_index, 7) self.assertEqual(response.cleaned_content.score, 2)
class TestBulkAPIMixins(TestCase): lang1 = {'id': 'en-us', 'lang_code': 'en', 'lang_subcode': 'us'} lang2 = {'id': 'fr-fr', 'lang_code': 'fr', 'lang_subcode': 'fr'} def setUp(self): super(TestBulkAPIMixins, self).setUp() self.request = RequestFactory() def test_get(self): """ Test that GET request is successful on bulk create view. """ view = BulkCreateView.as_view({'get': 'list'}) response = view(self.request.get('')) self.assertEqual(response.status_code, status.HTTP_200_OK) def test_post_single(self): """ Test that POST request with single resource only creates a single resource. """ view = BulkCreateView.as_view({'post': 'create'}) response = view( self.request.post( '', json.dumps(self.lang1), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Language.objects.count(), 1) self.assertEqual(Language.objects.get().id, self.lang1['id']) def test_post_bulk(self): """ Test that POST request with multiple resources creates all posted resources. """ view = BulkCreateView.as_view({'post': 'create'}) response = view( self.request.post( '', json.dumps([ self.lang1, self.lang2, ]), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Language.objects.count(), 2) self.assertEqual( list(Language.objects.all().values_list('id', flat=True)), [ self.lang1['id'], self.lang2['id'], ]) def test_delete_not_filtered(self): """ Test that DELETE is not allowed when results are not filtered. """ view = BulkDeleteView.as_view({'delete': 'bulk_destroy'}) Language.objects.create(**self.lang1) Language.objects.create(**self.lang2) response = view(self.request.delete('')) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_delete_filtered(self): """ Test that DELETE removes all filtered resources. """ view = BulkDeleteView.as_view({'delete': 'bulk_destroy'}) Language.objects.create(**self.lang1) Language.objects.create(**self.lang2) response = view(self.request.delete('?id=' + self.lang1['id'])) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(Language.objects.count(), 1) self.assertEqual(Language.objects.get().id, self.lang2['id'])
class TestBulkAPIView(TestCase): def setUp(self): super(TestBulkAPIView, self).setUp() self.view = SimpleBulkAPIView.as_view() self.request = RequestFactory() def test_get(self): """ Test that GET request is successful on bulk view. """ response = self.view(self.request.get('')) self.assertEqual(response.status_code, status.HTTP_200_OK) def test_post_single(self): """ Test that POST request with single resource only creates a single resource. """ response = self.view(self.request.post( '', json.dumps({'contents': 'hello world', 'number': 1}), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(SimpleModel.objects.count(), 1) self.assertEqual(SimpleModel.objects.get().contents, 'hello world') def test_post_bulk(self): """ Test that POST request with multiple resources creates all posted resources. """ response = self.view(self.request.post( '', json.dumps([ {'contents': 'hello world', 'number': 1}, {'contents': 'hello mars', 'number': 2}, ]), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(SimpleModel.objects.count(), 2) self.assertEqual(list(SimpleModel.objects.all().values_list('contents', flat=True)), [ 'hello world', 'hello mars', ]) def test_put(self): """ Test that PUT request updates all submitted resources. """ obj1 = SimpleModel.objects.create(contents='hello world', number=1) obj2 = SimpleModel.objects.create(contents='hello mars', number=2) response = self.view(self.request.put( '', json.dumps([ {'contents': 'foo', 'number': 3, 'id': obj1.pk}, {'contents': 'bar', 'number': 4, 'id': obj2.pk}, ]), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(SimpleModel.objects.count(), 2) self.assertEqual( list(SimpleModel.objects.all().values_list('id', 'contents', 'number')), [ (obj1.pk, 'foo', 3), (obj2.pk, 'bar', 4), ] ) def test_put_without_update_key(self): """ Test that PUT request updates all submitted resources. """ response = self.view(self.request.put( '', json.dumps([ {'contents': 'foo', 'number': 3}, {'contents': 'rainbows', 'number': 4}, # multiple objects without id {'contents': 'bar', 'number': 4, 'id': 555}, # non-existing id ]), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_patch(self): """ Test that PATCH request partially updates all submitted resources. """ obj1 = SimpleModel.objects.create(contents='hello world', number=1) obj2 = SimpleModel.objects.create(contents='hello mars', number=2) response = self.view(self.request.patch( '', json.dumps([ {'contents': 'foo', 'id': obj1.pk}, {'contents': 'bar', 'id': obj2.pk}, ]), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(SimpleModel.objects.count(), 2) self.assertEqual( list(SimpleModel.objects.all().values_list('id', 'contents', 'number')), [ (obj1.pk, 'foo', 1), (obj2.pk, 'bar', 2), ] ) def test_delete_not_filtered(self): """ Test that DELETE is not allowed when results are not filtered. """ SimpleModel.objects.create(contents='hello world', number=1) SimpleModel.objects.create(contents='hello mars', number=10) response = self.view(self.request.delete('')) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_delete_filtered(self): """ Test that DELETE removes all filtered resources. """ SimpleModel.objects.create(contents='hello world', number=1) SimpleModel.objects.create(contents='hello mars', number=10) response = FilteredBulkAPIView.as_view()(self.request.delete('')) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(SimpleModel.objects.count(), 1) self.assertEqual(SimpleModel.objects.get().contents, 'hello world') def test_options(self): """ Test that OPTIONS request is successful on bulk view. """ response = self.view(self.request.options('')) self.assertEqual(response.status_code, status.HTTP_200_OK)
class ViewTest(unittest.TestCase): """ Tests for BackboneAPIView. Note that django.contrib.auth must be in INSTALLED_APPS for these to work. """ def setUp(self): self.factory = RequestFactory() self.view = ReadOnlyView.as_view() self.writable_view = FullView.as_view() self.user1 = User.objects.create(username='******', first_name='Test', last_name='One') def tearDown(self): User.objects.all().delete() def add_two_more_users(self): self.user2 = User.objects.create(username='******', first_name='Test', last_name='Two') self.user3 = User.objects.create(username='******', first_name='Test', last_name='Three') def test_collection_get(self): request = self.factory.get('/users/') response = self.view(request) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) # Ensure response json deserializes to a 1-item list: self.assert_(isinstance(response_data, list)) self.assertEqual(len(response_data), 1) self.assertEqual(response_data[0]['username'], self.user1.username) # Try again with a few more users in the database: self.add_two_more_users() response = self.view(request) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) self.assert_(isinstance(response_data, list)) self.assertEqual(len(response_data), 3) # With User model's default ordering (by id), user3 should be last: self.assertEqual(response_data[2]['username'], self.user3.username) # Test pagination: response = self.writable_view(request) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) self.assert_(isinstance(response_data, list)) self.assertEqual(len(response_data), 2) # Page 2 should only have one item: request = self.factory.get('/users/?p=2') response = self.writable_view(request) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) self.assert_(isinstance(response_data, list)) self.assertEqual(len(response_data), 1) def test_single_item_get(self): request = self.factory.get('/users/1') response = self.view(request, id='1') # Simulate a urlconf passing in the 'id' kwarg self.assertEqual(response.status_code, 200) response_data = json.loads(response.content) self.assert_(isinstance(response_data, dict)) self.assertEqual(response_data['username'], self.user1.username) # Ensure 404s are raised for non-existent items: request = self.factory.get('/users/7') self.assertRaises(Http404, lambda: self.view(request, id='7')) def test_post(self): request = self.factory.post('/users') response = self.view(request) self.assertEqual(response.status_code, 405) # "Method not supported" if no add_form_class specified # Testing BackboneAPIView subclasses that support POST via add_form_class: # If no JSON provided in POST body, return HTTP 400: response = self.writable_view(request) self.assertEqual(response.status_code, 400) # Test the case where invalid input is given (leading to form errors): request = self.factory.post('/users', '{"wrong_field": "xyz"}', content_type='application/json') response = self.writable_view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.content, 'ERROR: validation failed') # If valid JSON was provided, a new instance should be created: request = self.factory.post('/users', '{"username": "******"}', content_type='application/json') response = self.writable_view(request) self.assertEqual(response.status_code, 200) self.assert_(User.objects.get(username='******')) response_json = json.loads(response.content) self.assertEqual(response_json['username'], 'post_test') def test_put(self): request = self.factory.put('/users/1') response = self.view(request, id='1') self.assertEqual(response.status_code, 405) # "Method not supported" if no edit_form_class specified # PUT is also not supported for collections (when no id is provided): request = self.factory.put('/users') response = self.writable_view(request) self.assertEqual(response.status_code, 405) # If no JSON in PUT body, return HTTP 400: response = self.writable_view(request, id='1') self.assertEqual(response.status_code, 400) # Raise 404 if an object with the given id doesn't exist: request = self.factory.put('/users/27', '{"username": "******"}', content_type='application/json') self.assertRaises(Http404, lambda: self.writable_view(request, id='27')) # If the object exists and an edit_form_class is supplied, it actually does something: request = self.factory.put('/users/1', '{"username": "******"}', content_type='application/json') response = self.writable_view(request, id='1') self.assertEqual(response.status_code, 200) self.assertEqual(User.objects.get(id=1).username, 'put_test') response_json = json.loads(response.content) self.assertEqual(response_json['username'], 'put_test') # Test the case where invalid input is given (leading to form errors): request = self.factory.put('/users/1', '{"wrong_field": "xyz"}', content_type='application/json') response = self.writable_view(request, id='1') self.assertEqual(response.status_code, 200) self.assertEqual(response.content, 'ERROR: validation failed') def test_delete(self): # Delete is not supported for collections: request = self.factory.delete('/users') response = self.view(request) self.assertEqual(response.status_code, 405) self.assertEqual(User.objects.filter(id=1).count(), 1) # But it is supported for single items (specified by id): request = self.factory.delete('/users/1') response = self.view(request, id='1') self.assertEqual(response.status_code, 200) self.assertEqual(User.objects.filter(id=1).count(), 0) # Should raise 404 if we try to access a deleted resource again: request = self.factory.delete('/users/1') self.assertRaises(Http404, lambda: self.view(request, id='1'))
class ProductResourceTestCase(TestCase): def setUp(self): self.factory = RequestFactory() self.product_resource = ProductResource() def test_GET_list_return_objects_and_count(self): """Should get a list of products with meta data""" product = ProductFactory.create() # Preconditions self.assertEqual(Product.objects.all().count(), 1) request = self.factory.get("/api/v1/product/") response = self.product_resource.dispatch_list(request) self.assertEqual(response.status_code, 200) self.assertEqual(response._charset, 'utf-8') content = json.loads(response.content.decode(response._charset)) self.assertTrue('meta' in content) self.assertTrue('total_count' in content['meta']) self.assertEqual(content['meta']['total_count'], 1) self.assertTrue('objects' in content) objects = content['objects'] self.assertEqual(len(objects), 1) obj1 = objects[0] self.assertEqual(obj1['name'], product.name) def test_GET_individual_product(self): """Should get an individual product by ID""" product = ProductFactory.create() ProductFactory.create() # Preconditions self.assertEqual(Product.objects.all().count(), 2) url = "/api/v1/product/{}/".format(product.id) request = self.factory.get(url) response = self.product_resource.dispatch_detail( request, pk=product.id) self.assertEqual(response.status_code, 200) self.assertEqual(response._charset, 'utf-8') content = json.loads(response.content.decode(response._charset)) self.assertEqual(content['name'], product.name) self.assertEqual(content['id'], product.id) def test_POST_a_product(self): """Should POST and create an individual product""" # Preconditions self.assertEqual(Product.objects.all().count(), 0) url = "/api/v1/product/" request = self.factory.post(url, data=json.dumps({ 'name': 'Test Product', 'description': 'Test description', 'inventory_count': 3 }), content_type="application/json") response = self.product_resource.dispatch_list(request) self.assertEqual(response.status_code, 201) self.assertEqual(Product.objects.all().count(), 1) def test_POST_an_invalid_inventory_product(self): """Should reject a product with invalid inventory count""" # Preconditions self.assertEqual(Product.objects.all().count(), 0) url = "/api/v1/product/" request = self.factory.post(url, data=json.dumps({ 'name': 'Test Product', 'description': 'Test description', 'inventory_count': 1000 # Too much! }), content_type="application/json") with self.assertRaises(ImmediateHttpResponse): self.product_resource.dispatch_list(request) def test_DELETE_a_product(self): """Should delete a product by ID""" product = ProductFactory.create() # Preconditions self.assertEqual(Product.objects.all().count(), 1) request = self.factory.delete("/api/v1/product/{}/".format(product.id)) response = self.product_resource.dispatch_list(request) self.assertEqual(response.status_code, 204) def test_update_a_product_inventory_count(self): """Should update the inventory count of a product through PATCH""" product = ProductFactory.create(inventory_count=3) # Preconditions self.assertEqual(Product.objects.all().count(), 1) self.assertEqual(product.inventory_count, 3) url = "/api/v1/product/{}/".format(product.id) request = self.factory.patch(url, data=json.dumps({ 'inventory_count': 7 }), content_type="application/json") response = self.product_resource.dispatch_detail( request, pk=product.id) self.assertEqual(response.status_code, 202)
class TestBulkAPIView(TestCase): def setUp(self): super(TestBulkAPIView, self).setUp() self.view = SimpleBulkAPIView.as_view() self.request = RequestFactory() def test_get(self): """ Test that GET request is successful on bulk view. """ response = self.view(self.request.get('')) self.assertEqual(response.status_code, status.HTTP_200_OK) def test_post_single(self): """ Test that POST request with single resource only creates a single resource. """ response = self.view( self.request.post( '', json.dumps({ 'contents': 'hello world', 'number': 1 }), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(SimpleModel.objects.count(), 1) self.assertEqual(SimpleModel.objects.get().contents, 'hello world') def test_post_bulk(self): """ Test that POST request with multiple resources creates all posted resources. """ response = self.view( self.request.post( '', json.dumps([ { 'contents': 'hello world', 'number': 1 }, { 'contents': 'hello mars', 'number': 2 }, ]), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(SimpleModel.objects.count(), 2) self.assertEqual( list(SimpleModel.objects.all().values_list('contents', flat=True)), [ 'hello world', 'hello mars', ]) def test_put(self): """ Test that PUT request updates all submitted resources. """ obj1 = SimpleModel.objects.create(contents='hello world', number=1) obj2 = SimpleModel.objects.create(contents='hello mars', number=2) response = self.view( self.request.put( '', json.dumps([ { 'contents': 'foo', 'number': 3, 'id': obj1.pk }, { 'contents': 'bar', 'number': 4, 'id': obj2.pk }, ]), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(SimpleModel.objects.count(), 2) self.assertEqual( list(SimpleModel.objects.all().values_list('id', 'contents', 'number')), [ (obj1.pk, 'foo', 3), (obj2.pk, 'bar', 4), ]) def test_put_without_update_key(self): """ Test that PUT request updates all submitted resources. """ response = self.view( self.request.put( '', json.dumps([ { 'contents': 'foo', 'number': 3 }, { 'contents': 'rainbows', 'number': 4 }, # multiple objects without id { 'contents': 'bar', 'number': 4, 'id': 555 }, # non-existing id ]), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_patch(self): """ Test that PATCH request partially updates all submitted resources. """ obj1 = SimpleModel.objects.create(contents='hello world', number=1) obj2 = SimpleModel.objects.create(contents='hello mars', number=2) response = self.view( self.request.patch( '', json.dumps([ { 'contents': 'foo', 'id': obj1.pk }, { 'contents': 'bar', 'id': obj2.pk }, ]), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(SimpleModel.objects.count(), 2) self.assertEqual( list(SimpleModel.objects.all().values_list('id', 'contents', 'number')), [ (obj1.pk, 'foo', 1), (obj2.pk, 'bar', 2), ]) def test_delete_not_filtered(self): """ Test that DELETE is not allowed when results are not filtered. """ SimpleModel.objects.create(contents='hello world', number=1) SimpleModel.objects.create(contents='hello mars', number=10) response = self.view(self.request.delete('')) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_delete_filtered(self): """ Test that DELETE removes all filtered resources. """ SimpleModel.objects.create(contents='hello world', number=1) SimpleModel.objects.create(contents='hello mars', number=10) response = FilteredBulkAPIView.as_view()(self.request.delete('')) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(SimpleModel.objects.count(), 1) self.assertEqual(SimpleModel.objects.get().contents, 'hello world') def test_options(self): """ Test that OPTIONS request is successful on bulk view. """ response = self.view(self.request.options('')) self.assertEqual(response.status_code, status.HTTP_200_OK)
class ToolApiTestCase(TestCase): def setUp(self): # Set up a Request Factory self.factory = RequestFactory() # Set up a User self.john = User( username='******', hashed_password='******', salt='NaCl', zip_code='00413', email='*****@*****.**', phone_number='1234567890', default_pickup_arrangements='Drop in nearest mailbox.', ) self.john.save() # Set up a Tool today = timezone.now() self.sledge = Tool( name="sledgehammer", owner=self.john, description="A sturdy sledgehammer.", tool_type="hammer", tool_pickup_arrangements="If you can lift it, you can have it.", available_date=today, ) self.sledge.save() # Data for a modified tool self.brokenSledge_info = { "id": self.sledge.id, "name": "broken sledgehammer", "description": "Basically a stick.", "tool_type": "1/2 hammer", "in_community_shed": False, "tool_pickup_arrangements": "Take it off my lawn.", "tool_available": True, } # Data for a new tool self.needles_info = { "name": "Knitting Needles", "description": "for making plush eldrich monstrosities", "tool_type": "needle", "in_community_shed": True, "tool_pickup_arrangements": "Get it from the shed.", "tool_available": True } # Mock session, where applicable self.mock_session = \ { "user" : \ { "username" : self.john.username, "id" : self.john.id, "zip_code" : self.john.zip_code, } } # Empty session, otherwise self.empty_session = {} def test_getById(self): request = self.factory.get('/api/tool/') request.session = self.mock_session response = get_tool(request, self.sledge.id) # Did we get a clean response? self.assertEqual(response.status_code, 200) # Did we get the right data? # NOTE: Instead of the owner object, we'll be getting back # the owner's username, and instead of a date object, we'll # be getting a datetime in milliseconds. response_data = json.loads(response.content.decode("utf-8")) self.assertEqual(response_data["name"], self.sledge.name) self.assertEqual( response_data["owner"], self.sledge.owner.username, ) self.assertEqual( response_data["description"], self.sledge.description, ) self.assertEqual( response_data["tool_type"], self.sledge.tool_type, ) self.assertEqual( response_data["tool_pickup_arrangements"], self.sledge.tool_pickup_arrangements, ) self.assertEqual( response_data["available_date"], dt_to_milliseconds(self.sledge.available_date), ) def test_createNewTool(self): request = self.factory.post(path='/api/tool/', data=json.dumps(self.needles_info), content_type="application/json") request.session = self.mock_session response = update(request) response_data = json.loads(response.content.decode("utf-8")) # No way to know the new ID, but here's some stuff it isn't! self.assertIsNotNone(response_data["id"]) self.assertNotEqual(response_data["id"], 0) # Also no way to know the exact time of creation, but all that # we care about right now is that it's in the past. self.assertTrue(response_data["available_date"] - dt_to_milliseconds(timezone.now()) < 0) # And now the rest of the validation. self.assertEqual(response_data["name"], self.needles_info["name"]) self.assertEqual(response_data["owner"], self.john.username) self.assertEqual(response_data["description"], self.needles_info["description"]) self.assertEqual(response_data["tool_type"], self.needles_info["tool_type"]) self.assertEqual(response_data["in_community_shed"], self.needles_info["in_community_shed"]) self.assertEqual(response_data["tool_pickup_arrangements"], self.needles_info["tool_pickup_arrangements"]) self.assertTrue(response_data["tool_available"]) def test_updateTool(self): request = self.factory.put( path='/api/tool', content_type="application/json", data=json.dumps(self.brokenSledge_info), ) request.session = self.mock_session response = update(request) # Did we get a clean response? # print(response.content) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content.decode("utf-8")) self.assertEqual(response_data["id"], self.sledge.id) self.assertEqual(response_data["name"], self.brokenSledge_info["name"]) self.assertEqual(response_data["owner"], self.john.username) self.assertIsNotNone(response_data["available_date"]) self.assertEqual(response_data["description"], self.brokenSledge_info["description"]) self.assertEqual(response_data["tool_type"], self.brokenSledge_info["tool_type"]) def test_deleteTool_good(self): # sanity check self.assertIn(self.sledge, Tool.objects.all()) # call the delete route request = self.factory.delete('/api/tool') request.session = self.mock_session response = get_tool(request, self.sledge.id) response_data = json.loads(response.content.decode("utf-8")) # is it gone? self.assertTrue(response_data["success"]) self.assertNotIn(self.sledge, Tool.objects.all()) #@unittest.expectedFailure # system doesn't know how to handle nonexistant IDs @unittest.skip #for submitting R2 def test_deleteTool_bad(self): # try to delete a tool twice request = self.factory.delete('/api/tool') request.session = self.mock_session response = get_tool(request, self.sledge.id) #first response = get_tool(request, self.sledge.id) #second response_data = json.loads(response.content.decode("utf-8")) self.assertFalse(response_data["success"]) def test_getLocalTools(self): request = self.factory.get('/api/tools/area') # We need a user to have local tools to browse. request.session = self.mock_session response = local_tools(request) response_data = json.loads(response.content.decode("utf-8")) self.assertIn(tool_to_json(self.sledge), response_data) def test_getPersonalTools(self): request = self.factory.get('/api/tools') # We need a user to have personal tools to browse. request.session = self.mock_session response = user_tools(request) response_data = json.loads(response.content.decode("utf-8")) self.assertIn(tool_to_json(self.sledge), response_data)
class ResourceHttpMethodsTestCase(BaseTestCase): def setUp(self): super(ResourceHttpMethodsTestCase, self).setUp() self.factory = RequestFactory() TestResource = type("TestResource", (Resource,), {"model": Book}) TestResource.preprocess(Api()) self.collection_resource = TestResource(TestResource.as_list_view()["routes"]) self.element_resource = TestResource(TestResource.as_detail_view()["routes"]) def get_response(self, request, resource, params={}, content_type="application/json", status=200): response = resource.handle_request(request, **params) assert response.status_code == status, response.status_code assert content_type in response["Content-Type"], response if content_type == "application/json": return simplejson.loads(response.content) return response.content def test_show_method(self): request = self.factory.get("/books/") self.element_method_test(request, "detail") def test_update_method(self): request = self.factory.post("/books/1") self.element_method_test(request, "update") request = self.factory.put("/books/1") self.element_method_test(request, "update") def test_destroy_method(self): request = self.factory.delete("/books/") self.element_method_test(request, "destroy") def element_method_test(self, request, method): setattr(self.element_resource, method, element_return_list) content = self.get_response(request, self.element_resource, params={"pk": 1}) assert isinstance(content, list) setattr(self.element_resource, method, element_return_str) content = self.get_response(request, self.element_resource, params={"pk": 1}, content_type="text/html") assert isinstance(content, str) setattr(self.element_resource, method, element_return_int) content = self.get_response(request, self.element_resource, params={"pk": 1}, content_type="text/html") assert not content setattr(self.element_resource, method, element_return_dict) content = self.get_response(request, self.element_resource, params={"pk": 1}) assert isinstance(content, dict) assert "Objects" not in content assert "Meta" not in content setattr(self.element_resource, method, element_return_none) content = self.get_response(request, self.element_resource, params={"pk": 1}, content_type="text/html") assert not content setattr(self.element_resource, method, element_return_queryset) content = self.get_response(request, self.element_resource, params={"pk": 1}) assert isinstance(content, list) setattr(self.element_resource, method, element_return_modelinstance) content = self.get_response(request, self.element_resource, params={"pk": 1}) assert isinstance(content, dict) assert "Objects" not in content assert "Meta" not in content setattr(self.element_resource, method, element_return_valuesset) content = self.get_response(request, self.element_resource, params={"pk": 1}) assert isinstance(content, list) setattr(self.element_resource, method, element_return_tuple) content = self.get_response( request, self.element_resource, params={"pk": 1}, status=500, content_type="text/html" ) assert isinstance(content, str) def test_list_method(self): def get_response_content(list_function, **kwargs): self.collection_resource.list = list_function return self.get_response(request, self.collection_resource, **kwargs) request = self.factory.get("/books/") content = get_response_content(list_return_list) assert isinstance(content, dict) assert "Objects" in content assert "Meta" in content content = get_response_content(list_return_str, content_type="text/html") assert isinstance(content, str) content = get_response_content(list_return_int, content_type="text/html") assert not content content = get_response_content(list_return_dict) assert isinstance(content, dict) assert "Objects" not in content assert "Meta" not in content content = get_response_content(list_return_none, content_type="text/html") assert not content content = get_response_content(list_return_queryset) assert isinstance(content, dict) assert "Objects" in content assert "Meta" in content content = get_response_content(list_return_modelinstance) assert isinstance(content, dict) assert "Objects" not in content assert "Meta" not in content content = get_response_content(list_return_valuesset) assert isinstance(content, dict) assert "Objects" in content content = get_response_content(list_return_tuple, status=500, content_type="text/html") assert isinstance(content, str) def test_create_method(self): def get_response_content(create_function, **kwargs): self.collection_resource.create = create_function return self.get_response(request, self.collection_resource, **kwargs) request = self.factory.post("/books/") content = get_response_content(create_return_list) assert isinstance(content, list) content = get_response_content(create_return_str, content_type="text/html") assert isinstance(content, str) content = get_response_content(create_return_int, content_type="text/html") assert not content content = get_response_content(create_return_dict) assert isinstance(content, dict) assert "Objects" not in content assert "Meta" not in content content = get_response_content(create_return_none, content_type="text/html") assert not content content = get_response_content(create_return_queryset) assert isinstance(content, list) content = get_response_content(create_return_modelinstance) assert isinstance(content, dict) content = get_response_content(create_return_valuesset) assert isinstance(content, list) content = get_response_content(create_return_tuple, status=500, content_type="text/html") assert isinstance(content, str)
class TestPlaceTagInstanceView (APITestMixin, TestCase): def setUp(self): self.owner = User.objects.create_user(username='******', password='******', email='*****@*****.**') self.submitter = User.objects.create_user(username='******', password='******', email='*****@*****.**') self.dataset = DataSet.objects.create(slug='ds', owner=self.owner) self.place = Place.objects.create( dataset=self.dataset, geometry='POINT(2 3)', submitter=self.submitter, data=json.dumps({ 'type': 'ATM', 'name': 'K-Mart', 'private-secrets': 42 }), ) self.tags = [ Tag.objects.create( name="status", dataset=self.dataset, ), ] self.tags.extend([ Tag.objects.create( name="approved", dataset=self.dataset, parent=self.tags[0] ), Tag.objects.create( name="rejected", dataset=self.dataset, parent=self.tags[0] ) ]) self.place_tag = PlaceTag.objects.create( place=self.place, submitter=self.submitter, tag=self.tags[1], note="I approve this place!" ) self.origin = Origin.objects.create(pattern='def', dataset=self.dataset) Origin.objects.create(pattern='def2', dataset=self.dataset) self.unauthorized_user = User.objects.create_user( username='******', password='******' ) self.authorized_user = User.objects.create_user( username='******', password='******' ) group = Group.objects.create( dataset=self.dataset, name='mygroup' ) group.submitters.add(self.authorized_user) GroupPermission.objects.create( group=group, # TODO: rename this to 'resource': submission_set='tags', can_destroy=True, can_update=True ) unauthorized_group = Group.objects.create( dataset=self.dataset, name='badgroup' ) unauthorized_group.submitters.add(self.unauthorized_user) unauthorized_group.submitters.add(self.authorized_user) GroupPermission.objects.create( group=unauthorized_group, # TODO: rename this to 'resource': submission_set='tags', ) self.request_kwargs = { 'owner_username': self.owner.username, 'dataset_slug': self.dataset.slug, 'place_id': self.place.id, 'place_tag_id': self.place_tag.id } self.factory = RequestFactory() self.path = reverse('place-tag-detail', kwargs=self.request_kwargs) self.view = PlaceTagInstanceView.as_view() cache_buffer.reset() django_cache.clear() def tearDown(self): User.objects.all().delete() DataSet.objects.all().delete() Place.objects.all().delete() # this should delete all of the PlaceTags as well, (via cascade) Tag.objects.all().delete() # this should delete all of the PlaceTags as well, (via cascade) # TODO: ensure that there are no more Tag or PlaceTag 's left # PlaceTag.objects.all().delete() cache_buffer.reset() django_cache.clear() def test_GET_response(self): request = self.factory.get(self.path) response = self.view(request, **self.request_kwargs) data = json.loads(response.rendered_content) # Check that the request was successful self.assertStatusCode(response, 200) # Check that the data attributes have been incorporated into the # properties self.assertEqual(data.get('note'), "I approve this place!") # Check that the appropriate attributes are in the properties self.assertIn('url', data) self.assertIn('submitter', data) self.assertIn('place', data) self.assertIn('tag', data) # Check that the URL is right self.assertEqual( data['url'], 'http://testserver' + reverse('place-tag-detail', args=[ self.owner.username, self.dataset.slug, self.place.id, self.place_tag.id]) ) def test_GET_invalid_url(self): # Make sure that we respond with 404 if a place_id is supplied, but for # the wrong dataset or owner. request_kwargs = { 'owner_username': '******', 'dataset_slug': self.dataset.slug, 'place_id': self.place.id, 'place_tag_id': self.place_tag.id } path = reverse('place-tag-detail', kwargs=request_kwargs) request = self.factory.get(path) response = self.view(request, **request_kwargs) self.assertStatusCode(response, 404) # TODO: implement this when caching is re-enabled: # def test_GET_from_cache(self): # path = reverse('submission-detail', kwargs=self.request_kwargs) # request = self.factory.get(path) # # Check that we make a finite number of queries # # # # ---- Checking data access permissions: # # # # - SELECT requested dataset and owner # # - SELECT dataset permissions # # - SELECT keys # # - SELECT key permissions # # - SELECT origins # # - SELECT origin permissions # # # # ---- Build the data # # # # - SELECT * FROM sa_api_submission AS s # # JOIN sa_api_submittedthing AS st ON (s.submittedthing_ptr_id = st.id) # # JOIN sa_api_dataset AS ds ON (st.dataset_id = ds.id) # # JOIN sa_api_submissionset AS ss ON (s.parent_id = ss.id) # # JOIN sa_api_place AS p ON (ss.place_id = p.submittedthing_ptr_id) # # JOIN sa_api_submittedthing AS pt ON (p.submittedthing_ptr_id = pt.id) # # WHERE st.id = <self.submission.id>; # # # # - SELECT * FROM sa_api_attachment AS a # # WHERE a.thing_id IN (<self.submission.id>); # # # with self.assertNumQueries(13): # response = self.view(request, **self.request_kwargs) # self.assertStatusCode(response, 200) # path = reverse('submission-detail', kwargs=self.request_kwargs) # request = self.factory.get(path) # # Check that this performs no more queries than required for auth, # # since the data's all cached # with self.assertNumQueries(0): # response = self.view(request, **self.request_kwargs) # self.assertStatusCode(response, 200) def test_DELETE_response(self): # # View should 401 when trying to delete when not authenticated # request = self.factory.delete(self.path) response = self.view(request, **self.request_kwargs) self.assertStatusCode(response, 401) # # View should 403 the place when user is unauthorized # request = self.factory.delete(self.path) request.user = self.unauthorized_user response = self.view(request, **self.request_kwargs) self.assertStatusCode(response, 403) # # View should delete the place when owner is authenticated # request = self.factory.delete(self.path) request.user = self.authorized_user response = self.view(request, **self.request_kwargs) # Check that the request was successful self.assertStatusCode(response, 204) # Check that no data was returned self.assertIsNone(response.data) def test_PUT_response(self): submission_data = json.dumps({ 'note': 'Revised comment', }) # TODO: get json from django model, merge with submission data to fix PUT # import ipdb # ipdb.set_trace() # # View should 401 when trying to update when not authenticated # request = self.factory.put(self.path, data=submission_data, content_type='application/json') response = self.view(request, **self.request_kwargs) self.assertStatusCode(response, 401) # # View should 403 when trying to update when not authorized # # user = User.objects.create_user(username='******', # password='******') request = self.factory.put(self.path, data=submission_data, content_type='application/json') request.user = self.unauthorized_user request.META['HTTP_ORIGIN'] = self.origin.pattern response = self.view(request, **self.request_kwargs) self.assertStatusCode(response, 403) # # # # View should 200 when trying to update when authorized # # # request = self.factory.put(self.path, data=submission_data, content_type='application/json') # request.user = self.authorized_user # request.META['HTTP_ORIGIN'] = self.origin.pattern # response = self.view(request, **self.request_kwargs) # self.assertStatusCode(response, 403) def test_PATCH_response(self): submission_data = json.dumps({ 'note': 'Revised comment', }) # # View should update the place when user is authenticated # request = self.factory.patch(self.path, data=submission_data, content_type='application/json') request.user = self.authorized_user request.META['HTTP_ORIGIN'] = self.origin.pattern response = self.view(request, **self.request_kwargs) # # Check that the request was successful self.assertStatusCode(response, 200) data = json.loads(response.rendered_content) # Check that the data attributes have been incorporated into the # properties self.assertEqual(data.get('note'), 'Revised comment')
class BorrowTransactionApiTestCase(TestCase): def setUp(self): # Set up a Request Factory self.factory = RequestFactory() # Make some basic objects to play with. self.parrot = User.create_new_user( "Parrot", "password", "03545", "*****@*****.**", "1234567890", "Pining for the fjords." ) self.penguin = User.create_new_user( 'Penguin', 'password', '03545', '*****@*****.**', '5555551234', 'It\'s on the telly.') self.polarbear = User.create_new_user( 'Polarbear', 'password', '00000', '*****@*****.**', '5555551234', 'Pick it up at the north pole' ) self.nail = Tool.create_new_tool( "Rusty Nail", toolownerID = self.parrot.id, tooldescription = "Holding up a stuffed parrot", tooltype = "nail", toolshed = False, pickup_info = "Rip it out of the cage.", tool_available= True ) self.zilly = Tool.create_new_tool( "Warhammer of Zillyhoo", toolownerID = self.parrot.id, tooldescription = "Its majesty makes you weep.", tooltype = "hammer", toolshed = False, pickup_info = "Some time travel required.", tool_available= True ) self.scraper = Tool.create_new_tool( "Ice Scraper", toolownerID = self.penguin.id, tooldescription = "An ice scraper for your car", tooltype = "ice scraper", toolshed = False, pickup_info = "Pick it up at the south pole.", tool_available= True ) #cutting this out in case we lose points for that dumb runtime warning @unittest.skip def test_requestBorrowTransaction(self): # Penguin borrows nail from parrot jsondata = { 'toolId' : self.nail.id, 'borrower_message' : "i need dis", # NOTE: Python throws a nasty runtime error here because it # can't tell whether the milliseconds are timezone-aware. # Nothing I can do about this, just ignore the warning. 'date' : dt_to_milliseconds(timezone.datetime( year = 3000, month = 4, day = 13, )), } request = self.factory.post( path = '/api/borrowTransaction', data = json.dumps(jsondata), content_type = "application/json", ) request.session = { 'user' : { 'id' : self.penguin.id } } response = api.borrowTransaction(request) #print(response.content) self.assertEqual(response.status_code, 200) """ @unittest.skip # this is not actually required behavior def test_requestBorrowTransaction_differentzones(self): # Polar bear borrows ice scraper from penguin # note that polar bears and penguins do not live in the same # place jsondata = { 'toolId' : self.scraper.id, 'borrower_message' : "i need dis", 'date' : dt_to_milliseconds(timezone.datetime( tzinfo = timezone.UTC, year = 3000, month = 4, day = 13, )), } request = self.factory.post( path = '/api/borrowTransaction', data = json.dumps(jsondata), content_type = "application/json", ) request.session = { 'user' : { 'id' : self.polarbear.id } } response = api.borrowTransaction(request) #print(response.content) self.assertNotEqual(response.status_code, 200) """ @unittest.skip #not ready yet def test_getUnresolvedBorrowTransactions(self): request = self.factory.get( path = '/api/borrowTransaction/requestPending' ) @unittest.skip #not ready yet def test_resolveBorrowRequest(self): request = self.factory.post('/api/borrowTransaction/resolve') @unittest.skip #not ready yet def test_getRejectedRequests(self): request = self.factory.get( path = '/api/borrowTransaction/rejected/:id' ) @unittest.skip #not ready yet def test_requestEndBorrowTransaction(self): request = self.factory.put('/api/borrowTransaction') @unittest.skip #not ready yet def test_getEndBorrowTransactionRequests(self): request = self.factory.get( path = '/api/borrowTransaction/endRequests' ) @unittest.skip #not ready yet def test_resolveEndBorrowTransaction(self): request = self.factory.delete( path = '/api/borrowTransaction/:transactionId' ) @unittest.skip #not ready yet def test_getToolsUserIsBorrowing(self): request = self.factory.put( path = '/api/borrowTransaction/borrowing/:userId' ) @unittest.skip #not ready yet def test_getToolsUserIsLending(self): request = self.factory.get( path = '/api/borrowTransaction/borrowed/:userId' ) @unittest.skip #not ready yet def test_getAllCommunityHistory(self): request = self.factory.get( path = '/api/borrowTransaction/community/:zip' ) @unittest.skip #not ready yet def test_getAllReturnPendingBorrowTransactionsInCommunityShed(self): request = self.factory.get( path = '/api/borrowTransaction/pendingCommunity' )
class ToolApiTestCase(TestCase): def setUp(self): # Set up a Request Factory self.factory = RequestFactory() # Set up a User self.john = User( username='******', hashed_password = '******', salt = 'NaCl', zip_code = '00413', email = '*****@*****.**', phone_number = '1234567890', default_pickup_arrangements = 'Drop in nearest mailbox.', ) self.john.save() # Set up a Tool today = timezone.now() self.sledge = Tool( name = "sledgehammer", owner = self.john, description = "A sturdy sledgehammer.", tool_type = "hammer", tool_pickup_arrangements = "If you can lift it, you can have it.", available_date = today, ) self.sledge.save() # Data for a modified tool self.brokenSledge_info = { "id" : self.sledge.id, "name" : "broken sledgehammer", "description" : "Basically a stick.", "tool_type" : "1/2 hammer", "in_community_shed" : False, "tool_pickup_arrangements" : "Take it off my lawn.", "tool_available" : True, } # Data for a new tool self.needles_info = { "name" : "Knitting Needles", "description" : "for making plush eldrich monstrosities", "tool_type" : "needle", "in_community_shed" : True, "tool_pickup_arrangements" : "Get it from the shed.", "tool_available" : True } # Mock session, where applicable self.mock_session = \ { "user" : \ { "username" : self.john.username, "id" : self.john.id, "zip_code" : self.john.zip_code, } } # Empty session, otherwise self.empty_session = { } def test_getById(self): request = self.factory.get('/api/tool/') request.session = self.mock_session response = get_tool(request, self.sledge.id) # Did we get a clean response? self.assertEqual(response.status_code, 200) # Did we get the right data? # NOTE: Instead of the owner object, we'll be getting back # the owner's username, and instead of a date object, we'll # be getting a datetime in milliseconds. response_data = json.loads(response.content.decode("utf-8")) self.assertEqual(response_data["name"], self.sledge.name) self.assertEqual(response_data["owner"], self.sledge.owner.username, ) self.assertEqual(response_data["description"], self.sledge.description, ) self.assertEqual(response_data["tool_type"], self.sledge.tool_type, ) self.assertEqual(response_data["tool_pickup_arrangements"], self.sledge.tool_pickup_arrangements, ) self.assertEqual(response_data["available_date"], dt_to_milliseconds(self.sledge.available_date), ) def test_createNewTool(self): request = self.factory.post( path = '/api/tool/', data = json.dumps(self.needles_info), content_type = "application/json" ) request.session = self.mock_session response = update(request) response_data = json.loads(response.content.decode("utf-8")) # No way to know the new ID, but here's some stuff it isn't! self.assertIsNotNone(response_data["id"]) self.assertNotEqual(response_data["id"], 0) # Also no way to know the exact time of creation, but all that # we care about right now is that it's in the past. self.assertTrue(response_data["available_date"] - dt_to_milliseconds(timezone.now()) < 0 ) # And now the rest of the validation. self.assertEqual(response_data["name"], self.needles_info["name"]) self.assertEqual(response_data["owner"], self.john.username) self.assertEqual(response_data["description"], self.needles_info["description"]) self.assertEqual(response_data["tool_type"], self.needles_info["tool_type"]) self.assertEqual(response_data["in_community_shed"], self.needles_info["in_community_shed"]) self.assertEqual(response_data["tool_pickup_arrangements"], self.needles_info["tool_pickup_arrangements"]) self.assertTrue(response_data["tool_available"]) def test_updateTool(self): request = self.factory.put( path = '/api/tool', content_type = "application/json", data = json.dumps(self.brokenSledge_info), ) request.session = self.mock_session response = update(request) # Did we get a clean response? # print(response.content) self.assertEqual(response.status_code, 200) response_data = json.loads(response.content.decode("utf-8")) self.assertEqual(response_data["id"], self.sledge.id) self.assertEqual(response_data["name"], self.brokenSledge_info["name"]) self.assertEqual(response_data["owner"], self.john.username) self.assertIsNotNone(response_data["available_date"]) self.assertEqual(response_data["description"], self.brokenSledge_info["description"]) self.assertEqual(response_data["tool_type"], self.brokenSledge_info["tool_type"]) def test_deleteTool_good(self): # sanity check self.assertIn(self.sledge, Tool.objects.all()) # call the delete route request = self.factory.delete('/api/tool') request.session = self.mock_session response = get_tool(request, self.sledge.id) response_data = json.loads(response.content.decode("utf-8")) # is it gone? self.assertTrue(response_data["success"]) self.assertNotIn(self.sledge, Tool.objects.all()) #@unittest.expectedFailure # system doesn't know how to handle nonexistant IDs @unittest.skip #for submitting R2 def test_deleteTool_bad(self): # try to delete a tool twice request = self.factory.delete('/api/tool') request.session = self.mock_session response = get_tool(request, self.sledge.id) #first response = get_tool(request, self.sledge.id) #second response_data = json.loads(response.content.decode("utf-8")) self.assertFalse(response_data["success"]) def test_getLocalTools(self): request = self.factory.get('/api/tools/area') # We need a user to have local tools to browse. request.session = self.mock_session response = local_tools(request) response_data = json.loads(response.content.decode("utf-8")) self.assertIn(tool_to_json(self.sledge), response_data) def test_getPersonalTools(self): request = self.factory.get('/api/tools') # We need a user to have personal tools to browse. request.session = self.mock_session response = user_tools(request) response_data = json.loads(response.content.decode("utf-8")) self.assertIn(tool_to_json(self.sledge), response_data)
class CRUDViewTest(TestCase): names = ['John', 'Anne', 'Chris', 'Beatrice', 'Matt'] emails = ["@".join((name, "example.com")) for name in names] def setUp(self): self.factory = RequestFactory() # DummyModel2 and DummyModel / CRUDTestViewWithFK model2 = DummyModel2(name="Model2 name") model2.save() for name in self.names: DummyModel(name=name, model2=model2).save() # SimpleModel / CRUDTestViewWithSlug for name, email in zip(self.names, self.emails): SimpleModel(name=name, email=email).save() # model with m2m relationship dummy_model2 = DummyModel2(name="Mathilde") dummy_model2.save() self.m2m_model = M2MModel() self.m2m_model.save() self.m2m_model.dummy_models.add(dummy_model2) self.m2m_model.save() def test_get_allowed_methods(self): allowed_methods = CRUDTestView().get_allowed_methods() self.assertEqual(allowed_methods, ['GET', 'POST', 'DELETE']) allowed_methods = CRUDTestViewWithFewAllowedMethod().get_allowed_methods() self.assertEqual(allowed_methods, ['POST']) def test_ng_query(self): # CRUDTestViewWithFK request = self.factory.get('/crud/') response = CRUDTestViewWithFK.as_view()(request) data = json.loads(response.content.decode('utf-8')) for obj in data: db_obj = DummyModel.objects.get(pk=obj['pk']) self.assertEqual(obj['name'], db_obj.name) # CRUDTestViewWithSlug request2 = self.factory.get('/crud/') response2 = CRUDTestViewWithSlug.as_view()(request2) data2 = json.loads(response2.content.decode('utf-8')) for obj in data2: db_obj = SimpleModel.objects.get(email=obj['email']) self.assertEqual(obj['name'], db_obj.name) def test_ng_get(self): # CRUDTestViewWithFK request = self.factory.get('/crud/?pk=1') response = CRUDTestViewWithFK.as_view()(request) data = json.loads(response.content.decode('utf-8')) self.assertEqual(self.names[0], data['name']) # CRUDTestViewWithSlug request2 = self.factory.get('/crud/?email={0}'.format(self.emails[0])) response2 = CRUDTestViewWithSlug.as_view()(request2) data2 = json.loads(response2.content.decode('utf-8')) self.assertEqual(self.names[0], data2['name']) def test_ng_save_create(self): # CRUDTestViewWithFK request = self.factory.post('/crud/', data=json.dumps({'name': 'Leonard'}), content_type='application/json') response = CRUDTestView.as_view()(request) data = json.loads(response.content.decode('utf-8')) pk = data['pk'] request2 = self.factory.get('/crud/?pk={0}'.format(pk)) response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content.decode('utf-8')) self.assertEqual(data2['name'], 'Leonard') # CRUDTestViewWithSlug request3 = self.factory.post('/crud/', data=json.dumps({'name': 'Leonard', 'email': '*****@*****.**'}), content_type='application/json') CRUDTestViewWithSlug.as_view()(request3) request4 = self.factory.get('/crud/?email={0}'.format('*****@*****.**')) response4 = CRUDTestViewWithSlug.as_view()(request4) data4 = json.loads(response4.content.decode('utf-8')) self.assertEqual(data4['name'], 'Leonard') request5 = self.factory.post('/crud/', data=json.dumps({'name': 'Leonard2', 'email': '*****@*****.**'}), content_type='application/json') response5 = CRUDTestViewWithSlug.as_view()(request5) self.assertGreaterEqual(response5.status_code, 400) data5 = json.loads(response5.content.decode('utf-8')) self.assertTrue('detail' in data5 and 'email' in data5['detail'] and len(data5['detail']['email']) > 0) def test_ng_save_update(self): # CRUDTestViewWithFK request = self.factory.post('/crud/?pk=1', data=json.dumps({'pk': 1, 'name': 'John2'}), content_type='application/json') response = CRUDTestView.as_view()(request) data = json.loads(response.content.decode('utf-8')) self.assertEqual(data['name'], 'John2') request2 = self.factory.get('/crud/?pk=1') response2 = CRUDTestView.as_view()(request2) data2 = json.loads(response2.content.decode('utf-8')) self.assertEqual(data2['name'], 'John2') # CRUDTestViewWithSlug request3 = self.factory.post('/crud/?pk=1', data=json.dumps({'name': 'John', 'email': '*****@*****.**'}), content_type='application/json') response3 = CRUDTestViewWithSlug.as_view()(request3) data3 = json.loads(response3.content.decode('utf-8')) self.assertEqual(data3['name'], 'John') self.assertEqual(data3['email'], '*****@*****.**') request4 = self.factory.get('/crud/[email protected]') response4 = CRUDTestViewWithSlug.as_view()(request4) data4 = json.loads(response4.content.decode('utf-8')) self.assertEqual(data4['name'], 'John') request5 = self.factory.post('/crud/?pk=3', # Modifying "Chris" data=json.dumps({'pk': 4, 'name': 'John2', 'email': '*****@*****.**'}), content_type='application/json') response5 = CRUDTestViewWithSlug.as_view()(request5) self.assertGreaterEqual(response5.status_code, 400) data5 = json.loads(response5.content.decode('utf-8')) self.assertTrue('detail' in data5 and 'email' in data5['detail'] and len(data5['detail']['email']) > 0) def test_ng_delete(self): # CRUDTestViewWithFK request = self.factory.delete('/crud/?pk=1') response = CRUDTestViewWithFK.as_view()(request) data = json.loads(response.content.decode('utf-8')) deleted_name = data['name'] request2 = self.factory.get('/crud/') response2 = CRUDTestViewWithFK.as_view()(request2) data2 = json.loads(response2.content.decode('utf-8')) for obj in data2: self.assertTrue(deleted_name != obj['name']) # CRUDTestViewWithSlug delete is not different from CRUDTestViewWithFK only testing error status codes request3 = self.factory.delete('/crud/[email protected]') # Missing pk response3 = CRUDTestViewWithSlug.as_view()(request3) self.assertEqual(response3.status_code, 400) request4 = self.factory.delete('/crud/?pk=100') # Invalid pk response4 = CRUDTestViewWithSlug.as_view()(request4) self.assertEqual(response4.status_code, 404) # Testing with m2m relationship request5 = self.factory.delete('/crud/?pk=%s' % self.m2m_model.pk) response5 = CRUDTestViewWithM2M.as_view()(request5) self.assertEqual(response5.status_code, 200) def test_method_not_supported(self): # CRUDTestViewWithFewAllowedMethod request = self.factory.get('/crud/') response = CRUDTestViewWithFewAllowedMethod.as_view()(request) self.assertEqual(response.status_code, 405) request = self.factory.post('/crud/', data=json.dumps({'name': 'Leonard'}), content_type='application/json') response = CRUDTestViewWithFewAllowedMethod.as_view()(request) self.assertEqual(response.status_code, 200)
class TestBulkAPIMixins(TestCase): lang1 = {'id': 'en-us', 'lang_code': 'en', 'lang_subcode': 'us'} lang2 = {'id': 'fr-fr', 'lang_code': 'fr', 'lang_subcode': 'fr'} def setUp(self): super(TestBulkAPIMixins, self).setUp() self.request = RequestFactory() def test_get(self): """ Test that GET request is successful on bulk create view. """ view = BulkCreateView.as_view({'get': 'list'}) response = view(self.request.get('')) self.assertEqual(response.status_code, status.HTTP_200_OK) def test_post_single(self): """ Test that POST request with single resource only creates a single resource. """ view = BulkCreateView.as_view({'post': 'create'}) response = view(self.request.post( '', json.dumps(self.lang1), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Language.objects.count(), 1) self.assertEqual(Language.objects.get().id, self.lang1['id']) def test_post_bulk(self): """ Test that POST request with multiple resources creates all posted resources. """ view = BulkCreateView.as_view({'post': 'create'}) response = view(self.request.post( '', json.dumps([ self.lang1, self.lang2, ]), content_type='application/json', )) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Language.objects.count(), 2) self.assertEqual(list(Language.objects.all().values_list('id', flat=True)), [ self.lang1['id'], self.lang2['id'], ]) def test_delete_not_filtered(self): """ Test that DELETE is not allowed when results are not filtered. """ view = BulkDeleteView.as_view({'delete': 'bulk_destroy'}) Language.objects.create(**self.lang1) Language.objects.create(**self.lang2) response = view(self.request.delete('')) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_delete_filtered(self): """ Test that DELETE removes all filtered resources. """ view = BulkDeleteView.as_view({'delete': 'bulk_destroy'}) Language.objects.create(**self.lang1) Language.objects.create(**self.lang2) response = view(self.request.delete('?id=' + self.lang1['id'])) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(Language.objects.count(), 1) self.assertEqual(Language.objects.get().id, self.lang2['id'])