def test_parser_async(body, doc): with disable_asgi_non_coroutine_wrapping(): class WrappedRespondersBodyParserAsyncResource: @falcon.before(validate_param_async, 'limit', 100) @falcon.before(parse_body_async) async def on_get(self, req, resp, doc=None): self.req = req self.resp = resp self.doc = doc app = create_app(asgi=True) resource = WrappedRespondersBodyParserAsyncResource() app.add_route('/', resource) testing.simulate_get(app, '/', body=body) assert resource.doc == doc async def test_direct(): resource = WrappedRespondersBodyParserAsyncResource() req = testing.create_asgi_req() resp = create_resp(True) await resource.on_get(req, resp, doc) assert resource.doc == doc testing.invoke_coroutine_sync(test_direct)
def test_asgi_raises_error(self, resource): app = create_app(asgi=True) app.add_route('/', resource) app.req_options.auto_parse_form_urlencoded = True with pytest.raises(UnsupportedError): testing.simulate_get(app, '/')
def test_parser_sync(body, doc): app = falcon.API() resource = WrappedRespondersBodyParserResource() app.add_route('/', resource) testing.simulate_get(app, '/', body=body) assert resource.doc == doc
def test_asgi_raises_error(self, resource): app = create_app(asgi=True) app.add_route('/', resource) app.req_options.auto_parse_form_urlencoded = True with pytest.raises(RuntimeError) as exc_info: testing.simulate_get(app, '/') assert 'RequestOptions.auto_parse_form_urlencoded' in exc_info.value.args[ 0]
def test_deserialization_raises(asgi): app = create_app(asgi) class SuchException(Exception): pass class FaultyHandler(media.BaseHandler): def deserialize(self, stream, content_type, content_length): raise SuchException('Wow such error.') def deserialize_async(self, stream, content_type, content_length): raise SuchException('Wow such error.') def serialize(self, media, content_type): raise SuchException('Wow such error.') handlers = media.Handlers({'application/json': FaultyHandler()}) app.req_options.media_handlers = handlers app.resp_options.media_handlers = handlers class Resource: def on_get(self, req, resp): resp.media = {} def on_post(self, req, resp): req.media class ResourceAsync: async def on_get(self, req, resp): resp.media = {} async def on_post(self, req, resp): # NOTE(kgriffs): In this one case we use the property # instead of get_media(), in order to test that the # alias works as expected. await req.media app.add_route('/', ResourceAsync() if asgi else Resource()) # NOTE(kgriffs): Now that we install a default handler for # Exception, we have to clear them to test the path we want # to trigger. # TODO(kgriffs): Since we always add a default error handler # for Exception, should we take out the checks in the WSGI/ASGI # callable and just always assume it will be handled? If so, # it makes testing that the right exception is propagated harder; # I suppose we'll have to look at what is logged. app._error_handlers.clear() with pytest.raises(SuchException): testing.simulate_get(app, '/') with pytest.raises(SuchException): testing.simulate_post(app, '/', json={})
def test_sync_methods_not_overridden(asgi): app = create_app(asgi) class FaultyHandler(media.BaseHandler): pass handlers = media.Handlers({'application/json': FaultyHandler()}) app.req_options.media_handlers = handlers app.resp_options.media_handlers = handlers class Resource: def on_get(self, req, resp): resp.media = {} def on_post(self, req, resp): req.media class ResourceAsync: async def on_get(self, req, resp): resp.media = {} async def on_post(self, req, resp): await req.get_media() app.add_route('/', ResourceAsync() if asgi else Resource()) # NOTE(caselit): force serialization in xml, since error.to_json uses the faulty handler result = testing.simulate_get(app, '/', headers={'Accept': 'text/xml'}) assert result.status_code == 500 result = testing.simulate_post(app, '/', json={}, headers={'Accept': 'text/xml'}) assert result.status_code == 500
def test_sync_methods_not_overridden(asgi): app = create_app(asgi) class FaultyHandler(media.BaseHandler): pass handlers = media.Handlers({'application/json': FaultyHandler()}) app.req_options.media_handlers = handlers app.resp_options.media_handlers = handlers class Resource: def on_get(self, req, resp): resp.media = {} def on_post(self, req, resp): req.media class ResourceAsync: async def on_get(self, req, resp): resp.media = {} async def on_post(self, req, resp): await req.get_media() app.add_route('/', ResourceAsync() if asgi else Resource()) result = testing.simulate_get(app, '/') assert result.status_code == 500 result = testing.simulate_post(app, '/', json={}) assert result.status_code == 500
def test_response_body_rendition_error(asgi): class MalbolgeHandler(falcon.media.BaseHandler): def serialize(self, media, content_type): raise falcon.HTTPError(falcon.HTTP_753) app = create_app(asgi) app.resp_options.media_handlers['text/x-malbolge'] = MalbolgeHandler() app.add_route('/test.mal', CodeResource()) resp = testing.simulate_get(app, '/test.mal') assert resp.status_code == 753 # NOTE(kgriffs): Validate that del works on media handlers. del app.resp_options.media_handlers['text/x-malbolge'] resp = testing.simulate_get(app, '/test.mal') assert resp.status_code == 415
def test_custom_render_body(): class CustomResponse(falcon.asgi.Response): async def render_body(self): body = await super().render_body() if not self.content_type.startswith('text/plain'): return body if not body.endswith(b'\n'): # Be a good Unix netizen return body + b'\n' return body class HelloResource: async def on_get(self, req, resp): resp.content_type = falcon.MEDIA_TEXT resp.text = 'Hello, World!' app = falcon.asgi.App(response_type=CustomResponse) app.add_route('/', HelloResource()) resp = testing.simulate_get(app, '/') assert resp.headers['Content-Type'] == 'text/plain; charset=utf-8' assert resp.text == 'Hello, World!\n'
def test_json_err_no_handler(asgi, monkeypatch_resolver): app = create_app(asgi) handlers = media.Handlers( {falcon.MEDIA_URLENCODED: media.URLEncodedFormHandler()}) # NOTE(kgriffs): Test the pre-3.0 method. Although undocumented, it was # technically a public method, and so we make sure it still works here. if monkeypatch_resolver: def _resolve(media_type, default, raise_not_found=True): with pytest.warns(DeprecatedWarning, match='This undocumented method'): h = handlers.find_by_media_type( media_type, default, raise_not_found=raise_not_found) return h, None, None handlers._resolve = _resolve app.req_options.media_handlers = handlers app.resp_options.media_handlers = handlers class Resource: def on_get(self, req, resp): raise falcon.HTTPForbidden() app.add_route('/', Resource()) result = testing.simulate_get(app, '/') assert result.status_code == 403 assert result.json == falcon.HTTPForbidden().to_dict()
def query(endpoint, parameters): """Query API and print JSON response. Parameters must be supplied as --name value or --name=value. See https://brightsky.dev/docs/ for the available endpoints and arguments. \b Examples: python -m brightsky query weather --lat 52 --lon 7.6 --date 2018-08-13 python -m brightsky query current_weather --lat=52 --lon=7.6 """ if not app._router.find(f'/{endpoint}'): raise click.UsageError(f"Unknown endpoint '{endpoint}'") resp = simulate_get(app, f'/{endpoint}', params=_parse_params(parameters)) print(json.dumps(resp.json))
def test_json_err_no_handler(asgi): app = create_app(asgi) handlers = media.Handlers({falcon.MEDIA_URLENCODED: media.URLEncodedFormHandler()}) app.req_options.media_handlers = handlers app.resp_options.media_handlers = handlers class Resource: def on_get(self, req, resp): raise falcon.HTTPForbidden() app.add_route('/', Resource()) result = testing.simulate_get(app, '/') assert result.status_code == 403 assert result.json == falcon.HTTPForbidden().to_dict()
def test_resource_with_uri_fields_async(): app = create_app(asgi=True) resource = ClassResourceWithURIFieldsAsync() app.add_route('/{field1}/{field2}', resource) result = testing.simulate_get(app, '/a/b') assert result.status_code == 200 assert result.headers['X-Fluffiness'] == 'fluffy' assert resource.fields == ('a', 'b') async def test_direct(): resource = ClassResourceWithURIFieldsAsync() req = testing.create_asgi_req() resp = create_resp(True) await resource.on_get(req, resp, '1', '2') assert resource.fields == ('1', '2') testing.invoke_coroutine_sync(test_direct)
def test_unsupported_response_content_type(asgi): app = create_app(asgi) app.add_route('/test.mal', CodeResource()) resp = testing.simulate_get(app, '/test.mal') assert resp.status_code == 415
def test_deserialization_raises(asgi, handler_mt, monkeypatch_resolver): app = create_app(asgi) class SuchException(Exception): pass class FaultyHandler(media.BaseHandler): def deserialize(self, stream, content_type, content_length): raise SuchException('Wow such error.') def deserialize_async(self, stream, content_type, content_length): raise SuchException('Wow such error.') def serialize(self, media, content_type): raise SuchException('Wow such error.') handlers = media.Handlers({handler_mt: FaultyHandler()}) # NOTE(kgriffs): Test the pre-3.0 method. Although undocumented, it was # technically a public method, and so we make sure it still works here. if monkeypatch_resolver: def _resolve(media_type, default, raise_not_found=True): with pytest.warns(DeprecatedWarning, match='This undocumented method'): h = handlers.find_by_media_type( media_type, default, raise_not_found=raise_not_found) return h, None, None handlers._resolve = _resolve app.req_options.media_handlers = handlers app.resp_options.media_handlers = handlers class Resource: def on_get(self, req, resp): resp.media = {} def on_post(self, req, resp): req.media class ResourceAsync: async def on_get(self, req, resp): resp.media = {} async def on_post(self, req, resp): # NOTE(kgriffs): In this one case we use the property # instead of get_media(), in order to test that the # alias works as expected. await req.media app.add_route('/', ResourceAsync() if asgi else Resource()) # NOTE(kgriffs): Now that we install a default handler for # Exception, we have to clear them to test the path we want # to trigger. # TODO(kgriffs): Since we always add a default error handler # for Exception, should we take out the checks in the WSGI/ASGI # callable and just always assume it will be handled? If so, # it makes testing that the right exception is propagated harder; # I suppose we'll have to look at what is logged. app._error_handlers.clear() with pytest.raises(SuchException): testing.simulate_get(app, '/') with pytest.raises(SuchException): testing.simulate_post(app, '/', json={})