def test_endpoints(client: Client, url: str, reverse_name: str) -> None: """Тестирование доступности точек API""" resp = client.options(url) # При получении ошибки 401 тоже считаем, что endpoint существует, но требует авторизации assert resp.status_code in [ status.HTTP_200_OK, status.HTTP_401_UNAUTHORIZED ] resp = client.options(reverse(reverse_name)) assert resp.status_code in [200, 401]
def test_django(): os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_test.settings") sys.path.append( os.path.join( os.path.abspath(os.path.dirname(__file__)), 'django_test_env' ) ) from django.test.utils import setup_test_environment setup_test_environment() from django.test.client import Client from werobot.parser import parse_xml, process_message import django django.setup() client = Client() token = 'TestDjango' timestamp = str(time.time()) nonce = str(random.randint(0, 10000)) signature = get_signature(token, timestamp, nonce) echostr = generate_token() response = client.get( '/robot/', { 'signature': signature, 'timestamp': timestamp, 'nonce': nonce, 'echostr': echostr } ) assert response.status_code == 200 assert response.content.decode('utf-8') == echostr xml = """ <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[this is a test]]></Content> <MsgId>1234567890123456</MsgId> </xml>""" params = "?timestamp=%s&nonce=%s&signature=%s" % \ (timestamp, nonce, signature) url = '/robot/' response = client.post(url, data=xml, content_type="text/xml") assert response.status_code == 403 assert response.content.decode('utf-8') == u'喵' url += params response = client.post(url, data=xml, content_type="text/xml") assert response.status_code == 200 response = process_message(parse_xml(response.content)) assert response.content == 'hello' response = client.options(url) assert response.status_code == 405
class Tests(unittest.TestCase): def setUp(self): self.client = Client() def test_default_headers(self): # CORS is disabled by default, but headers will be present r = self.client.get("/") self.assertEqual(r['Access-Control-Allow-Origin'], '') self.assertEqual(r['Access-Control-Allow-Methods'], '') self.assertEqual(r['Access-Control-Allow-Headers'], '') self.assertEqual(r['Access-Control-Allow-Credentials'], "false") self.assertEqual(r['Access-Control-Expose-Headers'], '') self.assertEqual(r['Access-Control-Max-Age'], '0') r = self.client.options("/") self.assertEqual(r['Access-Control-Allow-Origin'], '') self.assertEqual(r['Access-Control-Allow-Methods'], '') self.assertEqual(r['Access-Control-Allow-Headers'], '') self.assertEqual(r['Access-Control-Allow-Credentials'], "false") self.assertEqual(r['Access-Control-Expose-Headers'], '') self.assertEqual(r['Access-Control-Max-Age'], '0') @override_settings(CORS_ALLOW_ORIGIN="http://www.example.com", CORS_ALLOW_METHODS=["get", "post"]) def test_preflight(self): # Pre-flight OPTIONS request r = self.client.options("/") self.assertEqual(r['Access-Control-Allow-Origin'], 'http://www.example.com') self.assertEqual(r['Access-Control-Allow-Methods'], 'get,post') self.assertEqual(r['Access-Control-Allow-Headers'], '') self.assertEqual(r['Access-Control-Allow-Credentials'], "false") self.assertEqual(r['Access-Control-Expose-Headers'], '') self.assertEqual(r['Access-Control-Max-Age'], '0') @override_settings(CORS_ALLOW_ORIGIN="*", CORS_ALLOW_CREDENTIALS="true", CORS_ALLOW_ALL_ORIGIN=True) def test_crendentials_and_origin(self): r = self.client.get("/", HTTP_ORIGIN="http://www.example.com") self.assertEqual(r['Access-Control-Allow-Origin'], 'http://www.example.com') self.assertEqual(r['Access-Control-Allow-Methods'], '') self.assertEqual(r['Access-Control-Allow-Headers'], '') self.assertEqual(r['Access-Control-Allow-Credentials'], "true") self.assertEqual(r['Access-Control-Expose-Headers'], '') self.assertEqual(r['Access-Control-Max-Age'], '0')
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
class ResolverTestCase(TestCase): fixtures = [ 'test_uriregister.json', 'test_rewriterule.json', 'test_mediatype.json', 'test_acceptmapping.json' ] def setUp(self): self.c = Client() self.basePath = '/def' # this needs to be configured depending on how you've set up URL structure in your Django project def test_resolve_uri_invalid_HTTP_method(self): result = self.c.post(self.basePath + "something/sent/to/resolver") self.assertEqual(result.status_code, 405, 'Resolver.resolve_uri did not return a 405 error when receiving a POST') result = self.c.head(self.basePath + "something/sent/to/resolver") self.assertEqual(result.status_code, 405, 'Resolver.resolve_uri did not return a 405 error when receiving a HEAD') result = self.c.put(self.basePath + "something/sent/to/resolver") self.assertEqual(result.status_code, 405, 'Resolver.resolve_uri did not return a 405 error when receiving a PUT') result = self.c.delete(self.basePath + "something/sent/to/resolver") self.assertEqual(result.status_code, 405, 'Resolver.resolve_uri did not return a 405 error when receiving a DELETE') result = self.c.options(self.basePath + "something/sent/to/resolver") self.assertEqual(result.status_code, 405, 'Resolver.resolve_uri did not return a 405 error when receiving a OPTIONS') def test_resolve_uri_register_does_not_exist(self): result = self.c.get(self.basePath + "something/sent/to/resolver") self.assertEqual(result.status_code, 404, 'Resolver.resolve_uri did not return a 404 error when receiving a request for an unknown URI register') def test_resolve_uri_register_is_remote(self): result = self.c.get(self.basePath + "another-registry/to/resolver") self.assertEqual(result.status_code, 301, 'Resolver.resolve_uri did not return a 301 redirection when receiving a request for a remote URI register') def test_resolve_uri_no_matching_rules(self): result = self.c.get(self.basePath + "uri-gin/something/sent/to/resolver") self.assertEqual(result.status_code, 404, 'Resolver.resolve_uri did not return a 404 error when receiving a request for an unknown URI register') def test_resolve_uri_multiple_matching_rules(self): result = self.c.get(self.basePath + "uri-gin/this/is/a/duplicate/rule") self.assertEqual(result.status_code, 500, 'Resolver.resolve_uri did not return a 500 error when receiving a request matching multiple rules') def test_resolve_uri_no_acceptable_content(self): result = self.c.get(self.basePath + "uri-gin/something/twomappings", **{ "HTTP_ACCEPT": 'text/javascript' }) self.assertEqual(result.status_code, 406, 'Resolver.resolve_uri did not return a 406 error when receiving a request with no acceptable response') def test_resolve_uri_multiple_acceptable_content(self): result = self.c.get(self.basePath + "uri-gin/duplicate/accept/mappings/here", **{ "HTTP_ACCEPT": 'text/html' }) self.assertEqual(result.status_code, 500, 'Resolver.resolve_uri did not return a 500 error when receiving a request with multiple acceptable responses') def test_resolve_uri_success_one_group_one_mapping(self): result = self.c.get(self.basePath + "uri-gin/something/onegroup/onemapping/success", **{ "HTTP_ACCEPT": 'text/html' }) self.assertEqual(result['Location'], 'http://elsewhere.com/something', 'Resolver.resolve_uri did not return a 303 redirection to the appropriate location') def test_resolve_uri_success_one_group_two_mappings(self): result = self.c.get(self.basePath + "uri-gin/something/onegroup/twomappings/success", **{ "HTTP_ACCEPT": 'text/html' }) self.assertEqual(result['Location'], 'http://elsewhere.com/something', 'Resolver.resolve_uri did not return a 303 redirection to the appropriate location') def test_resolve_uri_success_two_groups_one_mapping(self): result = self.c.get(self.basePath + "uri-gin/first/twogroups/second/onemapping/success", **{ "HTTP_ACCEPT": 'text/html' }) self.assertEqual(result['Location'], 'http://elsewhere.com/first--second', 'Resolver.resolve_uri did not return a 303 redirection to the appropriate location') def test_resolve_uri_success_two_groups_two_mappings(self): result = self.c.get(self.basePath + "uri-gin/first/twogroups/second/twomappings/success", **{ "HTTP_ACCEPT": 'text/html' }) self.assertEqual(result['Location'], 'http://elsewhere.com/first--second', 'Resolver.resolve_uri did not return a 303 redirection to the appropriate location') def test_resolve_uri_success_extensions(self): result = self.c.get(self.basePath + "uri-gin/first/twogroups/second/twomappings/success.txt") self.assertEqual(result['Location'], 'http://fileextension.com/text.txt', 'Resolver.resolve_uri did not return a 303 redirection to the appropriate location when given a file extension')
class TestAuthentication(TestCase): def setUp(self): self.user = self.__create_test_user("user", "pass", True) self.client = Client() def tearDown(self): self.user.delete() def __create_test_user(self, username, password, is_admin=False): user = User.objects.create_user(username=username, password=password) user.is_staff = True user.is_superuser = is_admin user.save() return user def test_options_crossdomain_request(self): """ Browser sends OPTIONS request before crossdomain request. """ URLS = ( "/admin-api/login/", "/admin-api/logout/", "/admin-api/validate-api-key/", ) for url in URLS: response = self.client.options(url) tools.assert_equals(response.status_code, 200) def test_only_post_requests_allowed(self): """ Only POST requests are allowed for API views. Browser sends OPTIONS request before crossdomain request so this method is also allowed but returns only headers. """ URLS = ( "/admin-api/login/", "/admin-api/logout/", "/admin-api/validate-api-key/", ) for url in URLS: response = self.client.get(url) tools.assert_equals(response.status_code, 405) tools.assert_true(response.has_header("Allow")) tools.assert_equals(response["Allow"], "OPTIONS, POST") def test_unauthorized_when_not_login(self): """ Return "401 Unauthorized" header to anonymous user. """ response = self.client.get("/admin-api/article/") tools.assert_equals(response.status_code, 401) def test_unauthorized_in_wrong_format(self): api_key = self.__login("user", "pass") headers = {"HTTP_AUTHORIZATION": "ApiHey %s:%s" % ("user", api_key)} response = self.client.get("/admin-api/article/", **headers) tools.assert_equals(response.status_code, 401) response = self.client.post("/admin-api/logout/", **headers) tools.assert_equals(response.status_code, 401) def test_unauthorized_for_wrong_api_key(self): api_key = self.__login("user", "pass") TEST_CASES = ( # username, API key ("use", api_key), # wrong username ("user", api_key[:-1]), # wrong API key ("pepek", "spinach"), # wrong username and API key ) for username, api_key in TEST_CASES: headers = self.__build_headers(username, api_key) response = self.client.post("/admin-api/logout/", **headers) tools.assert_equals(response.status_code, 401) def test_missing_authorization_header(self): """ Return "401 Unauthorized" if header with API key is missing. """ response = self.client.post("/admin-api/logout/") tools.assert_equals(response.status_code, 401) def test_missing_api_key_for_user(self): user = self.__create_test_user("api_key", "secret") ApiKey.objects.get(user=user).delete() api_key = self.__login("api_key", "secret") headers = self.__build_headers("api_key", api_key) self.__logout(headers) def test_api_key_validity(self): """ Return information about API key expiration validity. """ TEST_CASES = ( # username, API key modifier, expected validity ("user", lambda k: k, True), ("use", lambda k: k, False), # wrong username ("user", lambda k: k[:-1], False), # wrong API key ("use", lambda k: k[:-1], False), # wrong username and API key ) for username, api_key_modifier, expected in TEST_CASES: api_key = api_key_modifier(self.__login("user", "pass")) headers = self.__build_headers(username, api_key) response = self.client.post('/admin-api/validate-api-key/', **headers) resources = self.__get_response_json(response) tools.assert_true("api_key_validity" in resources) tools.assert_equals(resources["api_key_validity"], expected, "Header pair %s:%s" % (username, api_key)) self.__logout(headers, 302 if expected else 401) def test_api_key_expiration(self): api_key = self.__login("user", "pass") headers = self.__build_headers("user", api_key) response = self.client.get("/admin-api/article/", **headers) tools.assert_equals(response.status_code, 200) api_key = ApiKey.objects.get(user=self.user) api_key.created = api_key.created - datetime.timedelta( days=conf.API_KEY_EXPIRATION_IN_DAYS) api_key.save() response = self.client.get("/admin-api/article/", **headers) tools.assert_equals(response.status_code, 401) self.__logout(headers, 401) def test_api_key_refresh_expiration(self): api_key = self.__login("user", "pass") headers = self.__build_headers("user", api_key) response = self.client.get("/admin-api/article/", **headers) tools.assert_equals(response.status_code, 200) api_key = ApiKey.objects.get(user=self.user) api_key.created = api_key.created - datetime.timedelta( days=conf.API_KEY_EXPIRATION_IN_DAYS) api_key.save() api_key = self.__login("user", "pass") headers = self.__build_headers("user", api_key) response = self.client.get("/admin-api/article/", **headers) tools.assert_equals(response.status_code, 200) self.__logout(headers) def test_unauthorized_with_wrong_credentials(self): """ Return "401 Unauthorized" header to user with wrong credetials. """ TEST_CASES = ( # username, password ("pepek", "spinach"), # wrong username and password ("use", "pas"), # wrong username and password ("use", "pass"), # wrong username ("user", "pas"), # wrong password ) for username, password in TEST_CASES: response = self.client.post("/admin-api/login/", data={"username": username, "password": password}) tools.assert_equals(response.status_code, 401) def test_unauthorized_after_logout(self): """ Return "401 Unauthorized" header to user after logout. """ api_key = self.__login("user", "pass") headers = self.__build_headers("user", api_key) response = self.client.get("/admin-api/article/", **headers) tools.assert_equals(response.status_code, 200) self.__logout(headers) response = self.client.get("/admin-api/article/", **headers) tools.assert_equals(response.status_code, 401) def __login(self, username, password): response = self.client.post('/admin-api/login/', data={"username": username, "password": password}) tools.assert_equals(response.status_code, 200) resources = self.__get_response_json(response) tools.assert_true("api_key" in resources) return resources["api_key"] def __logout(self, headers, status_code=302): response = self.client.post('/admin-api/logout/', **headers) tools.assert_equals(response.status_code, status_code) def __build_headers(self, username, api_key): return { "HTTP_AUTHORIZATION" : "ApiKey %s:%s" % (username, api_key), } def __get_response_json(self, response): return json.loads(response.content)
def test_resources(self): c = Client() # Test resource schema response = c.options('/test_api/v1/media/books/') self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 12) # Test auth api decorator response = c.get('/test_api/v1/media/books/') self.assertEqual(response.status_code, 403) response = c.get('/test_api/v1/media/books/', data={'api_key': 123}) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 0) response = c.post( '/test_api/v1/media/books/', data=json.dumps({'name': 'Moby Dick'}), content_type="application/json") self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(output['name'], "Moby Dick") response = c.get('/test_api/v1/media/books/', data={'api_key': 123, 'limit': 1}) self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(len(output), 1) self.assertEqual(output[0]['name'], "Moby Dick") id = output[0].get('id') self.assertIsNotNone(id) # Test getting etag from decorator and pagination decorator self.assertTrue(response.has_header("etag")) self.assertTrue(response.has_header("next-url")) # Test ETag decorator matching response = c.get( '/test_api/v1/media/books/', data={'api_key': 123}, **{"HTTP_IF_NONE_MATCH": response["etag"]} ) self.assertEqual(response.status_code, 304) response = c.get('/test_api/v1/media/books/' + id + "/") self.assertEqual(response.status_code, 200) output = json.loads(response.content) self.assertEqual(output['name'], "Moby Dick") self.assertEqual(output['id'], id) response = c.get('/test_api/v1/media/books/' + id + "/author/") self.assertEqual(response.status_code, 200) self.assertEqual(response.content, "Unknown") response = c.post( '/test_api/v1/media/books/' + id + "/author/", data=json.dumps("Herman Melville"), content_type="application/json" ) self.assertEqual(response.status_code, 204) response = c.get('/test_api/v1/media/books/' + id + "/author/") self.assertEqual(response.status_code, 200) self.assertEqual(response.content, "Herman Melville")
class ClientTestCaseMixin(AuthTestCaseMixin): logger = logging.getLogger('tests') def setUp(self): self.c = Client() self.r_factory = RequestFactory() self.default_headers = {} super(ClientTestCaseMixin, self).setUp() def get_request_with_user(self, request): request.user = self.logged_user.user return request def logout(self): self.get(config.LOGOUT_URL) self.logged_user = None def authorize(self, username, password): assert_http_redirect( self.post(config.LOGIN_URL, { config.USERNAME: username, config.PASSWORD: password })) def get(self, url, headers=None): headers = headers or {} headers.update(self.default_headers) resp = self.c.get(url, **headers) return resp def put(self, url, data={}, headers=None): headers = headers or {} headers.update(self.default_headers) return self.c.put(url, data, **self.headers) def post(self, url, data, headers=None): headers = headers or {} headers.update(self.default_headers) return self.c.post(url, data, **headers) def head(self, url, headers=None): headers = headers or {} headers.update(self.default_headers) return self.c.head(url, **headers) def options(self, url, headers=None): headers = headers or {} headers.update(self.default_headers) return self.c.options(url, **headers) def delete(self, url, headers=None): headers = headers or {} headers.update(self.default_headers) resp = self.c.delete(url, **headers) return resp
class ApiTestCase(TestCase): fixtures = ['_initial_data.json',] def __init__(self, *args, **kargs): super(ApiTestCase, self).__init__(*args, **kargs) self._passwords = {} # user_id -> password def setUp(self): self.client = Client() self.user = amcattest.create_test_user() self.user.is_superuser = True self.user.save() def _login(self, as_user=None, password=None): as_user = as_user or self.user if not password: password = self._passwords.get(as_user.id) if not password: password = '******' as_user.set_password(password) as_user.save() self._passwords[as_user.id] = password self.assertTrue(self.client.login(username=as_user.username, password=password), "Cannot log in") def _request(self, resource, as_user=None, method='get', check_status=200, request_args=[], request_options={}, **options): if as_user is not None: self._login(as_user=as_user) resource_url = resource if isinstance(resource, str) else resource.get_url() if options: resource_url += "?" + surlencode(options) log.info("{method} {resource_url} {request_args} {request_options}".format(**locals())) method = getattr(self.client, method) request = method(resource_url, *request_args, **request_options) if check_status: self.assertEqual(request.status_code, check_status, "Error: request returned status {request.status_code} (required: {check_status})\n{request.content}".format(**locals())) return request def get_options(self, resource): self._login() request = self.client.options(resource.get_url() + "?format=json") return json.loads(request.content.decode("utf-8")) def get(self, resource, **options): result = self._request(resource, format='json', **options) return json.loads(result.content.decode("utf-8")) def post(self, resource, body, check_status=201, **options): result = self._request(resource, method='post', format='json', request_args=[body], check_status=check_status, **options) return json.loads(result.content.decode("utf-8")) def get_object(self, resource, pk, **options): result = self.get(resource, pk=pk, **options) result = result['results'][0] keys, values = zip(*result.items()) t = collections.namedtuple(resource.model.__name__, keys) return t(*values) def assertDictsEqual(self, a,b): if a != b: msg = [] for x in a: if x not in b: msg += [">> {x} not in b".format(**locals())] elif a[x] != b[x]: msg += ["!! a[x]={ax} != b[x]={bx}".format(ax=a[x], bx=b[x])] for x in b: if x not in a: msg += ["<< {x} not in a".format(**locals())] self.assertEqual(a,b, "\n".join(msg))
class ApiTestCase(TestCase): fixtures = [ '_initial_data.json', ] def __init__(self, *args, **kargs): super(ApiTestCase, self).__init__(*args, **kargs) self._passwords = {} # user_id -> password def setUp(self): self.client = Client() self.user = amcattest.create_test_user() self.user.is_superuser = True self.user.save() def _login(self, as_user=None, password=None): as_user = as_user or self.user if not password: password = self._passwords.get(as_user.id) if not password: password = '******' as_user.set_password(password) as_user.save() self._passwords[as_user.id] = password self.assertTrue( self.client.login(username=as_user.username, password=password), "Cannot log in") def _request(self, resource, as_user=None, method='get', check_status=200, request_args=[], request_options={}, **options): if as_user is not None: self._login(as_user=as_user) resource_url = resource if isinstance(resource, str) else resource.get_url() if options: resource_url += "?" + surlencode(options) log.info( "{method} {resource_url} {request_args} {request_options}".format( **locals())) method = getattr(self.client, method) request = method(resource_url, *request_args, **request_options) if check_status: self.assertEqual( request.status_code, check_status, "Error: request returned status {request.status_code} (required: {check_status})\n{request.content}" .format(**locals())) return request def get_options(self, resource): self._login() request = self.client.options(resource.get_url() + "?format=json") return json.loads(request.content.decode("utf-8")) def get(self, resource, **options): result = self._request(resource, format='json', **options) return json.loads(result.content.decode("utf-8")) def post(self, resource, body, check_status=201, **options): result = self._request(resource, method='post', format='json', request_args=[body], check_status=check_status, **options) return json.loads(result.content.decode("utf-8")) def get_object(self, resource, pk, **options): result = self.get(resource, pk=pk, **options) result = result['results'][0] keys, values = zip(*result.items()) t = collections.namedtuple(resource.model.__name__, keys) return t(*values) def assertDictsEqual(self, a, b): if a != b: msg = [] for x in a: if x not in b: msg += [">> {x} not in b".format(**locals())] elif a[x] != b[x]: msg += [ "!! a[x]={ax} != b[x]={bx}".format(ax=a[x], bx=b[x]) ] for x in b: if x not in a: msg += ["<< {x} not in a".format(**locals())] self.assertEqual(a, b, "\n".join(msg))
def test_no_OPTIONS(self): c = Client() response = c.options("/api/v1/null") self.assertEquals(response.status_code, 405)
def options(self, url, *args, **kwargs): response = Client.options(self, url, *args, **kwargs)
class ClientTestCase(AuthTestCaseMixin, LiveServerTestCase, AssertMixin): logger = logging.getLogger('tests') def setUp(self): self.c = Client() self.r_factory = RequestFactory() self.default_headers = {} super(ClientTestCase, self).setUp() def get_request_with_user(self, request): request.user = self.logged_user.user return request def logout(self): self.get(config.LOGOUT_URL) self.logged_user = None def authorize(self, username, password): resp = self.post(config.LOGIN_URL, { config.USERNAME: username, config.PASSWORD: password }) self.assert_http_redirect(resp) def get(self, url, headers=None): headers = headers or {} headers.update(self.default_headers) resp = self.c.get(url, **headers) return resp def put(self, url, data={}, headers=None): headers = headers or {} headers.update(self.default_headers) return self.c.put(url, data, **self.headers) def post(self, url, data, headers=None): headers = headers or {} headers.update(self.default_headers) return self.c.post(url, data, **headers) def head(self, url, headers=None): headers = headers or {} headers.update(self.default_headers) return self.c.head(url, **headers) def options(self, url, headers=None): headers = headers or {} headers.update(self.default_headers) return self.c.options(url, **headers) def delete(self, url, headers=None): headers = headers or {} headers.update(self.default_headers) resp = self.c.delete(url, **headers) return resp def assert_http_ok(self, resp, msg=None): return self.assert_equal(resp.status_code, 200, msg) def assert_http_created(self, resp, msg=None): return self.assert_equal(resp.status_code, 201, msg) def assert_http_accepted(self, resp, msg=None): return self.assert_in(resp.status_code, [202, 204], msg) def assert_http_multiple_choices(self, resp, msg=None): return self.assertEqual(resp.status_code, 300, msg) def assert_http_redirect(self, resp, msg=None): """ Ensures the response is returning a HTTP 302. """ return self.assertEqual(resp.status_code, 302, msg) def assert_http_see_other(self, resp, msg=None): """ Ensures the response is returning a HTTP 303. """ return self.assertEqual(resp.status_code, 303, msg) def assert_http_not_modified(self, resp, msg=None): """ Ensures the response is returning a HTTP 304. """ return self.assertEqual(resp.status_code, 304, msg) def assert_http_bad_request(self, resp, msg=None): """ Ensures the response is returning a HTTP 400. """ return self.assertEqual(resp.status_code, 400, msg) def assert_http_unauthorized(self, resp, msg=None): """ Ensures the response is returning a HTTP 401. """ return self.assertEqual(resp.status_code, 401, msg) def assert_http_forbidden(self, resp, msg=None): """ Ensures the response is returning a HTTP 403. """ return self.assertEqual(resp.status_code, 403, msg) def assert_http_not_found(self, resp, msg=None): """ Ensures the response is returning a HTTP 404. """ return self.assertEqual(resp.status_code, 404, msg) def assert_http_method_not_allowed(self, resp, msg=None): """ Ensures the response is returning a HTTP 405. """ return self.assertEqual(resp.status_code, 405, msg) def assert_http_conflict(self, resp, msg=None): """ Ensures the response is returning a HTTP 409. """ return self.assertEqual(resp.status_code, 409, msg) def assert_http_gone(self, resp, msg=None): """ Ensures the response is returning a HTTP 410. """ return self.assertEqual(resp.status_code, 410, msg) def assert_http_unprocessable_entity(self, resp, msg=None): """ Ensures the response is returning a HTTP 422. """ return self.assertEqual(resp.status_code, 422, msg) def assert_http_too_many_requests(self, resp, msg=None): """ Ensures the response is returning a HTTP 429. """ return self.assertEqual(resp.status_code, 429, msg) def assert_http_application_error(self, resp, msg=None): """ Ensures the response is returning a HTTP 500. """ return self.assertEqual(resp.status_code, 500, msg) def assert_http_not_implemented(self, resp, msg=None): """ Ensures the response is returning a HTTP 501. """ return self.assertEqual(resp.status_code, 501, msg)