class EndpointTest(TestCase): urls = 'api.test_urls' def setUp(self): self.c = Client() def test_routing(self): self.assertEqual(self.c.get('/t1/').status_code, 200) self.assertEqual(self.c.post('/t1/', {1:2}).status_code, 405) self.assertEqual(self.c.delete('/t1/').content, 405) self.assertEqual(self.c.delete('/t1/').status_code, 405) self.assertEqual(self.c.options('/t1/').status_code, 405) self.assertEqual(self.c.patch('/t1/').status_code, 405) def test_echo(self): self.assertEqual(self.c.get('/t2/').content, '{\n "hello": true\n}') self.assertEqual(self.c.get('/t2/').status_code, 200) self.assertEqual(json.loads(self.c.post('/t2/', {1:2}).content), {"1":"2"}) #We see a string conversion here because it's form-encoded. self.assertEqual(json.loads(self.c.post('/t2/', json.dumps({1:2}), content_type='application/json').content), {"1":2}) self.assertEqual(self.c.post('/t2/', {1:2}).status_code, 200) self.assertEqual(self.c.put('/t2/', {1:2}).status_code, 200) self.assertEqual(json.loads(self.c.put('/t2/', {1:2}).content), {"1":"2"}) self.assertEqual(json.loads(self.c.put('/t2/', json.dumps({1:2}), content_type='application/json').content), {"1":2}) self.assertEqual(self.c.get('/t2/entity/').status_code, 200) self.assertEqual(self.c.get('/t2/entity/').content, '"entity"') self.assertEqual(json.loads(self.c.post('/t2/entity/', {1:2}).content), {u'1': u'2', u'id': u'entity'}) self.assertEqual(json.loads(self.c.post('/t2/entity/', json.dumps({1:2}), content_type='application/json').content), {u'1': 2, u'id': u'entity'}) self.assertEqual(self.c.put('/t2/entity/', {1:2}).status_code, 200) self.assertEqual(json.loads(self.c.put('/t2/entity/', {1:2}).content), {u'1': u'2', u'id': u'entity'}) self.assertEqual(json.loads(self.c.put('/t2/entity/', json.dumps({1:2}), content_type='application/json').content), {u'1': 2, u'id': u'entity'}) self.assertEqual(self.c.patch('/t2/entity/', {1:2}).status_code, 200) self.assertEqual(json.loads(self.c.patch('/t2/entity/', {1:2}).content), {u'1': u'2', u'id': u'entity'}) self.assertEqual(json.loads(self.c.patch('/t2/entity/', json.dumps({1:2}), content_type='application/json').content), {u'1': 2, u'id': u'entity'}) def test_middleware(self): #self.assertEqual(json.loads(self.c.post('/t2/', json.dumps({1:2}), content_type='application/json').content), {"1":2}) self.assertEqual(json.loads(self.c.get('/t2/', {'format': 'json'}).content), {u'hello': True}) self.assertEqual(self.c.get('/t2/', {'format': 'jsonp'}).status_code, 500) self.assertEqual(json.loads(self.c.get('/t2/', {'format': 'noformat'}).content), {u'hello': True}) #Falls back to JSON self.assertEqual(json.loads(self.c.get('/t2/', HTTP_ACCEPT='application/json').content), {u'hello': True}) self.assertEqual(json.loads(self.c.get('/t2/', HTTP_ACCEPT='NOTHING/HERE').content), {u'hello': True}) self.assertEqual(json.loads(self.c.get('/t2/', HTTP_ACCEPT='INVALID').content), {u'hello': True}) self.assertEqual(self.c.get('/t2/', {'callback': 'hello'}).content, 'hello({\n "hello": true\n})') #r = self.c.put('/t2/', {1:2}) #print r.content #r = c.post('/api/test/', {'name': 'fred', 'age': 7}) #print r.content #print r.status_code def test_validation(self): print self.c.get('/t3/', {'id': 302}).status_code print self.c.get('/t3/', {'id': 302}).content
def test_user_service_schedule_update( user: User, client_with_token: Client, service_schedules: QuerySet, ): """Should be able to update a user service schedule.""" service_schedules.filter(day_of_week=6).delete() obj = service_schedules.filter(service__professional__user=user).first() service = obj.service service.is_base_schedule = False service.save() start_time = obj.start_time end_time = obj.end_time response = client_with_token.patch( reverse("user-service-schedule-detail", args=[obj.pk]), { "day_of_week": 6, "service": obj.service.pk, }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.day_of_week == 6 assert obj.start_time == start_time assert obj.end_time == end_time assert obj.service.professional.user == user assert obj.modified_by == user
def test_update_app_token(self): """ 更新app_token :return: """ c = Client() c.login(**dict(username='******', password='******')) app_token_dict = dict(app_name='yunwei_new', ticket_sn_prefix='yunweinew', workflow_ids='2') response_content = c.patch('/api/v1.0/accounts/app_token/4', data=json.dumps(app_token_dict), content_type='application/json').content response_content_dict = json.loads( str(response_content, encoding='utf-8')) self.assertEqual(response_content_dict.get('code'), 0) new_response_content = c.get('/api/v1.0/accounts/app_token', content_type='application/json').content response_content_dict = json.loads( str(new_response_content, encoding='utf-8')) result = response_content_dict['data']['value'] for result0 in result: if result0['id'] == 4: self.assertEqual(result0['app_name'], 'yunwei_new') self.assertEqual(result0['ticket_sn_prefix'], 'yunweinew') self.assertEqual(result0['workflow_ids'], '2')
def test_accounts_profile_update(admin: User, admin_client: Client): """Should be able to update the user profile.""" response = admin_client.patch( reverse("profile"), { "first_name": "new_name", "email": "*****@*****.**", "avatar": ("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKBAMAA" "AB/HNKOAAAAGFBMVEXMzMyWlpajo6O3t7fFxcWcnJyxsbG+vr50Rsl6AAAAC" "XBIWXMAAA7EAAAOxAGVKw4bAAAAJklEQVQImWNgwADKDAwsAQyuDAzMAgyMb" "OYMAgyuLApAUhnMRgIANvcCBwsFJwYAAAAASUVORK5CYII=") }, content_type="application/json", ) admin.refresh_from_db() data = response.json() avatar_path = f"avatars/{slugify(ADMIN_EMAIL)}" assert response.status_code == 200 assert response.accepted_media_type == "application/json" assert data["email"] == ADMIN_EMAIL assert data["first_name"] == "new_name" assert admin.first_name == "new_name" assert admin.email == ADMIN_EMAIL assert avatar_path in admin.avatar.name assert admin.avatar_thumbnail is not None admin.avatar.delete()
def api_call(self, method, url, params={}): import json from django.test.client import Client c = Client() if method not in ('get', 'post', 'patch', 'delete', 'put'): return json.loads(dict(code=-1, msg='method is invalid')) if method == 'get': response_content = c.get(url, data=params, **self.headers).content elif method == 'post': response_content = c.post(url, data=json.dumps(params), content_type='application/json', **self.headers).content elif method == 'patch': response_content = c.patch(url, data=json.dumps(params), content_type='application/json', **self.headers).content elif method == 'delete': response_content = c.delete(url, data=json.dumps(params), content_type='application/json', **self.headers).content elif method == 'put': response_content = c.put(url, data=json.dumps(params), content_type='application/json', **self.headers).content response_content_dict = json.loads( str(response_content, encoding='utf-8')) return response_content_dict
def test_user_sent_order_update( user: User, client_with_token: Client, orders: QuerySet, availability_slots: QuerySet, ): """Should be able to update a sent order.""" query = orders.exclude(service__professional__user=user) query.update(client=user) order = query.first() price = order.price slot = availability_slots.filter(service=order.service).last() response = client_with_token.patch( reverse("user-orders-sent-detail", args=[order.pk]), { "note": "new note", "start_datetime": slot.start_datetime.isoformat(), "end_datetime": "", "phone": "+12136210002", }, ) order.refresh_from_db() assert response.status_code == 200 assert order.client == user assert order.price != price assert order.modified_by == user assert order.end_datetime == arrow.get( order.start_datetime).shift(minutes=order.service.duration).datetime
def _patch_answer_response(client: Client, answer_response: quiz_models.AnswerResponse): """ Patch answer response throw client. """ answer_response_id = answer_response.id quiz_id = answer_response.quiz_id url = f'/api/answer_responses/{answer_response_id}/' data = get_test_answer_response_data() data['quiz'] = str(quiz_id) data['answers_to_questions'][0] = { "question": 1, "text": "new answer", "answer_options": [] } data['answers_to_questions'][1] = { "question": 2, "text": "", "answer_options": [2] } response = client.patch(path=url, data=json.dumps(data), content_type='application/json') return response
def test_user_professional_closed_periods_update( user: User, client_with_token: Client, professional_closed_periods: QuerySet, ): """Should be able to update a user professional closed period.""" obj = professional_closed_periods.filter(professional__user=user).first() start = arrow.utcnow().shift(days=10) end = arrow.utcnow().shift(days=12) response = client_with_token.patch( reverse("user-professional-closed-periods-detail", args=[obj.pk]), { "is_enabled": False, "start_datetime": start.isoformat(), "end_datetime": end.isoformat(), "professional": obj.professional.pk, }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.is_enabled is False assert obj.start_datetime == start.datetime assert obj.end_datetime == end.datetime assert obj.professional.user == user assert obj.modified_by == user
def test_footprint_viewset(self): csrf_client = Client(enforce_csrf_checks=True) grp = GroupFactory(permissions=ADD_CHANGE_PERMISSIONS) contributor = UserFactory(group=grp) csrf_client.login(username=contributor.username, password="******") # get a csrf token url = reverse('create-footprint-view') response = csrf_client.get(url) footprint = FootprintFactory() data = {'pk': footprint.id, 'title': 'abcdefg'} content = encode_multipart('BoUnDaRyStRiNg', data) content_type = 'multipart/form-data; boundary=BoUnDaRyStRiNg' url = '/api/footprint/%s/' % footprint.id csrf_header = response.cookies['csrftoken'].value response = csrf_client.patch(url, content, content_type=content_type, HTTP_X_CSRFTOKEN=csrf_header) self.assertEquals(response.status_code, 200) footprint.refresh_from_db() self.assertEquals(footprint.title, 'abcdefg')
def test_user_service_schedule_restricted_entry( admin: User, client_with_token: Client, service_schedules: QuerySet, ): """Should deny access to someone else"s record.""" obj = service_schedules.filter(service__professional__user=admin).first() response = client_with_token.patch( reverse("user-service-schedule-detail", args=[obj.pk])) assert response.status_code == 404
def test_user_review_comment_restricted_entry( admin: User, client_with_token: Client, review_comments: QuerySet, ): """Should deny access to someone else"s record.""" obj = review_comments.filter(user=admin).first() response = client_with_token.patch( reverse("user-review-comments-detail", args=[obj.pk])) assert response.status_code == 404
def test_user_professional_certificate_restricted_entry( admin: User, client_with_token: Client, professional_certificates: QuerySet, ): """Should deny access to someone else"s record.""" obj = professional_certificates.filter(professional__user=admin).first() response = client_with_token.patch( reverse("user-professional-certificates-detail", args=[obj.pk])) assert response.status_code == 404
def test_patching_payment_amount(client: Client, db_payment: Payment): assert db_payment.attributes["amount"] == "100.21" response = client.patch(f"/api/v0/payment/{db_payment.id}/", data={"attributes": { "amount": "100.22" }}, content_type="application/json") assert response.status_code == 200 db_payment.refresh_from_db() assert db_payment.attributes["amount"] == "100.22"
def test_patching_payment_organisation_id(client: Client, db_payment: Payment): assert str( db_payment.organisation_id) == "743d5b63-8e6f-432e-a8fa-c5d8d2ee5fcb" response = client.patch( f"/api/v0/payment/{db_payment.id}/", data={"organisation_id": "143d5b63-8e6f-432e-a8fa-c5d8d2ee5fcd"}, content_type="application/json") assert response.status_code == 200 db_payment.refresh_from_db() assert str( db_payment.organisation_id) == "143d5b63-8e6f-432e-a8fa-c5d8d2ee5fcd"
def test_sent_read_message_update( user: User, client_with_token: Client, messages: QuerySet, ): """Should not update a sent read message.""" obj = messages.filter(sender=user).first() obj.is_read = True obj.save() response = client_with_token.patch( reverse("messages-sent-detail", args=[obj.pk]), { "body": "new body", }, ) obj.refresh_from_db() assert response.status_code == 400
def test_sent_message_update( user: User, client_with_token: Client, messages: QuerySet, ): """Should update a sent message.""" obj = messages.filter(sender=user).first() response = client_with_token.patch( reverse("messages-sent-detail", args=[obj.pk]), { "body": "new body", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.body == "new body" assert obj.modified_by == user
def test_user_service_locations_update( user: User, client_with_token: Client, services: QuerySet, ): """Should be able to update a user professional tag.""" obj = services.filter(professional__user=user).first().locations.first() response = client_with_token.patch( reverse("user-service-locations-detail", args=[obj.pk]), { "max_distance": 0.5, }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.max_distance == Decimal("0.5") assert obj.service.professional.user == user assert obj.modified_by == user
def test_user_settings_update( user: User, client_with_token: Client, user_settings: QuerySet, ): """Should be able to update a user settings.""" obj = user_settings.filter(user=user).first() response = client_with_token.patch( reverse("user-settings-detail", args=[obj.pk]), { "language": "ru", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.language == "ru" assert obj.user == user assert obj.modified_by == user
def test_user_saved_professional_update( user: User, client_with_token: Client, user_saved_professionals: QuerySet, ): """Should be able to update a user saved professional.""" obj = user_saved_professionals.filter(user=user).first() response = client_with_token.patch( reverse("user-saved-professionals-detail", args=[obj.pk]), { "note": "new note", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.note == "new note" assert obj.user == user assert obj.modified_by == user
def test_user_professional_contacts_update( user: User, client_with_token: Client, professional_contacts: QuerySet, ): """Should be able to update a user professional contact.""" obj = professional_contacts.filter(professional__user=user).first() response = client_with_token.patch( reverse("user-professional-contacts-detail", args=[obj.pk]), { "value": "new name", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.value == "new name" assert obj.professional.user == user assert obj.modified_by == user
def test_user_professional_certificate_update( user: User, client_with_token: Client, professional_certificates: QuerySet, ): """Should be able to update a user professional certificates.""" obj = professional_certificates.filter(professional__user=user).first() response = client_with_token.patch( reverse("user-professional-certificates-detail", args=[obj.pk]), { "organization": "new organization", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.organization == "new organization" assert obj.professional.user == user assert obj.modified_by == user
def test_user_professional_location_update( user: User, client_with_token: Client, professional_locations: QuerySet, ): """Should be able to update a user professional location.""" obj = professional_locations.filter(professional__user=user).first() response = client_with_token.patch( reverse("user-professional-locations-detail", args=[obj.pk]), { "address": "new address", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.address == "new address" assert obj.professional.user == user assert obj.modified_by == user
def test_user_service_photos_update( user: User, client_with_token: Client, services: QuerySet, ): """Should be able to update a user service photo.""" obj = services.filter(professional__user=user).first().photos.first() response = client_with_token.patch( reverse("user-service-photos-detail", args=[obj.pk]), { "name": "new name", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.name == "new name" assert obj.service.professional.user == user assert obj.modified_by == user
def test_user_review_comment_update( user: User, client_with_token: Client, review_comments: QuerySet, ): """Should be able to update a user review comment.""" obj = review_comments.filter(user=user).first() response = client_with_token.patch( reverse("user-review-comments-detail", args=[obj.pk]), { "title": "new title", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.title == "new title" assert obj.user == user assert obj.modified_by == user
def test_user_professional_experience_update( user: User, client_with_token: Client, professional_experience: QuerySet, ): """Should be able to update a user professional experience.""" obj = professional_experience.filter(professional__user=user).first() response = client_with_token.patch( reverse("user-professional-experience-detail", args=[obj.pk]), { "company": "new company", "start_date": "2016-11-01", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.company == "new company" assert obj.professional.user == user assert obj.modified_by == user
def test_user_professional_education_update( user: User, client_with_token: Client, professional_educations: QuerySet, ): """Should be able to update a user professional education.""" obj = professional_educations.filter(professional__user=user).first() response = client_with_token.patch( reverse("user-professional-education-detail", args=[obj.pk]), { "university": "new university", "start_date": "2010-10-01", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.university == "new university" assert obj.professional.user == user assert obj.modified_by == user
def test_user_service_tags_update( user: User, client_with_token: Client, services: QuerySet, ): """Should be able to update a user professional tag.""" # pylint: disable=unused-argument obj = ServiceTag.objects.filter(service__professional__user=user).first() response = client_with_token.patch( reverse("user-service-tags-detail", args=[obj.pk]), { "name": "new name", }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.name == "new name" assert obj.service.professional.user == user assert obj.modified_by == user
def test_user_service_prices_update( user: User, client_with_token: Client, services: QuerySet, ): """Should be able to update a user professional tag.""" # pylint: disable=unused-argument obj = services.filter(professional__user=user).first() response = client_with_token.patch( reverse("user-service-prices-detail", args=[obj.price.pk]), { "price": 0.5, }, ) obj.refresh_from_db() assert response.status_code == 200 price = obj.price assert price.price == Money(Decimal("0.5"), USD) assert price.service.professional.user == user assert price.modified_by == user
def test_user_location_update( user: User, client_with_token: Client, user_locations: QuerySet, ): """Should be able to update a user location.""" obj = user_locations.filter(user=user).first() response = client_with_token.patch( reverse("user-locations-detail", args=[obj.pk]), { "address": "new test address", "is_default": True, }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.is_default is True assert obj.address == "new test address" assert obj.user == user assert obj.modified_by == user
def test_user_languages_update( user: User, client_with_token: Client, user_languages: QuerySet, ): """Should be able to update a user language.""" lang = user_languages.filter(user=user).first() response = client_with_token.patch( reverse("user-languages-detail", args=[lang.pk]), { "language": "en", "is_native": True, }, ) lang.refresh_from_db() assert response.status_code == 200 assert lang.is_native is True assert lang.language == "en" assert lang.user == user assert lang.modified_by == user
def test_user_order_reminders_update( user: User, client_with_token: Client, order_reminders: QuerySet, ): """Should be able to update a user order reminder.""" obj: OrderReminder = order_reminders.filter(recipient=user).first() obj.order.client = user obj.order.save() step: int = settings.D8B_REMINDER_INTERVAL response = client_with_token.patch( reverse("user-order-reminders-detail", args=[obj.pk]), { "remind_before": step * 5, }, ) obj.refresh_from_db() assert response.status_code == 200 assert obj.remind_before == step * 5 assert obj.recipient == user assert obj.modified_by == user
def test_user_sent_started_order_update( user: User, client_with_token: Client, orders: QuerySet, ): """Should deny access to someone else"s record.""" query = orders.exclude(service__professional__user=user) query.update(client=user) order = query.first() order.start_datetime = arrow.utcnow().shift(hours=-1).datetime order.end_datetime = None order.save() response = client_with_token.patch( reverse("user-orders-sent-detail", args=[order.pk]), { "note": "new note", "phone": "+12136210002", }, ) assert response.status_code == 400 assert response.json()["error"] == "Updating a started order is forbiden."
def test_model_resources_item(self): c = Client() # Post New Items - Just so we have test data response = c.post( '/test_api/v1/testmodelresource/', data=model_bootstrap, content_type="application/json" ) self.assertEqual(response.status_code, 201) output = json.loads(response.content) self.assertEqual(len(output), 5) # Test Get Item response = c.get( '/test_api/v1/testmodelresource/1/', content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(output['charfield'], "Carver Burks") self.assertEqual(output['intfield'], 40) self.assertEqual(len(output), 12) # Test Put Item response = c.put( '/test_api/v1/testmodelresource/1/?return=object', data=single_item, content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(output['charfield'], "John Nadratowski") self.assertEqual(output['intfield'], 55) self.assertEqual(len(output), 12) # Test Patch Item response = c.patch( '/test_api/v1/testmodelresource/1/?return=object', data=json.dumps({ "datefield": "2000-01-01", "timefield": "00:00:00 +04:00", }), content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(output['datefield'], "2000-01-01") self.assertEqual(output['timefield'], "00:00:00") self.assertEqual(len(output), 12) # Test Delete Item response = c.delete( '/test_api/v1/testmodelresource/1/', content_type="application/json" ) self.assertEqual(response.status_code, 204) response = c.get( '/test_api/v1/testmodelresource/', content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 4)
class OreTestHelpers(): """ The base class for all test cases that rely on a reachable web server during testing. This is need when the backend daemon needs to call back, or if some HTTP redirection target is needed. Mainly provides helper functions for deal with auth stuff. """ def setUpAnonymous(self): ''' If the test case wants to have a anonymous login session, it should call this function in setUp().''' self.c = Client() def setUpLogin(self): ''' If the test case wants to have a functional login session, it should call this function in setUp().''' self.c = Client() self.c.login(username='******', password='******') def get(self, url): return self.c.get(url) def post(self, url, data): return self.c.post(url, data) def getWithAPIKey(self, url): return self.c.get( url, **{'HTTP_AUTHORIZATION': 'ApiKey f1cc367bc09fc95720e6c8a4225ae2b912fff91b'}) def postWithAPIKey(self, url, data, content_type): return self.c.post(url, data, content_type, **{'HTTP_AUTHORIZATION': 'ApiKey f1cc367bc09fc95720e6c8a4225ae2b912fff91b'}) def ajaxGet(self, url): return self.c.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') def ajaxPost(self, url, data, content_type): """ :rtype : django.http.response.HttpResponse """ return self.c.post( url, data, content_type, **{'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}) def ajaxPatch(self, url, data, content_type): """ :rtype : django.http.response.HttpResponse """ return self.c.patch( url, data, content_type, **{'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}) def ajaxDelete(self, url): return self.c.delete(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') def requestJob(self, base_url, graph, kind): """ Helper function for requesting a job. Waits for the result and returns its URL. """ newjob = json.dumps({'kind': kind}) response = self.ajaxPost( base_url + '/graphs/%u/jobs/' % graph, newjob, 'application/json') self.assertNotEqual( response.status_code, 500) # the backend daemon is not started self.assertEqual( response.status_code, 201) # test if we got a created job assert ('Location' in response) # hardcoded host in docker test suite runs parsed = list(urlparse.urlparse(response['Location'])) parsed[1] = "front:8000" jobUrl = urlparse.urlunparse(parsed) code = 202 assert (not jobUrl.endswith('jobs/')) print "Waiting for result from " + jobUrl, while (code == 202): response = self.ajaxGet(jobUrl) code = response.status_code self.assertEqual(response.status_code, 200) assert ('Location' in response) return response
def test_model_resources_list(self): c = Client() # Test Post New Item response = c.post( '/test_api/v1/testmodelresource/', data=single_item, content_type="application/json" ) self.assertEqual(response.status_code, 201) output = json.loads(response.content) self.assertEqual(len(output), 12) # Test Post New Items response = c.post( '/test_api/v1/testmodelresource/', data=model_bootstrap, content_type="application/json" ) self.assertEqual(response.status_code, 201) output = json.loads(response.content) self.assertEqual(len(output), 5) # Test Get Items response = c.get( '/test_api/v1/testmodelresource/', content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 6) # Test Get Items w/ filter response = c.get( '/test_api/v1/testmodelresource/', data={'filter': json.dumps({'decimalfield__gt': 2000})}, content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 3) # Test Get Items w/ filter returning count response = c.get( '/test_api/v1/testmodelresource/', data={'filter': json.dumps({'decimalfield__gt': 2000}), 'return': 'count'}, content_type="application/json" ) self.assertEqual(response.status_code, 200) self.assertEqual(int(response.content), 3) # Test Get Items w/ exclude response = c.get( '/test_api/v1/testmodelresource/', data={'exclude': json.dumps({'decimalfield__gt': 2000})}, content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 3) # Test Get Items w/ filter & values response = c.get( '/test_api/v1/testmodelresource/', data={'filter': json.dumps({'decimalfield__gt': 2000}), 'values': json.dumps(['fkfield', 'charfield']) }, content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 3) for i in range(len(output)): item = output[i] self.assertEqual(len(item), 2) self.assertIn('fkfield', item) self.assertIn('charfield', item) # Test Get Items w/ all response = c.get( '/test_api/v1/testmodelresource/', data={'filter': json.dumps({'decimalfield__gt': 2000}), 'exclude': json.dumps({'charfield__contains': 'Murray'}), 'values': json.dumps(['id', 'fkfield', 'charfield']), 'order_by': json.dumps(['-id']) }, content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 2) self.assertEqual(output[0]['id'], 4) self.assertEqual(output[1]['id'], 2) # Test Patch Items response = c.patch( '/test_api/v1/testmodelresource/?return=objects', data=json.dumps({ "datefield": "2000-01-01", "timefield": "00:00:00 +04:00", }), content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 6) for i in range(5): self.assertEqual(output[i]['datefield'], "2000-01-01") self.assertEqual(output[i]['timefield'], "00:00:00") # Test Patch Items Filtered/count return response = c.patch( '/test_api/v1/testmodelresource/?filter=' + json.dumps({'decimalfield__gt': 2000}), data=json.dumps({"fkfield": "20"}), content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(output, 3) # Test Delete Items response = c.delete( '/test_api/v1/testmodelresource/', data={'filter': json.dumps({'decimalfield__lt': 2000}), 'return': 'count'}, content_type="application/json" ) self.assertEqual(response.status_code, 200) self.assertEqual(int(response.content), 3) # Test Delete Items (no match) & objects response = c.delete( '/test_api/v1/testmodelresource/', data={'filter': json.dumps({'decimalfield__lt': 2000}), 'return': 'objects'}, content_type="application/json" ) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 0) # Test Delete All Items & no response content response = c.delete( '/test_api/v1/testmodelresource/', content_type="application/json" ) self.assertEqual(response.status_code, 204) self.assertEqual(response.content, '')
class CreateReadUpdateDeleteSurveyDraftsTests(TestCase): def setUp(self): test_user_credentials = {"username": "******", "password": "******"} if User.objects.count() is 0: new_user = User(username=test_user_credentials["username"], email="*****@*****.**") new_user.set_password(test_user_credentials["password"]) new_user.save() self.anonymousClient = Client() self.user = User.objects.all()[0] self.client = Client() self.client.post("/accounts/login/", test_user_credentials) def post_survey(self, client, survey={}): survey_dict = {u"name": "Test Form", u"body": "body", u"description": "description"} survey_dict.update(survey) return self.client.post("/api/survey_drafts", json.dumps(survey_dict), content_type="application/json") def post_asset(self, client, survey={}): survey_dict = {u"name": "Test Form", u"body": "body", u"asset_type": "question"} survey_dict.update(survey) return self.client.post("/api/library_assets", json.dumps(survey_dict), content_type="application/json") def test_anonymous_list(self): resp = self.anonymousClient.get("/api/survey_drafts") self.assertEqual(resp.status_code, 403) def test_empty_list(self): resp = self.client.get("/api/survey_drafts") self.assertEqual(resp.status_code, 200) self.assertEqual(len(resp.data), 0) self.post_survey(self.client) resp2 = self.client.get("/api/survey_drafts") self.assertEqual(len(resp2.data), 1) def test_retrieve_survey(self): self.post_survey(self.client) resp = self.client.get("/api/survey_drafts") self.assertEqual(resp.status_code, 200) self.assertEqual(resp.data[0]["id"], 1) resp = self.client.get("/api/survey_drafts/1") self.assertEqual(resp.data.get("id"), 1) def test_patch_survey(self): def make_body(question_label): return """survey,,,\n,type,name,label\n,text,q1,%s""" % question_label self.post_survey(self.client, {u"body": make_body("Question1")}) resp = self.client.get("/api/survey_drafts") self.assertEqual(resp.data[0]["id"], 1) resp2 = self.client.patch( "/api/survey_drafts/1", json.dumps({u"body": make_body("Question2")}), content_type="application/json" ) self.assertEqual(SurveyDraft.objects.get(id=1).body, make_body("Question2")) def test_library_assets(self): # post a library_asset (question) resp = self.client.get("/api/library_assets") self.assertEqual(resp.status_code, 200) self.assertEqual(len(resp.data.get("results")), 0) # ensure library_assets was incremented self.post_survey(self.client, {u"asset_type": "question"}) resp = self.client.get("/api/library_assets") self.assertEqual(resp.status_code, 200) self.assertEqual(len(resp.data.get("results")), 1) # ensure that survey_drafts was not incremented resp = self.client.get("/api/survey_drafts") self.assertEqual(resp.status_code, 200) self.assertEqual(len(resp.data), 0) def test_patch_asset(self): def make_body(question_label): return """survey,,,\n,type,name,label\n,text,q1,%s""" % question_label self.post_asset(self.client, {u"body": make_body("Question1")}) resp = self.client.get("/api/library_assets") self.assertEqual(resp.data.get("results")[0]["id"], 1) resp2 = self.client.patch( "/api/library_assets/1", json.dumps({u"body": make_body("Question2"), u"asset_type": "question"}), content_type="application/json", ) self.assertEqual(SurveyDraft.objects.get(id=1).body, make_body("Question2")) def test_library_assets_get_loaded_in_correct_order(self): def make_body(question_label): return """survey,,,\n,type,name,label\n,text,q1,%s""" % question_label self.post_asset(self.client, {u"body": make_body("Question1"), u"asset_type": "question"}) self.post_asset(self.client, {u"body": make_body("Question2"), u"asset_type": "question"}) self.post_asset(self.client, {u"body": make_body("Question3"), u"asset_type": "question"}) resp = self.client.get("/api/library_assets") self.assertEqual(resp.status_code, 200) self.assertEqual(len(resp.data.get("results")), 3) self.assertEqual(resp.data.get("results")[0].get("body"), make_body("Question3")) self.assertEqual(resp.data.get("results")[1].get("body"), make_body("Question2")) self.assertEqual(resp.data.get("results")[2].get("body"), make_body("Question1"))
class UsersApiIntegrationTest(TestCase): def setUp(self): self.admin1 = DjangoUser.objects.create( username='******', is_staff=True, is_superuser=True) self.admin1.set_password('admin1') self.admin1.save() self.admin2 = DjangoUser.objects.create( username='******', is_staff=True, is_superuser=True) self.admin2.set_password('admin2') self.admin2.save() self.unauth_client = Client() self.admin1_client = Client() self.admin1_client.login(username='******', password='******') self.admin2_client = Client() self.admin2_client.login(username='******', password='******') self.users_url = '/api/1.0/users/' def test_get_users(self): user1 = User.objects.create( first_name='user1 first', last_name='user1 last', iban='DE89370400440532013000', creator=self.admin1) user2 = User.objects.create( first_name='user2 first', last_name='user2 last', iban='BE68539007547034', creator=self.admin2) self.assertEquals( self.unauth_client.get(self.users_url).status_code, 403) response = self.admin1_client.get(self.users_url) self.assertEquals(response.status_code, 200) self.assertEquals(response.json()['count'], 2) self.assertEquals(response.json()['results'], [ {'iban': 'DE89370400440532013000', 'last_name': 'user1 last', 'id': user1.id, 'first_name': 'user1 first', 'creator': {'username': '******', 'id': self.admin1.id}}, {'iban': 'BE68539007547034', 'last_name': 'user2 last', 'id': user2.id, 'first_name': 'user2 first', 'creator': {'username': '******', 'id': self.admin2.id}}],) self.assertEquals( self.admin2_client.get(self.users_url).content, response.content) def test_post_users(self): valid_user_data = { 'first_name': 'Some', 'last_name': 'Other', 'iban': 'BE68539007547034'} invalid_iban_user_data = { 'first_name': 'Some', 'last_name': 'Other', 'iban': 'BE68539007547022'} too_long_name_user_data = { 'first_name': '1' * 101, 'last_name': 'Other', 'iban': 'BE68539007547034'} missed_field_user_data = { 'first_name': 'Some', 'iban': 'BE68539007547034'} self.assertEquals( self.unauth_client.post( self.users_url, valid_user_data).status_code, 403) response = self.admin1_client.post(self.users_url, valid_user_data) self.assertEquals(response.status_code, 201) data = response.json() self.assertEquals(data['first_name'], 'Some') self.assertEquals(data['last_name'], 'Other') self.assertEquals(data['iban'], 'BE68539007547034') self.assertEquals(data['creator']['username'], 'admin1') response = self.admin2_client.post(self.users_url, valid_user_data) self.assertEquals(response.status_code, 201) data = response.json() self.assertEquals(data['first_name'], 'Some') self.assertEquals(data['last_name'], 'Other') self.assertEquals(data['iban'], 'BE68539007547034') self.assertEquals(data['creator']['username'], 'admin2') response = self.admin1_client.post( self.users_url, invalid_iban_user_data) self.assertEquals(response.status_code, 400) self.assertEquals( response.json(), {'iban': ['Not a valid IBAN.']}) response = self.admin1_client.post( self.users_url, too_long_name_user_data) self.assertEquals(response.status_code, 400) self.assertEquals( response.json(), {'first_name': ['Ensure this field has no more than 100 characters.']}) response = self.admin1_client.post( self.users_url, missed_field_user_data) self.assertEquals(response.status_code, 400) self.assertEquals( response.json(), {'last_name': ['This field is required.']}) def test_delete_user(self): user = User.objects.create( first_name='user1 first', last_name='user1 last', iban='DE89370400440532013000', creator=self.admin1) user_url = '{}{}/'.format(self.users_url, user.id) self.assertEquals( self.unauth_client.delete(user_url).status_code, 403) self.assertEquals( self.admin2_client.delete(user_url).status_code, 403) response = self.admin1_client.delete(user_url) self.assertEquals(response.status_code, 204) def test_patch_user(self): user = User.objects.create( first_name='user1 first', last_name='user1 last', iban='DE89370400440532013000', creator=self.admin1) valid_data = { 'first_name': 'Other name', 'last_name': 'New name', 'iban': 'BE68539007547034'} invalid_iban_user_data = { 'first_name': 'Some', 'last_name': 'Other', 'iban': 'BE68539007547022'} too_long_name_user_data = { 'first_name': '1' * 101, 'last_name': 'Other', 'iban': 'BE68539007547034'} data_with_read_only_fields = { 'first_name': 'Other name', 'last_name': 'New name', 'iban': 'BE68539007547034', 'creator': {'id': self.admin2.id, 'username': '******'}} user_url = '{}{}/'.format(self.users_url, user.id) self.assertEquals( self.unauth_client.patch(user_url, valid_data).status_code, 403) self.assertEquals( self.admin2_client.patch(user_url, valid_data).status_code, 403) response = self.admin1_client.patch( user_url, json.dumps(invalid_iban_user_data), content_type='application/json') self.assertEquals(response.status_code, 400) self.assertEquals( response.json(), {'iban': ['Not a valid IBAN.']}) response = self.admin1_client.patch( user_url, json.dumps(too_long_name_user_data), content_type='application/json') self.assertEquals(response.status_code, 400) self.assertEquals( response.json(), {'first_name': ['Ensure this field has no more than 100 characters.']}) response = self.admin1_client.patch( user_url, json.dumps(data_with_read_only_fields), content_type='application/json') self.assertEquals(response.status_code, 200) self.assertEquals( response.json(), {'creator': {'username': '******', 'id': self.admin1.id}, 'last_name': 'New name', 'iban': 'BE68539007547034', 'id': 4, 'first_name': 'Other name'})
class TestApiClient(object): def __init__(self, serializer=None): """ Sets up a fresh ``TestApiClient`` instance. If you are employing a custom serializer, you can pass the class to the ``serializer=`` kwarg. """ self.client = Client() self.serializer = serializer if not self.serializer: self.serializer = Serializer() def set_request_session(self, session_values): """ Set a given key/value pair in the session for this client """ if type(session_values) == dict: session = self.client.session for key,value in session_values.items(): session[key] = value session.save() def get_content_type(self, short_format): """ Given a short name (such as ``json`` or ``xml``), returns the full content-type for it (``application/json`` or ``application/xml`` in this case). """ return self.serializer.content_types.get(short_format, 'json') def get(self, uri, format='json', data=None, authentication=None, session=None, **kwargs): """ Performs a simulated ``GET`` request to the provided URI. Optionally accepts a ``data`` kwarg, which in the case of ``GET``, lets you send along ``GET`` parameters. This is useful when testing filtering or other things that read off the ``GET`` params. Example:: from tastypie.test import TestApiClient client = TestApiClient() response = client.get('/api/v1/entry/1/', data={ 'format': 'json', 'title__startswith': 'a', 'limit': 20, 'offset': 60 }) Optionally accepts an ``authentication`` kwarg, which should be an HTTP header with the correct authentication data already setup. All other ``**kwargs`` passed in get passed through to the Django ``TestClient``. See https://docs.djangoproject.com/en/dev/topics/testing/#module-django.test.client for details. """ content_type = self.get_content_type(format) kwargs['HTTP_ACCEPT'] = content_type self.set_request_session(session) # GET & DELETE are the only times we don't serialize the data. if data is not None: kwargs['data'] = data if authentication is not None: kwargs['HTTP_AUTHORIZATION'] = authentication return self.client.get(uri, **kwargs) def post(self, uri, format='json', data=None, authentication=None, session=None, **kwargs): """ Performs a simulated ``POST`` request to the provided URI. Optionally accepts a ``data`` kwarg. **Unlike** ``GET``, in ``POST`` the ``data`` gets serialized & sent as the body instead of becoming part of the URI. Example:: from tastypie.test import TestApiClient client = TestApiClient() response = client.post('/api/v1/entry/', data={ 'created': '2012-05-01T20:02:36', 'slug': 'another-post', 'title': 'Another Post', 'user': '******', }) Optionally accepts an ``authentication`` kwarg, which should be an HTTP header with the correct authentication data already setup. All other ``**kwargs`` passed in get passed through to the Django ``TestClient``. See https://docs.djangoproject.com/en/dev/topics/testing/#module-django.test.client for details. """ content_type = self.get_content_type(format) kwargs['content_type'] = content_type self.set_request_session(session) if data is not None: kwargs['data'] = self.serializer.serialize( data, format=content_type) if authentication is not None: kwargs['HTTP_AUTHORIZATION'] = authentication return self.client.post(uri, **kwargs) def put(self, uri, format='json', data=None, authentication=None, session=None, **kwargs): """ Performs a simulated ``PUT`` request to the provided URI. Optionally accepts a ``data`` kwarg. **Unlike** ``GET``, in ``PUT`` the ``data`` gets serialized & sent as the body instead of becoming part of the URI. Example:: from tastypie.test import TestApiClient client = TestApiClient() response = client.put('/api/v1/entry/1/', data={ 'created': '2012-05-01T20:02:36', 'slug': 'another-post', 'title': 'Another Post', 'user': '******', }) Optionally accepts an ``authentication`` kwarg, which should be an HTTP header with the correct authentication data already setup. All other ``**kwargs`` passed in get passed through to the Django ``TestClient``. See https://docs.djangoproject.com/en/dev/topics/testing/#module-django.test.client for details. """ content_type = self.get_content_type(format) kwargs['content_type'] = content_type self.set_request_session(session) if data is not None: kwargs['data'] = self.serializer.serialize( data, format=content_type) if authentication is not None: kwargs['HTTP_AUTHORIZATION'] = authentication return self.client.put(uri, **kwargs) def patch(self, uri, format='json', data=None, authentication=None, session=None, **kwargs): """ Performs a simulated ``PATCH`` request to the provided URI. Optionally accepts a ``data`` kwarg. **Unlike** ``GET``, in ``PATCH`` the ``data`` gets serialized & sent as the body instead of becoming part of the URI. Example:: from tastypie.test import TestApiClient client = TestApiClient() response = client.patch('/api/v1/entry/1/', data={ 'created': '2012-05-01T20:02:36', 'slug': 'another-post', 'title': 'Another Post', 'user': '******', }) Optionally accepts an ``authentication`` kwarg, which should be an HTTP header with the correct authentication data already setup. All other ``**kwargs`` passed in get passed through to the Django ``TestClient``. See https://docs.djangoproject.com/en/dev/topics/testing/#module-django.test.client for details. """ content_type = self.get_content_type(format) kwargs['content_type'] = content_type self.set_request_session(session) if data is not None: kwargs['data'] = self.serializer.serialize( data, format=content_type) if authentication is not None: kwargs['HTTP_AUTHORIZATION'] = authentication return self.client.patch(uri, **kwargs) def delete(self, uri, format='json', data=None, authentication=None, session=None, **kwargs): """ Performs a simulated ``DELETE`` request to the provided URI. Optionally accepts a ``data`` kwarg, which in the case of ``DELETE``, lets you send along ``DELETE`` parameters. This is useful when testing filtering or other things that read off the ``DELETE`` params. Example:: from tastypie.test import TestApiClient client = TestApiClient() response = client.delete('/api/v1/entry/1/', data={'format': 'json'}) Optionally accepts an ``authentication`` kwarg, which should be an HTTP header with the correct authentication data already setup. All other ``**kwargs`` passed in get passed through to the Django ``TestClient``. See https://docs.djangoproject.com/en/dev/topics/testing/#module-django.test.client for details. """ content_type = self.get_content_type(format) kwargs['content_type'] = content_type self.set_request_session(session) # GET & DELETE are the only times we don't serialize the data. if data is not None: kwargs['data'] = data if authentication is not None: kwargs['HTTP_AUTHORIZATION'] = authentication return self.client.delete(uri, **kwargs)