def test_methods(method): app = Mach9('test_methods') class DummyView(HTTPMethodView): async def get(self, request): assert request.stream is None return text('', headers={'method': 'GET'}) def post(self, request): return text('', headers={'method': 'POST'}) async def put(self, request): return text('', headers={'method': 'PUT'}) def head(self, request): return text('', headers={'method': 'HEAD'}) def options(self, request): return text('', headers={'method': 'OPTIONS'}) async def patch(self, request): return text('', headers={'method': 'PATCH'}) def delete(self, request): return text('', headers={'method': 'DELETE'}) app.add_route(DummyView.as_view(), '/') request, response = getattr(app.test_client, method.lower())('/') assert response.headers['method'] == method
def test_with_middleware_response(): app = Mach9('test_with_middleware_response') results = [] @app.middleware('request') async def process_response(request): results.append(request) @app.middleware('response') async def process_response1(request, response): results.append(request) results.append(response) class DummyView(HTTPMethodView): def get(self, request): return text('I am get method') app.add_route(DummyView.as_view(), '/') request, response = app.test_client.get('/') assert response.text == 'I am get method' assert type(results[0]) is Request assert type(results[1]) is Request assert isinstance(results[2], HTTPResponse)
def test_file_head_response(file_name, static_file_directory): app = Mach9('test_file_helper') @app.route('/files/<filename>', methods=['GET', 'HEAD']) async def file_route(request, filename): file_path = os.path.join(static_file_directory, filename) file_path = os.path.abspath(unquote(file_path)) stats = await async_os.stat(file_path) headers = dict() headers['Accept-Ranges'] = 'bytes' headers['Content-Length'] = str(stats.st_size) if request.method == "HEAD": return HTTPResponse(headers=headers, content_type=guess_type(file_path)[0] or 'text/plain') else: return file(file_path, headers=headers, mime_type=guess_type(file_path)[0] or 'text/plain') request, response = app.test_client.head('/files/{}'.format(file_name)) assert response.status == 200 assert 'Accept-Ranges' in response.headers assert 'Content-Length' in response.headers assert int(response.headers['Content-Length']) == len( get_file_content(static_file_directory, file_name))
def blueprint_app(): app = Mach9('blueprints') first_print = Blueprint('first', url_prefix='/first') second_print = Blueprint('second', url_prefix='/second') @first_print.route('/foo') def foo(): return text('foo from first') @first_print.route('/foo/<param>') def foo_with_param(request, param): return text('foo from first : {}'.format(param)) @second_print.route('/foo') # noqa def foo(): return text('foo from second') @second_print.route('/foo/<param>') # noqa def foo_with_param(request, param): return text('foo from second : {}'.format(param)) app.blueprint(first_print) app.blueprint(second_print) return app
def test_remove_static_route(): app = Mach9('test_remove_static_route') async def handler1(request): return text('OK1') async def handler2(request): return text('OK2') app.add_route(handler1, '/test') app.add_route(handler2, '/test2') request, response = app.test_client.get('/test') assert response.status == 200 request, response = app.test_client.get('/test2') assert response.status == 200 app.remove_route('/test') app.remove_route('/test2') request, response = app.test_client.get('/test') assert response.status == 404 request, response = app.test_client.get('/test2') assert response.status == 404
def redirect_app(): app = Mach9('test_redirection') @app.route('/redirect_init') async def redirect_init(request): return redirect("/redirect_target") @app.route('/redirect_init_with_301') async def redirect_init_with_301(request): return redirect("/redirect_target", status=301) @app.route('/redirect_target') async def redirect_target(request): return text('OK') @app.route('/1') def handler(request): return redirect('/2') @app.route('/2') def handler(request): return redirect('/3') @app.route('/3') def handler(request): return text('OK') return app
def simple_app(): app = Mach9('simple_app') handler_names = list(string.ascii_letters) _generate_handlers_from_names(app, handler_names) return app
def test_unmergeable_overload_routes(): app = Mach9('test_dynamic_route') @app.route('/overload_whole', methods=None) async def handler1(request): return text('OK1') with pytest.raises(RouteExists): @app.route('/overload_whole', methods=['POST', 'PUT']) async def handler2(request): return text('Duplicated') request, response = app.test_client.get('/overload_whole') assert response.text == 'OK1' request, response = app.test_client.post('/overload_whole') assert response.text == 'OK1' @app.route('/overload_part', methods=['GET']) async def handler1(request): return text('OK1') with pytest.raises(RouteExists): @app.route('/overload_part') async def handler2(request): return text('Duplicated') request, response = app.test_client.get('/overload_part') assert response.text == 'OK1' request, response = app.test_client.post('/overload_part') assert response.status == 405
def test_url_attributes_with_ssl(path, query, expected_url): app = Mach9('test_url_attrs_with_ssl') current_dir = os.path.dirname(os.path.realpath(__file__)) context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH) context.load_cert_chain( os.path.join(current_dir, 'certs/selfsigned.cert'), keyfile=os.path.join(current_dir, 'certs/selfsigned.key')) async def handler(request): return text('OK') app.add_route(handler, path) request, response = app.test_client.get( 'https://{}:{}'.format(HOST, PORT) + path + '?{}'.format(query), server_kwargs={'ssl': context}) assert request.url == expected_url.format(HOST, PORT) parsed = urlparse(request.url) assert parsed.scheme == request.scheme assert parsed.path == request.path assert parsed.query == request.query_string assert parsed.netloc == request.host
def test_remove_unhashable_route(): app = Mach9('test_remove_unhashable_route') async def handler(request, unhashable): return text('OK') app.add_route(handler, '/folder/<unhashable:[A-Za-z0-9/]+>/end/') request, response = app.test_client.get('/folder/test/asdf/end/') assert response.status == 200 request, response = app.test_client.get('/folder/test///////end/') assert response.status == 200 request, response = app.test_client.get('/folder/test/end/') assert response.status == 200 app.remove_route('/folder/<unhashable:[A-Za-z0-9/]+>/end/') request, response = app.test_client.get('/folder/test/asdf/end/') assert response.status == 404 request, response = app.test_client.get('/folder/test///////end/') assert response.status == 404 request, response = app.test_client.get('/folder/test/end/') assert response.status == 404
def test_request_stream_composition_view(): app = Mach9('test_request_stream__composition_view') def get_handler(request): assert request.stream is None return text('OK') async def post_handler(request): assert isinstance(request.stream, BodyChannel) result = '' while True: body_chunk = await request.stream.receive() if body_chunk['more_content'] is False: break result += body_chunk['content'].decode('utf-8') return text(result) view = CompositionView() view.add(['GET'], get_handler) view.add(['POST'], post_handler, stream=True) app.add_route(view, '/composition_view') request, response = app.test_client.get('/composition_view') assert response.status == 200 assert response.text == 'OK' request, response = app.test_client.post('/composition_view', data=data) assert response.status == 200 assert response.text == data
def test_remove_route_without_clean_cache(): app = Mach9('test_remove_static_route') async def handler(request): return text('OK') app.add_route(handler, '/test') request, response = app.test_client.get('/test') assert response.status == 200 app.remove_route('/test', clean_cache=True) request, response = app.test_client.get('/test') assert response.status == 404 app.add_route(handler, '/test') request, response = app.test_client.get('/test') assert response.status == 200 app.remove_route('/test', clean_cache=False) request, response = app.test_client.get('/test') assert response.status == 200
def test_bp_with_host(): app = Mach9('test_bp_host') bp = Blueprint('test_bp_host', url_prefix='/test1', host="example.com") @bp.route('/') def handler(request): return text('Hello') @bp.route('/', host="sub.example.com") def handler3(request): return text('Hello subdomain!') app.blueprint(bp) headers = {"Host": "example.com"} request, response = app.test_client.get( '/test1/', headers=headers) assert response.text == 'Hello' headers = {"Host": "sub.example.com"} request, response = app.test_client.get( '/test1/', headers=headers) assert response.text == 'Hello subdomain!'
def test_request_stream_method_view(): app = Mach9('test_request_stream_method_view') class SimpleView(HTTPMethodView): def get(self, request): assert request.stream is None return text('OK') @stream_decorator async def post(self, request): assert isinstance(request.stream, BodyChannel) result = '' while True: body_chunk = await request.stream.receive() if body_chunk['more_content'] is False: break result += body_chunk['content'].decode('utf-8') return text(result) app.add_route(SimpleView.as_view(), '/method_view') request, response = app.test_client.get('/method_view') assert response.status == 200 assert response.text == 'OK' request, response = app.test_client.post('/method_view', data=data) assert response.status == 200 assert response.text == data
def test_bp_strict_slash(): app = Mach9('test_route_strict_slash') bp = Blueprint('test_text') @bp.get('/get', strict_slashes=True) def handler1(request): return text('OK') @bp.post('/post/', strict_slashes=True) def handler2(request): return text('OK') app.blueprint(bp) request, response = app.test_client.get('/get') assert response.text == 'OK' request, response = app.test_client.get('/get/') assert response.status == 404 request, response = app.test_client.post('/post/') assert response.text == 'OK' request, response = app.test_client.post('/post') assert response.status == 404
def test_bp_listeners(): app = Mach9('test_middleware') blueprint = Blueprint('test_middleware') order = [] @blueprint.listener('before_server_start') def handler_1(mach9, loop): order.append(1) @blueprint.listener('after_server_start') def handler_2(mach9, loop): order.append(2) @blueprint.listener('after_server_start') def handler_3(mach9, loop): order.append(3) @blueprint.listener('before_server_stop') def handler_4(mach9, loop): order.append(5) @blueprint.listener('before_server_stop') def handler_5(mach9, loop): order.append(4) @blueprint.listener('after_server_stop') def handler_6(mach9, loop): order.append(6) app.blueprint(blueprint) request, response = app.test_client.get('/') assert order == [1, 2, 3, 4, 5, 6]
def test_bp_exception_handler(): app = Mach9('test_middleware') blueprint = Blueprint('test_middleware') @blueprint.route('/1') def handler_1(request): raise InvalidUsage("OK") @blueprint.route('/2') def handler_2(request): raise ServerError("OK") @blueprint.route('/3') def handler_3(request): raise NotFound("OK") @blueprint.exception(NotFound, ServerError) def handler_exception(request, exception): return text("OK") app.blueprint(blueprint) request, response = app.test_client.get('/1') assert response.status == 400 request, response = app.test_client.get('/2') assert response.status == 200 assert response.text == 'OK' request, response = app.test_client.get('/3') assert response.status == 200
def exception_app(): app = Mach9('test_exceptions') @app.route('/') def handler(request): return text('OK') @app.route('/error') def handler_error(request): raise ServerError("OK") @app.route('/404') def handler_404(request): raise NotFound("OK") @app.route('/invalid') def handler_invalid(request): raise InvalidUsage("OK") @app.route('/divide_by_zero') def handle_unhandled_exception(request): 1 / 0 @app.route('/error_in_error_handler_handler') def custom_error_handler(request): raise Mach9ExceptionTestException('Dummy message!') @app.exception(Mach9ExceptionTestException) def error_in_error_handler_handler(request, exception): 1 / 0 return app
def test_overload_routes(): app = Mach9('test_dynamic_route') @app.route('/overload', methods=['GET']) async def handler1(request): return text('OK1') @app.route('/overload', methods=['POST', 'PUT']) async def handler2(request): return text('OK2') request, response = app.test_client.get('/overload') assert response.text == 'OK1' request, response = app.test_client.post('/overload') assert response.text == 'OK2' request, response = app.test_client.put('/overload') assert response.text == 'OK2' request, response = app.test_client.delete('/overload') assert response.status == 405 with pytest.raises(RouteExists): @app.route('/overload', methods=['PUT', 'DELETE']) async def handler3(request): return text('Duplicated')
def test_static_file(static_file_directory, file_name): app = Mach9('test_static') app.static('/testing.file', get_file_path(static_file_directory, file_name)) request, response = app.test_client.get('/testing.file') assert response.status == 200 assert response.body == get_file_content(static_file_directory, file_name)
def test_static_directory(file_name, base_uri, static_file_directory): app = Mach9('test_static') app.static(base_uri, static_file_directory) request, response = app.test_client.get( uri='{}/{}'.format(base_uri, file_name)) assert response.status == 200 assert response.body == get_file_content(static_file_directory, file_name)
def test_overwrite_exisiting_config(): app = Mach9('test_overwrite_exisiting_config') app.config.DEFAULT = 1 class Config: DEFAULT = 2 app.config.from_object(Config) assert app.config.DEFAULT == 2
def test_uri_template(): app = Mach9('test_uri_template') @app.route('/foo/<id:int>/bar/<name:[A-z]+>') async def handler(request): return text('OK') request, response = app.test_client.get('/foo/123/bar/baz') assert request.uri_template == '/foo/<id:int>/bar/<name:[A-z]+>'
def test_utf8_query_string(): app = Mach9('test_utf8_query_string') @app.route('/') async def handler(request): return text('OK') request, response = app.test_client.get('/', params=[("utf8", '✓')]) assert request.args.get('utf8') == '✓'
def test_utf8_response(): app = Mach9('test_utf8_response') @app.route('/') async def handler(request): return text('✓') request, response = app.test_client.get('/') assert response.text == '✓'
def test_text(): app = Mach9('test_text') @app.route('/') async def handler(request): return text('Hello') request, response = app.test_client.get('/') assert response.text == 'Hello'
def test_all_listeners(): random_name_app = Mach9(''.join( [choice(ascii_letters) for _ in range(choice(range(5, 10)))])) output = list() for listener_name in AVAILABLE_LISTENERS: listener = create_listener(listener_name, output) random_name_app.listener(listener_name)(listener) start_stop_app(random_name_app) for listener_name in AVAILABLE_LISTENERS: assert random_name_app.name + listener_name == output.pop()
def skip_test_utf8_route(): app = Mach9('skip_test_utf8_route') @app.route('/') async def handler(request): return text('OK') # UTF-8 Paths are not supported request, response = app.test_client.get('/✓') assert response.text == 'OK'
def test_single_listener(listener_name): """Test that listeners on their own work""" random_name_app = Mach9(''.join( [choice(ascii_letters) for _ in range(choice(range(5, 10)))])) output = list() # Register listener random_name_app.listener(listener_name)( create_listener(listener_name, output)) start_stop_app(random_name_app) assert random_name_app.name + listener_name == output.pop()
def test_load_from_envvar(): app = Mach9('test_load_from_envvar') config = b"VALUE = 'some value'" with NamedTemporaryFile() as config_file: config_file.write(config) config_file.seek(0) environ['APP_CONFIG'] = config_file.name app.config.from_envvar('APP_CONFIG') assert 'VALUE' in app.config assert app.config.VALUE == 'some value'