import copy from flask import url_for, Blueprint import flask_restx as restx class APITest(object): def test_root_endpoint(self, app): api = restx.Api(app, version="1.0") with app.test_request_context(): url = url_for("root") assert url == "/" assert api.base_url == "http://localhost/" def test_root_endpoint_lazy(self, app): api = restx.Api(version="1.0") api.init_app(app) with app.test_request_context(): url = url_for("root") assert url == "/" assert api.base_url == "http://localhost/" def test_root_endpoint_with_blueprint(self, app): blueprint = Blueprint("api", __name__, url_prefix="/api") api = restx.Api(blueprint, version="1.0") app.register_blueprint(blueprint) with app.test_request_context(): url = url_for("api.root") assert url == "/api/" assert api.base_url == "http://localhost/api/" def test_root_endpoint_with_blueprint_with_subdomain(self, app): blueprint = Blueprint("api", __name__, subdomain="api", url_prefix="/api") api = restx.Api(blueprint, version="1.0") app.register_blueprint(blueprint) with app.test_request_context(): url = url_for("api.root") assert url == "http://api.localhost/api/" assert api.base_url == "http://api.localhost/api/" def test_parser(self): api = restx.Api() assert isinstance(api.parser(), restx.reqparse.RequestParser) def test_doc_decorator(self, app): api = restx.Api(app, prefix="/api", version="1.0") params = {"q": {"description": "some description"}} @api.doc(params=params) class TestResource(restx.Resource): pass assert hasattr(TestResource, "__apidoc__") assert TestResource.__apidoc__ == {"params": params} def test_doc_with_inheritance(self, app): api = restx.Api(app, prefix="/api", version="1.0") base_params = { "q": { "description": "some description", "type": "string", "paramType": "query", } } child_params = { "q": {"description": "some new description"}, "other": {"description": "another param"}, } @api.doc(params=base_params) class BaseResource(restx.Resource): pass @api.doc(params=child_params) class TestResource(BaseResource): pass assert TestResource.__apidoc__ == { "params": { "q": { "description": "some new description", "type": "string", "paramType": "query", }, "other": {"description": "another param"}, } } def test_specs_endpoint_not_added(self, app): api = restx.Api() api.init_app(app, add_specs=False) assert "specs" not in api.endpoints assert "specs" not in app.view_functions def test_specs_endpoint_not_found_if_not_added(self, app, client): api = restx.Api() api.init_app(app, add_specs=False) resp = client.get("/swagger.json") assert resp.status_code == 404 def test_default_endpoint(self, app): api = restx.Api(app) @api.route("/test/") class TestResource(restx.Resource): pass with app.test_request_context(): assert url_for("test_resource") == "/test/" def test_default_endpoint_lazy(self, app): api = restx.Api() @api.route("/test/") class TestResource(restx.Resource): pass api.init_app(app) with app.test_request_context(): assert url_for("test_resource") == "/test/" def test_default_endpoint_with_blueprint(self, app): blueprint = Blueprint("api", __name__, url_prefix="/api") api = restx.Api(blueprint) app.register_blueprint(blueprint) @api.route("/test/") class TestResource(restx.Resource): pass with app.test_request_context(): assert url_for("api.test_resource") == "/api/test/" def test_default_endpoint_with_blueprint_with_subdomain(self, app): blueprint = Blueprint("api", __name__, subdomain="api", url_prefix="/api") api = restx.Api(blueprint) app.register_blueprint(blueprint) @api.route("/test/") class TestResource(restx.Resource): pass with app.test_request_context(): assert url_for("api.test_resource") == "http://api.localhost/api/test/" def test_default_endpoint_for_namespace(self, app): api = restx.Api(app) ns = api.namespace("ns", "Test namespace") @ns.route("/test/") class TestResource(restx.Resource): pass with app.test_request_context(): assert url_for("ns_test_resource") == "/ns/test/" def test_default_endpoint_lazy_for_namespace(self, app): api = restx.Api() ns = api.namespace("ns", "Test namespace") @ns.route("/test/") class TestResource(restx.Resource): pass api.init_app(app) with app.test_request_context(): assert url_for("ns_test_resource") == "/ns/test/" def test_default_endpoint_for_namespace_with_blueprint(self, app): blueprint = Blueprint("api", __name__, url_prefix="/api") api = restx.Api(blueprint) ns = api.namespace("ns", "Test namespace") @ns.route("/test/") class TestResource(restx.Resource): pass app.register_blueprint(blueprint) with app.test_request_context(): assert url_for("api.ns_test_resource") == "/api/ns/test/" def test_multiple_default_endpoint(self, app): api = restx.Api(app) @api.route("/test2/") @api.route("/test/") class TestResource(restx.Resource): pass with app.test_request_context(): assert url_for("test_resource") == "/test/" assert url_for("test_resource_2") == "/test2/" def test_multiple_default_endpoint_lazy(self, app): api = restx.Api() @api.route("/test2/") @api.route("/test/") class TestResource(restx.Resource): pass api.init_app(app) with app.test_request_context(): assert url_for("test_resource") == "/test/" assert url_for("test_resource_2") == "/test2/" def test_multiple_default_endpoint_for_namespace(self, app): api = restx.Api(app) ns = api.namespace("ns", "Test namespace") @ns.route("/test2/") @ns.route("/test/") class TestResource(restx.Resource): pass with app.test_request_context(): assert url_for("ns_test_resource") == "/ns/test/" assert url_for("ns_test_resource_2") == "/ns/test2/" def test_multiple_default_endpoint_lazy_for_namespace(self, app): api = restx.Api() ns = api.namespace("ns", "Test namespace") @ns.route("/test2/") @ns.route("/test/") class TestResource(restx.Resource): pass api.init_app(app) with app.test_request_context(): assert url_for("ns_test_resource") == "/ns/test/" assert url_for("ns_test_resource_2") == "/ns/test2/" def test_multiple_default_endpoint_for_namespace_with_blueprint(self, app): blueprint = Blueprint("api", __name__, url_prefix="/api") api = restx.Api(blueprint) ns = api.namespace("ns", "Test namespace") @ns.route("/test2/") @ns.route("/test/") class TestResource(restx.Resource): pass app.register_blueprint(blueprint) with app.test_request_context(): assert url_for("api.ns_test_resource") == "/api/ns/test/" assert url_for("api.ns_test_resource_2") == "/api/ns/test2/" def test_ns_path_prefixes(self, app): api = restx.Api() ns = restx.Namespace("test_ns", description="Test namespace") @ns.route("/test/", endpoint="test_resource") class TestResource(restx.Resource): pass api.add_namespace(ns, "/api_test") api.init_app(app) with app.test_request_context(): assert url_for("test_resource") == "/api_test/test/" def test_multiple_ns_with_authorizations(self, app): api = restx.Api() a1 = {"apikey": {"type": "apiKey", "in": "header", "name": "X-API"}} a2 = { "oauth2": { "type": "oauth2", "flow": "accessCode", "tokenUrl": "https://somewhere.com/token", "scopes": { "read": "Grant read-only access", "write": "Grant read-write access", }, } } ns1 = restx.Namespace("ns1", authorizations=a1) ns2 = restx.Namespace("ns2", authorizations=a2) @ns1.route("/") class Ns1(restx.Resource): @ns1.doc(security="apikey") def get(self): pass @ns2.route("/") class Ns2(restx.Resource): @ns1.doc(security="oauth2") def post(self): pass api.add_namespace(ns1, path="/ns1") api.add_namespace(ns2, path="/ns2") api.init_app(app) assert {"apikey": []} in api.__schema__["paths"]["/ns1/"]["get"]["security"] assert {"oauth2": []} in api.__schema__["paths"]["/ns2/"]["post"]["security"] unified_auth = copy.copy(a1) unified_auth.update(a2) assert api.__schema__["securityDefinitions"] == unified_auth def test_non_ordered_namespace(self, app): api = restx.Api(app) ns = api.namespace("ns", "Test namespace") assert not ns.ordered def test_ordered_namespace(self, app): api = restx.Api(app, ordered=True) ns = api.namespace("ns", "Test namespace") assert ns.ordered def test_decorators(self, app, mocker): decorator1 = mocker.Mock(return_value=lambda x: x) decorator2 = mocker.Mock(return_value=lambda x: x) decorator3 = mocker.Mock(return_value=lambda x: x) class TestResource(restx.Resource): method_decorators = [] api = restx.Api(decorators=[decorator1]) ns = api.namespace("test_ns", decorators=[decorator2, decorator3]) ns.add_resource(TestResource, "/test", endpoint="test") api.init_app(app) assert decorator1.called is True assert decorator2.called is True assert decorator3.called is True def test_specs_url(self, app): api = restx.Api(app) specs_url = api.specs_url assert specs_url == "/swagger.json" def test_url_scheme(self, app): api = restx.Api(app, url_scheme="https") assert api.specs_url == "https://localhost/swagger.json" assert api.base_url == "https://localhost/"