def test_errors(self): ''' Tests that errors are raised for status codes Errors should be raised for URL error responses (4xx and 5xx) ''' r = ResponseTest(400, {}, "Bad Request") with self.assertRaises(RequestError) as err: Response(r, self.app) self.assertEqual(str(err.exception), "Bad Request") r = ResponseTest(500, {}, "Server Error") with self.assertRaises(ServerError) as err: Response(r, self.app) self.assertEqual(str(err.exception), "Server Error")
def test_URLs(self): ''' Test that the URL special datatype handler works Tests the special handler for URL datatypes gets identified and used ''' params = {"url": "/test"} r = ResponseTest(200, {"Content-Type": "application/json"}, json.dumps(params)) response = Response(r, self.app) self.assertEqual(response.data["url"], "http://nope/test")
def test_date(self): ''' Tests that datetime strings are handled as datetimes Tests the various formats for datetime strings and makes sure they get converted into the proper structure. ''' params = {"date": "12/24/99"} r = ResponseTest(200, {"Content-Type": "application/json"}, json.dumps(params)) response = Response(r, self.app) self.assertEqual(response.data["date"].strftime("%Y%m%d"), "19991224")
def test_json(self): ''' Tests that the `Content-Type` for json is identified and parsed This tests the __json_handler for mimetypes in `Response` ''' r = ResponseTest(200, {"Content-Type": "application/json"}, "{\"foo\":\"bar\"}") response = Response(r, self.app) self.assertTrue(isinstance(response.data, dict)) self.assertTrue("foo" in response.data) self.assertEqual(response.data["foo"], "bar")
def test_nonroot_mismatchURLs(self): ''' Tests that URLs of a non root base URL handle mismatches This is when the passed in URL is for a root folder that is not the same as the base subfolder of the application. ''' self.app = Restler("http://nope/test/") params = {"url": "/derp"} r = ResponseTest(200, {"Content-Type": "application/json"}, json.dumps(params)) response = Response(r, self.app) self.assertEqual(response.data["url"], "/derp")
def test_fullURLs(self): ''' Test that full URLs are handled Tests the handler for full URLs (ones including the host) are caught and properly converted. ''' params = {"url": "http://nope/test2"} r = ResponseTest(200, {"Content-Type": "application/json"}, json.dumps(params)) response = Response(r, self.app) self.assertTrue(isinstance(response.data["url"], Route)) self.assertEqual(response.data["url"], "http://nope/test2")
def test_encoded(self): ''' Tests that the `Content-Type` for url encoded works This tests the __form_handler for mimetypes in `Response` ''' r = ResponseTest(200, {"Content-Type": "application/x-www-form-urlencoded"}, "foo=bar&bar=baz") response = Response(r, self.app) self.assertTrue(isinstance(response.data, dict)) self.assertTrue("foo" in response.data) self.assertEqual(response.data["foo"], "bar")
def test_nonroot_URLs(self): ''' Test that URLs of a non root base URL are handled properly This is a test for when an app uses a path in the base URL (i.e. something like `http://twitter.com/api/`) so URLs that get converted take into account this additional base folder ''' self.app = Restler("http://nope/test/") params = {"url": "/test"} r = ResponseTest(200, {"Content-Type": "application/json"}, json.dumps(params)) response = Response(r, self.app) self.assertEqual(response.data["url"], "http://nope/test") # Bug, url in above doesn't have trailing slash, messed up with the natural # trailing slash self.app = Restler("http://nope/test/") params = {"url": "/test/"} r = ResponseTest(200, {"Content-Type": "application/json"}, json.dumps(params)) response = Response(r, self.app) self.assertEqual(response.data["url"], "http://nope/test")
def test_links(self): ''' Tests the parsing of the Link header If a Link header is present, the response should have a `link` property which exposes easy access to the attributes of the header. ''' r = ResponseTest( 200, { "Link": "</next>; rel=\"next\", " + "</args?test=1>; rel=\"test\", " + "<http://nope/full>; rel=\"full\"" }, "") response = Response(r, self.app) self.assertEquals(str(response.links.next), "http://nope/next") self.assertDictEqual(response.links.test._default_params, {"test": "1"}) self.assertEquals(str(response.links.full), "http://nope/full") self.assertEqual(response.links.none, None)
any of them match the provided string value. Keeps track of which format was matched so that it may later be used for conversion. """ for dateset in cls.types: if not isstr(value): continue if dateset.matcher.match(value): cls.current = dateset.parser return True cls.current = None return False @classmethod def handler(cls, response, value): """ Converts the raw value into a rich ``datetime`` object using the most recently detected format as the parsing definition. """ if not cls.current: return value new_date = datetime.strptime(value, cls.current) cls.current = None return new_date DateHandler.register("[0-3][0-9]/[0-3][0-9]/[0-9]{2}", "%m/%d/%y") from restler import Response Response.add_datatype(DateHandler.detection, DateHandler.handler)
try: from urlparse import parse_qs except ImportError: from urllib.parse import parse_qs def handler(response, body): """ MIMEtype handling function for form urlencoded data strings. Performs the conversion from the raw url encoded string using the ``urlparse`` library to handle the basic parsing. (HTTP allows for the same key to be used multiple times, as this behaviour is often handled differently between applications, this does not attempt to handle these and it should be defined by the user based on the application being communicated with) """ data = parse_qs(body) for key, value in data.items(): if len(value) == 1: data[key] = value[0] return data from restler import Response Response.add_mimetype("application/x-www-form-urlencoded", handler)
try: from urlparse import parse_qs except ImportError: from urllib.parse import parse_qs def handler(response, body): ''' form.handler: Performs a conversion from the raw string into a dictionary using the built in urlparsing library. ''' data = parse_qs(body) for key, value in data.items(): if len(value) == 1: data[key] = value[0] return data from restler import Response Response.add_mimetype("application/x-www-form-urlencoded", handler)
from restler.utils import isstr class URLHandler(object): """ Datatype handler for URL strings. Attempts to detect whether the string respresents a valid URL within the namespace of the base URL definition and converts the value into an equivalent :class:`Route <Route>` """ @classmethod def detection(cls, response, value): """ Tests if the value matches a format that signifies it is either an absolute or relative path. """ if not isstr(value): return False return value.startswith('/') or \ value.startswith(str(response.__parent__)) @classmethod def handler(cls, response, value): """ Generates a representative :class:`Route <Route>` """ return response.__parent__[value] from restler import Response Response.add_datatype(URLHandler.detection, URLHandler.handler)
import json def handler(response, body): """ MIMEtype handling function for JSON data strings. Performs the conversion fromt he raw JSON string into the rich JSON structure using the built in ``json`` library. """ return json.loads(body) from restler import Response Response.add_mimetype("application/json", handler)
format was matched so that it may later be used for conversion. """ for dateset in cls.types: if not isstr(value): continue if dateset.matcher.match(value): cls.current = dateset.parser return True cls.current = None return False @classmethod def handler(cls, response, value): """ Converts the raw value into a rich ``datetime`` object using the most recently detected format as the parsing definition. """ if not cls.current: return value new_date = datetime.strptime(value, cls.current) cls.current = None return new_date DateHandler.register("[0-3][0-9]/[0-3][0-9]/[0-9]{2}", "%m/%d/%y") from restler import Response Response.add_datatype(DateHandler.detection, DateHandler.handler)