sanic/tests/test_blueprint_group.py

250 lines
7.6 KiB
Python
Raw Normal View History

Enable Middleware Support for Blueprint Groups (#1399) * enable blueprint group middleware support This commit will enable the users to implement a middleware at the blueprint group level whereby enforcing the middleware automatically to each of the available Blueprints that are part of the group. This will eanble a simple way in which a certain set of common features and criteria can be enforced on a Blueprint group. i.e. authentication and authorization This commit will address the feature request raised as part of Issue #1386 Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * enable indexing of BlueprintGroup object Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * rename blueprint group file to fix spelling error Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add documentation and additional unit tests Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup and optimize headers in unit test file Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix Bluprint Group iteratable method Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add additional unit test to check StopIteration condition Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup iter protocol implemenation for blueprint group and add slots Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix blueprint group middleware invocation identification Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * feat: enable list behavior on blueprint group object and use append instead of properly to add blueprint to group Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2019-03-03 22:26:05 +00:00
from pytest import raises
from sanic.app import Sanic
from sanic.blueprint_group import BlueprintGroup
2021-03-11 15:09:18 +00:00
from sanic.blueprints import Blueprint
Enable Middleware Support for Blueprint Groups (#1399) * enable blueprint group middleware support This commit will enable the users to implement a middleware at the blueprint group level whereby enforcing the middleware automatically to each of the available Blueprints that are part of the group. This will eanble a simple way in which a certain set of common features and criteria can be enforced on a Blueprint group. i.e. authentication and authorization This commit will address the feature request raised as part of Issue #1386 Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * enable indexing of BlueprintGroup object Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * rename blueprint group file to fix spelling error Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add documentation and additional unit tests Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup and optimize headers in unit test file Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix Bluprint Group iteratable method Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add additional unit test to check StopIteration condition Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup iter protocol implemenation for blueprint group and add slots Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix blueprint group middleware invocation identification Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * feat: enable list behavior on blueprint group object and use append instead of properly to add blueprint to group Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2019-03-03 22:26:05 +00:00
from sanic.request import Request
from sanic.response import HTTPResponse, text
Enable Middleware Support for Blueprint Groups (#1399) * enable blueprint group middleware support This commit will enable the users to implement a middleware at the blueprint group level whereby enforcing the middleware automatically to each of the available Blueprints that are part of the group. This will eanble a simple way in which a certain set of common features and criteria can be enforced on a Blueprint group. i.e. authentication and authorization This commit will address the feature request raised as part of Issue #1386 Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * enable indexing of BlueprintGroup object Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * rename blueprint group file to fix spelling error Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add documentation and additional unit tests Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup and optimize headers in unit test file Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix Bluprint Group iteratable method Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add additional unit test to check StopIteration condition Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup iter protocol implemenation for blueprint group and add slots Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix blueprint group middleware invocation identification Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * feat: enable list behavior on blueprint group object and use append instead of properly to add blueprint to group Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2019-03-03 22:26:05 +00:00
MIDDLEWARE_INVOKE_COUNTER = {"request": 0, "response": 0}
AUTH = "dGVzdDp0ZXN0Cg=="
def test_bp_group_indexing(app: Sanic):
blueprint_1 = Blueprint("blueprint_1", url_prefix="/bp1")
blueprint_2 = Blueprint("blueprint_2", url_prefix="/bp2")
group = Blueprint.group(blueprint_1, blueprint_2)
assert group[0] == blueprint_1
with raises(expected_exception=IndexError) as e:
_ = group[3]
def test_bp_group_with_additional_route_params(app: Sanic):
blueprint_1 = Blueprint("blueprint_1", url_prefix="/bp1")
blueprint_2 = Blueprint("blueprint_2", url_prefix="/bp2")
@blueprint_1.route(
"/request_path", methods=frozenset({"PUT", "POST"}), version=2
)
def blueprint_1_v2_method_with_put_and_post(request: Request):
if request.method == "PUT":
return text("PUT_OK")
elif request.method == "POST":
return text("POST_OK")
@blueprint_2.route(
"/route/<param>", methods=frozenset({"DELETE", "PATCH"}), name="test"
)
def blueprint_2_named_method(request: Request, param):
if request.method == "DELETE":
return text(f"DELETE_{param}")
Enable Middleware Support for Blueprint Groups (#1399) * enable blueprint group middleware support This commit will enable the users to implement a middleware at the blueprint group level whereby enforcing the middleware automatically to each of the available Blueprints that are part of the group. This will eanble a simple way in which a certain set of common features and criteria can be enforced on a Blueprint group. i.e. authentication and authorization This commit will address the feature request raised as part of Issue #1386 Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * enable indexing of BlueprintGroup object Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * rename blueprint group file to fix spelling error Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add documentation and additional unit tests Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup and optimize headers in unit test file Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix Bluprint Group iteratable method Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add additional unit test to check StopIteration condition Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup iter protocol implemenation for blueprint group and add slots Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix blueprint group middleware invocation identification Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * feat: enable list behavior on blueprint group object and use append instead of properly to add blueprint to group Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2019-03-03 22:26:05 +00:00
elif request.method == "PATCH":
return text(f"PATCH_{param}")
Enable Middleware Support for Blueprint Groups (#1399) * enable blueprint group middleware support This commit will enable the users to implement a middleware at the blueprint group level whereby enforcing the middleware automatically to each of the available Blueprints that are part of the group. This will eanble a simple way in which a certain set of common features and criteria can be enforced on a Blueprint group. i.e. authentication and authorization This commit will address the feature request raised as part of Issue #1386 Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * enable indexing of BlueprintGroup object Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * rename blueprint group file to fix spelling error Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add documentation and additional unit tests Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup and optimize headers in unit test file Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix Bluprint Group iteratable method Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add additional unit test to check StopIteration condition Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup iter protocol implemenation for blueprint group and add slots Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix blueprint group middleware invocation identification Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * feat: enable list behavior on blueprint group object and use append instead of properly to add blueprint to group Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2019-03-03 22:26:05 +00:00
blueprint_group = Blueprint.group(
blueprint_1, blueprint_2, url_prefix="/api"
)
@blueprint_group.middleware("request")
def authenticate_request(request: Request):
global AUTH
auth = request.headers.get("authorization")
if auth:
# Dummy auth check. We can have anything here and it's fine.
if AUTH not in auth:
return text("Unauthorized", status=401)
else:
return text("Unauthorized", status=401)
@blueprint_group.middleware("response")
def enhance_response_middleware(request: Request, response: HTTPResponse):
response.headers.add("x-test-middleware", "value")
app.blueprint(blueprint_group)
header = {"authorization": " ".join(["Basic", AUTH])}
_, response = app.test_client.put(
"/v2/api/bp1/request_path", headers=header
)
assert response.text == "PUT_OK"
assert response.headers.get("x-test-middleware") == "value"
_, response = app.test_client.post(
"/v2/api/bp1/request_path", headers=header
)
assert response.text == "POST_OK"
_, response = app.test_client.delete("/api/bp2/route/bp2", headers=header)
assert response.text == "DELETE_bp2"
_, response = app.test_client.patch("/api/bp2/route/bp2", headers=header)
assert response.text == "PATCH_bp2"
_, response = app.test_client.put("/v2/api/bp1/request_path")
Enable Middleware Support for Blueprint Groups (#1399) * enable blueprint group middleware support This commit will enable the users to implement a middleware at the blueprint group level whereby enforcing the middleware automatically to each of the available Blueprints that are part of the group. This will eanble a simple way in which a certain set of common features and criteria can be enforced on a Blueprint group. i.e. authentication and authorization This commit will address the feature request raised as part of Issue #1386 Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * enable indexing of BlueprintGroup object Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * rename blueprint group file to fix spelling error Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add documentation and additional unit tests Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup and optimize headers in unit test file Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix Bluprint Group iteratable method Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add additional unit test to check StopIteration condition Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup iter protocol implemenation for blueprint group and add slots Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix blueprint group middleware invocation identification Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * feat: enable list behavior on blueprint group object and use append instead of properly to add blueprint to group Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2019-03-03 22:26:05 +00:00
assert response.status == 401
def test_bp_group(app: Sanic):
blueprint_1 = Blueprint("blueprint_1", url_prefix="/bp1")
blueprint_2 = Blueprint("blueprint_2", url_prefix="/bp2")
@blueprint_1.route("/")
def blueprint_1_default_route(request):
return text("BP1_OK")
@blueprint_2.route("/")
def blueprint_2_default_route(request):
return text("BP2_OK")
blueprint_group_1 = Blueprint.group(
blueprint_1, blueprint_2, url_prefix="/bp"
)
blueprint_3 = Blueprint("blueprint_3", url_prefix="/bp3")
@blueprint_group_1.middleware("request")
def blueprint_group_1_middleware(request):
global MIDDLEWARE_INVOKE_COUNTER
MIDDLEWARE_INVOKE_COUNTER["request"] += 1
2021-02-15 19:50:20 +00:00
@blueprint_group_1.middleware
def blueprint_group_1_middleware_not_called(request):
global MIDDLEWARE_INVOKE_COUNTER
MIDDLEWARE_INVOKE_COUNTER["request"] += 1
Enable Middleware Support for Blueprint Groups (#1399) * enable blueprint group middleware support This commit will enable the users to implement a middleware at the blueprint group level whereby enforcing the middleware automatically to each of the available Blueprints that are part of the group. This will eanble a simple way in which a certain set of common features and criteria can be enforced on a Blueprint group. i.e. authentication and authorization This commit will address the feature request raised as part of Issue #1386 Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * enable indexing of BlueprintGroup object Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * rename blueprint group file to fix spelling error Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add documentation and additional unit tests Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup and optimize headers in unit test file Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix Bluprint Group iteratable method Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add additional unit test to check StopIteration condition Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup iter protocol implemenation for blueprint group and add slots Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix blueprint group middleware invocation identification Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * feat: enable list behavior on blueprint group object and use append instead of properly to add blueprint to group Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2019-03-03 22:26:05 +00:00
@blueprint_3.route("/")
def blueprint_3_default_route(request):
return text("BP3_OK")
blueprint_group_2 = Blueprint.group(
blueprint_group_1, blueprint_3, url_prefix="/api"
)
@blueprint_group_2.middleware("response")
def blueprint_group_2_middleware(request, response):
global MIDDLEWARE_INVOKE_COUNTER
MIDDLEWARE_INVOKE_COUNTER["response"] += 1
app.blueprint(blueprint_group_2)
@app.route("/")
def app_default_route(request):
return text("APP_OK")
_, response = app.test_client.get("/")
assert response.text == "APP_OK"
_, response = app.test_client.get("/api/bp/bp1")
assert response.text == "BP1_OK"
_, response = app.test_client.get("/api/bp/bp2")
assert response.text == "BP2_OK"
_, response = app.test_client.get("/api/bp3")
assert response.text == "BP3_OK"
assert MIDDLEWARE_INVOKE_COUNTER["response"] == 3
2021-02-15 19:50:20 +00:00
assert MIDDLEWARE_INVOKE_COUNTER["request"] == 4
Enable Middleware Support for Blueprint Groups (#1399) * enable blueprint group middleware support This commit will enable the users to implement a middleware at the blueprint group level whereby enforcing the middleware automatically to each of the available Blueprints that are part of the group. This will eanble a simple way in which a certain set of common features and criteria can be enforced on a Blueprint group. i.e. authentication and authorization This commit will address the feature request raised as part of Issue #1386 Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * enable indexing of BlueprintGroup object Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * rename blueprint group file to fix spelling error Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add documentation and additional unit tests Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup and optimize headers in unit test file Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix Bluprint Group iteratable method Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * add additional unit test to check StopIteration condition Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * cleanup iter protocol implemenation for blueprint group and add slots Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * fix blueprint group middleware invocation identification Signed-off-by: Harsha Narayana <harsha2k4@gmail.com> * feat: enable list behavior on blueprint group object and use append instead of properly to add blueprint to group Signed-off-by: Harsha Narayana <harsha2k4@gmail.com>
2019-03-03 22:26:05 +00:00
def test_bp_group_list_operations(app: Sanic):
blueprint_1 = Blueprint("blueprint_1", url_prefix="/bp1")
blueprint_2 = Blueprint("blueprint_2", url_prefix="/bp2")
@blueprint_1.route("/")
def blueprint_1_default_route(request):
return text("BP1_OK")
@blueprint_2.route("/")
def blueprint_2_default_route(request):
return text("BP2_OK")
blueprint_group_1 = Blueprint.group(
blueprint_1, blueprint_2, url_prefix="/bp"
)
blueprint_3 = Blueprint("blueprint_2", url_prefix="/bp3")
@blueprint_3.route("/second")
def blueprint_3_second_route(request):
return text("BP3_OK")
assert len(blueprint_group_1) == 2
blueprint_group_1.append(blueprint_3)
assert len(blueprint_group_1) == 3
del blueprint_group_1[2]
assert len(blueprint_group_1) == 2
blueprint_group_1[1] = blueprint_3
assert len(blueprint_group_1) == 2
assert blueprint_group_1.url_prefix == "/bp"
2021-02-15 19:50:20 +00:00
def test_bp_group_as_list():
blueprint_1 = Blueprint("blueprint_1", url_prefix="/bp1")
blueprint_2 = Blueprint("blueprint_2", url_prefix="/bp2")
blueprint_group_1 = Blueprint.group([blueprint_1, blueprint_2])
assert len(blueprint_group_1) == 2
def test_bp_group_as_nested_group():
blueprint_1 = Blueprint("blueprint_1", url_prefix="/bp1")
blueprint_2 = Blueprint("blueprint_2", url_prefix="/bp2")
blueprint_group_1 = Blueprint.group(
Blueprint.group(blueprint_1, blueprint_2)
)
assert len(blueprint_group_1) == 2
def test_blueprint_group_insert():
blueprint_1 = Blueprint(
"blueprint_1", url_prefix="/bp1", strict_slashes=True, version=1
)
blueprint_2 = Blueprint("blueprint_2", url_prefix="/bp2")
blueprint_3 = Blueprint("blueprint_3", url_prefix=None)
group = BlueprintGroup(
url_prefix="/test", version=1.3, strict_slashes=False
)
group.insert(0, blueprint_1)
group.insert(0, blueprint_2)
group.insert(0, blueprint_3)
assert group.blueprints[1].strict_slashes is False
assert group.blueprints[2].strict_slashes is True
assert group.blueprints[0].url_prefix == "/test"
def test_bp_group_properties():
blueprint_1 = Blueprint("blueprint_1", url_prefix="/bp1")
blueprint_2 = Blueprint("blueprint_2", url_prefix="/bp2")
group = Blueprint.group(
blueprint_1,
blueprint_2,
version=1,
version_prefix="/api/v",
url_prefix="/grouped",
strict_slashes=True,
)
assert group.version_prefix == "/api/v"
assert blueprint_1.version_prefix == "/api/v"
assert blueprint_2.version_prefix == "/api/v"
assert group.version == 1
assert blueprint_1.version == 1
assert blueprint_2.version == 1
assert group.strict_slashes
assert blueprint_1.strict_slashes
assert blueprint_2.strict_slashes
assert group.url_prefix == "/grouped"
assert blueprint_1.url_prefix == "/grouped/bp1"
assert blueprint_2.url_prefix == "/grouped/bp2"