def setUp(self): super(RouterArgumentsValidatorTestCase, self).setUp() self.validator = RouteArgumentsValidator()
class RouterArgumentsValidatorTestCase(unittest.TestCase): def setUp(self): super(RouterArgumentsValidatorTestCase, self).setUp() self.validator = RouteArgumentsValidator() def test_check_path(self): invalid_path = 'api' self.assertRaises(InvalidPathArgument, self.validator.path_validator.validate, invalid_path) valid_path = '/api' self.assertIsNone(self.validator.path_validator.validate(valid_path)) def test_check_handler(self): valid_handler = MethodBasedView self.assertIsNone( self.validator.handler_validator.validate(valid_handler)) def test_check_handler_failed(self): invalid_handler = object self.assertRaises(InvalidHandler, self.validator.handler_validator.validate, invalid_handler) def test_check_handler_with_none_function(self): invalid_handler = [ 'not a class', ] self.assertRaises(InvalidHandler, self.validator.handler_validator.validate, invalid_handler) def test_check_methods(self): valid_methods = [ 'get', ] self.assertIsNone( self.validator.methods_validator.validate(valid_methods)) def test_check_methods_2(self): valid_methods = 'get' self.assertIsNone( self.validator.methods_validator.validate(valid_methods)) def test_check_methods_failed(self): invalid_methods = ('get', ) self.assertRaises(NotSupportedArgumentType, self.validator.methods_validator.validate, invalid_methods) def test_check_name(self): valid_name = 'basename' self.assertIsNone( self.validator.endpoint_name_validator.validate(valid_name)) def test_check_name_2(self): self.assertIsNone( self.validator.endpoint_name_validator.validate(None)) def test_check_name_failed(self): invalid_name = ('basename', ) self.assertRaises(NotSupportedArgumentType, self.validator.endpoint_name_validator.validate, invalid_name) def test_validate(self): args = '/api/', MethodBasedView, 'GET', None self.validator.validate(*args)
class SimpleRouter(AbstractRouter): """ Default router class, used for working with REST over WebSockets. """ args_validator = RouteArgumentsValidator() url_parser = URLParser() def _correct_path(self, path): """ Convert path to valid value. :param path: URL, which used to get access to API. """ path = path.strip() if not path.endswith('/'): path += '/' return path def register(self, path, handler, methods, name=None): """ Add new endpoint to the router. :param path: URL, which used to get access to API. :param handler: inherited class from the MethodBasedView, which used for processing request. :param methods: list of available for user methods or string with concrete method name. :param name: short name for endpoint. """ path = self._correct_path(path) self.args_validator.validate(path, handler, methods, name) route = self.url_parser.define_route(path, handler, methods, name) self._register_url(route) def register_endpoint(self, endpoint): """ Add new endpoint to the router. :param endpoint: function with @endpoint decorator, which used for processing request. """ path, handler, methods, name = endpoint() self.register(path, handler, methods, name) def extract_url(self, request): """ Extracting URL parameter for request. :param request: request from the user. """ if not request.url: raise NotSpecifiedURL() return self._correct_path(request.url) def search_handler(self, request, url): """ Searching handler by URL. :param request: request from user. :param url: path to the registered endpoint. """ args = () kwargs = {} handler = None # Iterate over the all endpoints for route in self._urls: # Find match between endpoint and request URL match = route.match(url) if match is not None: handler = route.handler() args = match parameters = request.args if parameters: kwargs.update(parameters) break return handler, args, kwargs def process_request(self, request): """ Handle received request from user. :param request: request from user. """ logger.info("\"{method} {url}\" args={args}".format( method=request.method, url=request.url, args=request.args)) response = Response() try: url = self.extract_url(request) handler, args, kwargs = self.search_handler(request, url) # Invoke handler for request if handler: for middleware in self.middlewares: middleware.process_request(request, handler) # Search serializer for response format = request.get_argument('format') serializer = handler.get_renderer(format, *args, **kwargs) response.content = handler.dispatch(request, *args, **kwargs) else: raise NotSpecifiedHandler() except BaseAPIException as exc: logger.exception(exc) response.wrap_exception(exc) serializer = JSONRenderer() response.append_request(request) return serializer.render(response.content) def _register_url(self, route): """ Register new endpoint. :param route: instance of class, inherited from AbstractEndpoint. """ if not issubclass(type(route), (AbstractEndpoint, )): raise TypeError(u"Custom route must be inherited from the " u"AbstractEndpoint class.") if route.name: if route.name in self._routes.keys(): raise EndpointValueError( 'Duplicate {}, already handled by {}'.format( route.name, self._routes[route.name])) self._routes[route.name] = route self._urls.append(route) def include(self, router): """ Appending endpoints from another router to self. :param router: instance of subclass, derived from AbstractRouter. """ if not issubclass(type(router), (AbstractRouter, )): raise TypeError(u"Passed router must be inherited from the " u"AbstractRouter class.") self._urls.extend(router._urls) self._routes.update(router._routes)
class RouterArgumentsValidatorTestCase(unittest.TestCase): def setUp(self): super(RouterArgumentsValidatorTestCase, self).setUp() self.validator = RouteArgumentsValidator() def test_check_path(self): invalid_path = 'api' self.assertRaises( InvalidPathArgument, self.validator.path_validator.validate, invalid_path ) valid_path = '/api' self.assertIsNone(self.validator.path_validator.validate(valid_path)) def test_check_handler(self): valid_handler = MethodBasedView self.assertIsNone( self.validator.handler_validator.validate(valid_handler) ) def test_check_handler_failed(self): invalid_handler = object self.assertRaises( InvalidHandler, self.validator.handler_validator.validate, invalid_handler ) def test_check_handler_with_none_function(self): invalid_handler = ['not a class', ] self.assertRaises( InvalidHandler, self.validator.handler_validator.validate, invalid_handler ) def test_check_methods(self): valid_methods = ['get', ] self.assertIsNone( self.validator.methods_validator.validate(valid_methods) ) def test_check_methods_2(self): valid_methods = 'get' self.assertIsNone( self.validator.methods_validator.validate(valid_methods) ) def test_check_methods_failed(self): invalid_methods = ('get', ) self.assertRaises( NotSupportedArgumentType, self.validator.methods_validator.validate, invalid_methods ) def test_check_name(self): valid_name = 'basename' self.assertIsNone( self.validator.endpoint_name_validator.validate(valid_name) ) def test_check_name_2(self): self.assertIsNone( self.validator.endpoint_name_validator.validate(None) ) def test_check_name_failed(self): invalid_name = ('basename', ) self.assertRaises( NotSupportedArgumentType, self.validator.endpoint_name_validator.validate, invalid_name ) def test_validate(self): args = '/api/', MethodBasedView, 'GET', None self.validator.validate(*args)