def hydrated_client_multiple_middleware(): """Create a server for testing, with all included middlewares""" data_store = DataStore() class PhilosopherResource: schema = Philosopher() def on_get(self, req, resp, phil_id): """Get a philosopher""" req.context["result"] = data_store.get(phil_id) class PhilosopherCollection: schema = Philosopher() def on_post(self, req, resp): req.context["result"] = data_store.insert(req.context["json"]) app = API(middleware=[ m.Marshmallow(), m.JSONEnforcer(), m.EmptyRequestDropper() ]) app.add_route("/philosophers", PhilosopherCollection()) app.add_route("/philosophers/{phil_id}", PhilosopherResource()) yield testing.TestClient(app) data_store.clear()
def hydrated_client_multiple_middleware(): """A Falcon API with an endpoint for testing Marshmallow, with all included middlewares registered.""" data_store = DataStore() class PhilosopherResource: schema = Philosopher() def on_get(self, req, resp, phil_id): """Get a philosopher""" req.context['result'] = data_store.get(phil_id) class PhilosopherCollection: schema = Philosopher() def on_post(self, req, resp): req.context['result'] = data_store.insert(req.context['json']) app = API(middleware=[ m.Marshmallow(), m.JSONEnforcer(), m.EmptyRequestDropper()]) app.add_route('/philosophers', PhilosopherCollection()) app.add_route('/philosophers/{phil_id}', PhilosopherResource()) yield testing.TestClient(app) data_store.clear()
class TestJSONEnforcer: """Test enforcement of JSON requests""" enforcer = mid.JSONEnforcer() @pytest.mark.parametrize("accepts", [True, False]) def test_client_accept(self, accepts): # type: (bool) -> None """Test asserting that the client accepts JSON""" req = mock.Mock() req.client_accepts_json = accepts req.method = "GET" if not accepts: with pytest.raises(errors.HTTPNotAcceptable): # noinspection PyTypeChecker self.enforcer.process_request(req, "foo") else: # noinspection PyTypeChecker self.enforcer.process_request(req, "foo") @pytest.mark.parametrize( "method, content_type, raises", [ ("GET", None, False), ("GET", "application/json", False), ("GET", "mimetype/xml", False), ("POST", None, True), ("POST", "application/json", False), ("POST", "mimetype/xml", True), ("PATCH", None, True), ("PATCH", "application/json", False), ("PATCH", "mimetype/xml", True), ("PUT", None, True), ("PUT", "application/json", False), ("PUT", "mimetype/xml", True), ("DELETE", None, False), ("DELETE", "application/json", False), ("DELETE", "mimetype/xml", False), ], ) def test_method_content_type(self, method, content_type, raises): # type: (str, Optional[str], bool) -> None """Test checking of content-type for certain methods""" req = mock.Mock(client_accepts_json=True) req.method = method req.content_type = content_type if raises: with pytest.raises(errors.HTTPUnsupportedMediaType): # noinspection PyTypeChecker self.enforcer.process_request(req, "foo") else: # noinspection PyTypeChecker self.enforcer.process_request(req, "foo")
def test_content_type_json_required(self, endpoint, method, endpoint_exists, ct_is_json, required): # type: (str, str, bool, bool, bool) -> None """Test HTTP methods that should reuquire content-type json Note ``required`` is always true at the moment, because the middleware applies to all requests with no exceptions. If that changes, add parameters above. The endpoint here does not really matter, because ``process_request`` middleware, which handles enforcement of the accept header, is processed before routing. However, the ``endpoint_exists`` option is provided in case it is necessary in the future to ensure this is called against a real endpoint. """ client = testing.TestClient(API(middleware=[m.JSONEnforcer()])) if ct_is_json: heads = {'Content-Type': str('application/json')} else: heads = {} res = client.simulate_request( method=str(method), path=endpoint, headers=heads ) # type: testing.Result meth_not_allowed = status_codes.HTTP_METHOD_NOT_ALLOWED if required: if method in m.JSON_CONTENT_REQUIRED_METHODS: # Ensure that non-json content type is denied if ct_is_json: if endpoint_exists: assert bool( 200 <= res.status_code < 300 or res.status_code == meth_not_allowed ) else: assert res.status == status_codes.HTTP_NOT_FOUND else: exp_code = status_codes.HTTP_UNSUPPORTED_MEDIA_TYPE assert res.status == exp_code else: # We shouldn't deny for non-json content type if endpoint_exists: assert bool( 200 <= res.status_code < 300 or res.status_code == meth_not_allowed ) else: assert res.status == status_codes.HTTP_NOT_FOUND else: # No endpoints for which this is applicable exist at the moment pass
def test_accepts_json_required(self, endpoint, accepts, required, endpoint_exists): # type: (str, bool, bool, bool) -> None """Test that application/json is required in the accepts header Note ``required`` is always true at the moment, because the middleware applies to all requests with no exceptions. If that changes, add parameters above. The endpoint here does not really matter, because ``process_request`` middleware, which handles enforcement of the accept header, is processed before routing. However, the ``endpoint_exists`` option is provided in case it is necessary in the future to ensure this is called against a real endpoint. """ client = testing.TestClient(API(middleware=[m.JSONEnforcer()])) if accepts: heads = {'Accept': str('application/json')} else: heads = {'Accept': str('mimetype/xml')} res = client.simulate_get( endpoint, headers=heads ) # type: testing.Result if required: if accepts: if endpoint_exists: assert bool( 200 <= res.status_code < 300 or res.status_code == status_codes.HTTP_METHOD_NOT_ALLOWED ) else: assert res.status == status_codes.HTTP_NOT_FOUND else: assert res.status == status_codes.HTTP_NOT_ACCEPTABLE else: # Not currently needed or implemented pass