Функция обнаружения
def blueprint_site_map(app, blueprint, all_methods=False):
'''
utilizes Flask's built-in rule mapper to generate a
site-map of the application, returning a list of dicts, ex.
{
'endpoint' : repr(Blueprint)
'methods' : list
'rule' : /route
{
'''
reply = []
rules = list(app.url_map.iter_rules())
ignored_methods = set(() if all_methods else ('HEAD', 'OPTIONS'))
rule_methods = [','.join(sorted(rule.methods - ignored_methods)) for rule in rules]
for rule, methods in zip(rules, rule_methods):
if (rule.endpoint != 'static') and (rule.endpoint.startswith(blueprint)):
reply.append(dict(endpoint=rule.endpoint, methods=methods.split(','), rule=rule.rule))
return reply
Пример вывода
>>> blueprint_site_map(app, 'my_blueprint')
[
{
'endpoint': 'my_blueprint.foo',
'methods': ['GET', 'POST'],
'rule': '/auth/foo'
},
{
'endpoint': 'my_blueprint.bar',
'methods': ['DELETE', 'GET', 'POST'],
'rule': '/auth/bar'
}
]
Использование
def test_my_blueprint_is_protected(client):
from flask import current_app as app
obj = blueprint_site_map(app, 'my_blueprint')
for each in obj:
for method in each['methods']:
func = getattr(client, method)
url = each['rule'] # *see note
kwargs = {} # inject headers, etc if needed
response = func(url, **kwargs)
assert response.status_code == 401
Следует отметить, что если вы используете какие-либо параметризованные правила URL, такие как разрешающие и /foo
, и /foo/<string:s>
, вам нужно будет вручную шаблонизировать или отфильтровать их. Функция blueprint_site_map
будет включать в себя отдельные элементы списка для /foo
и /foo/<string:s>
, что при буквальном рассмотрении вызовет проблемы либо у самого тестового клиента, либо у вашего маршрута. c.
Обнаружение Функция создана таким образом, что вы можете использовать это соглашение для стольких различных чертежей, сколько необходимо, что по самой природе вашего использования соглашения Blueprint означает, что вы можете сохранять свои модульные тесты такими же модульными, как и приложение.
Ура!