forked from Github-Mirrors/canaille
Enable jinja2 strict mode in unit tests
This commit is contained in:
parent
f7007544ec
commit
1a0a8096eb
8 changed files with 75 additions and 120 deletions
|
@ -55,6 +55,9 @@ def test_html(user):
|
|||
site_name=current_app.config.get("NAME", "Canaille"),
|
||||
site_url=base_url,
|
||||
logo=current_app.config.get("LOGO"),
|
||||
title=_("Test email from {website_name}").format(
|
||||
website_name=current_app.config.get("NAME", "Canaille"),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
@ -77,6 +80,9 @@ def password_init_html(user):
|
|||
"account.reset",
|
||||
user=user,
|
||||
hash=profile_hash(user.identifier, user.preferred_email, user.password[0]),
|
||||
title=_("Password initialization on {website_name}").format(
|
||||
website_name=current_app.config.get("NAME", "Canaille")
|
||||
),
|
||||
_external=True,
|
||||
)
|
||||
|
||||
|
@ -87,7 +93,7 @@ def password_init_html(user):
|
|||
reset_url=reset_url,
|
||||
logo=current_app.config.get("LOGO"),
|
||||
title=_("Password initialization on {website_name}").format(
|
||||
website_name=current_app.config.get("NAME", reset_url)
|
||||
website_name=current_app.config.get("NAME", "Canaille")
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -105,7 +111,7 @@ def password_init_txt(user):
|
|||
|
||||
return render_template(
|
||||
"mail/firstlogin.txt",
|
||||
site_name=current_app.config.get("NAME", reset_url),
|
||||
site_name=current_app.config.get("NAME", "Canaille"),
|
||||
site_url=current_app.config.get("SERVER_NAME", base_url),
|
||||
reset_url=reset_url,
|
||||
)
|
||||
|
@ -119,6 +125,9 @@ def password_reset_html(user):
|
|||
"account.reset",
|
||||
user=user,
|
||||
hash=profile_hash(user.identifier, user.preferred_email, user.password[0]),
|
||||
title=_("Password reset on {website_name}").format(
|
||||
website_name=current_app.config.get("NAME", "")
|
||||
),
|
||||
_external=True,
|
||||
)
|
||||
|
||||
|
@ -129,7 +138,7 @@ def password_reset_html(user):
|
|||
reset_url=reset_url,
|
||||
logo=current_app.config.get("LOGO"),
|
||||
title=_("Password reset on {website_name}").format(
|
||||
website_name=current_app.config.get("NAME", reset_url)
|
||||
website_name=current_app.config.get("NAME", base_url)
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ def send_test_mail(email):
|
|||
site_name=current_app.config.get("NAME", "Canaille"),
|
||||
site_url=base_url,
|
||||
logo=f"cid:{logo_cid[1:-1]}" if logo_cid else None,
|
||||
title=subject,
|
||||
)
|
||||
|
||||
return send_email(
|
||||
|
@ -50,20 +51,21 @@ def send_password_reset_mail(user, mail):
|
|||
logo_cid, logo_filename, logo_raw = logo()
|
||||
|
||||
subject = _("Password reset on {website_name}").format(
|
||||
website_name=current_app.config.get("NAME", reset_url)
|
||||
website_name=current_app.config.get("NAME", base_url)
|
||||
)
|
||||
text_body = render_template(
|
||||
"mail/reset.txt",
|
||||
site_name=current_app.config.get("NAME", reset_url),
|
||||
site_name=current_app.config.get("NAME", base_url),
|
||||
site_url=base_url,
|
||||
reset_url=reset_url,
|
||||
)
|
||||
html_body = render_template(
|
||||
"mail/reset.html",
|
||||
site_name=current_app.config.get("NAME", reset_url),
|
||||
site_name=current_app.config.get("NAME", base_url),
|
||||
site_url=base_url,
|
||||
reset_url=reset_url,
|
||||
logo=f"cid:{logo_cid[1:-1]}" if logo_cid else None,
|
||||
title=subject,
|
||||
)
|
||||
|
||||
return send_email(
|
||||
|
@ -90,20 +92,21 @@ def send_password_initialization_mail(user, email):
|
|||
logo_cid, logo_filename, logo_raw = logo()
|
||||
|
||||
subject = _("Password initialization on {website_name}").format(
|
||||
website_name=current_app.config.get("NAME", reset_url)
|
||||
website_name=current_app.config.get("NAME", base_url)
|
||||
)
|
||||
text_body = render_template(
|
||||
"mail/firstlogin.txt",
|
||||
site_name=current_app.config.get("NAME", reset_url),
|
||||
site_name=current_app.config.get("NAME", base_url),
|
||||
site_url=base_url,
|
||||
reset_url=reset_url,
|
||||
)
|
||||
html_body = render_template(
|
||||
"mail/firstlogin.html",
|
||||
site_name=current_app.config.get("NAME", reset_url),
|
||||
site_name=current_app.config.get("NAME", base_url),
|
||||
site_url=base_url,
|
||||
reset_url=reset_url,
|
||||
logo=f"cid:{logo_cid[1:-1]}" if logo_cid else None,
|
||||
title=subject,
|
||||
)
|
||||
|
||||
return send_email(
|
||||
|
@ -120,20 +123,21 @@ def send_invitation_mail(email, registration_url):
|
|||
logo_cid, logo_filename, logo_raw = logo()
|
||||
|
||||
subject = _("You have been invited to create an account on {website_name}").format(
|
||||
website_name=current_app.config.get("NAME", registration_url)
|
||||
website_name=current_app.config.get("NAME", base_url)
|
||||
)
|
||||
text_body = render_template(
|
||||
"mail/invitation.txt",
|
||||
site_name=current_app.config.get("NAME", registration_url),
|
||||
site_name=current_app.config.get("NAME", base_url),
|
||||
site_url=base_url,
|
||||
registration_url=registration_url,
|
||||
)
|
||||
html_body = render_template(
|
||||
"mail/invitation.html",
|
||||
site_name=current_app.config.get("NAME", registration_url),
|
||||
site_name=current_app.config.get("NAME", base_url),
|
||||
site_url=base_url,
|
||||
registration_url=registration_url,
|
||||
logo=f"cid:{logo_cid[1:-1]}" if logo_cid else None,
|
||||
title=subject,
|
||||
)
|
||||
|
||||
return send_email(
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{% block content %}
|
||||
<div class="ui error icon message">
|
||||
{% if icon and (debug or (user and user.can_manage_oidc)) %}
|
||||
{% if icon is defined and (debug or (user and user.can_manage_oidc)) %}
|
||||
<i class="{{ icon }} icon"></i>
|
||||
{% elif error_code == 400 %}
|
||||
<i class="question icon"></i>
|
||||
|
|
|
@ -183,12 +183,12 @@ id=none,
|
|||
csrf=true) -%}
|
||||
<form method="POST"
|
||||
id="{{ id or form.__class__.__name__|lower }}"
|
||||
action="{{ action or form.action }}"
|
||||
action="{% if action %}{{ action }}{% elif form.action is defined %}{{ form.action }}{% endif %}"
|
||||
role="form"
|
||||
enctype="multipart/form-data"
|
||||
class="ui form {{ class_ }}"
|
||||
>
|
||||
{% if caller %}
|
||||
{% if caller is defined %}
|
||||
{% if csrf %}
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
{% endif %}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
{{ form.hidden_tag() if form.hidden_tag }}
|
||||
<input type="hidden" name="page" value="{{ page }}">
|
||||
<input type="hidden" name="query" value="{{ form.query.data }}">
|
||||
{% if page == null %}
|
||||
{% if page is none %}
|
||||
<span class="icon disabled ui button" style="border-radius: 0">
|
||||
{{ caller() }}
|
||||
</span>
|
||||
|
@ -69,7 +69,7 @@
|
|||
<i class="left chevron icon"></i>
|
||||
{% endcall %}
|
||||
{% else %}
|
||||
{% call buttonform(form, "previous", null) %}
|
||||
{% call buttonform(form, "previous", none) %}
|
||||
<i class="left chevron icon"></i>
|
||||
{% endcall %}
|
||||
{% endif %}
|
||||
|
@ -79,7 +79,7 @@
|
|||
{% endcall %}
|
||||
{% endif %}
|
||||
{% if form.page.data > 2 %}
|
||||
{% call buttonform(form, "ellipsis-previous", null) %}
|
||||
{% call buttonform(form, "ellipsis-previous", none) %}
|
||||
…
|
||||
{% endcall %}
|
||||
{% endif %}
|
||||
|
@ -87,7 +87,7 @@
|
|||
{{ form.page.data }}
|
||||
</span>
|
||||
{% if form.page.data < form.page_max - 1 %}
|
||||
{% call buttonform(form, "ellipsis-next", null) %}
|
||||
{% call buttonform(form, "ellipsis-next", none) %}
|
||||
…
|
||||
{% endcall %}
|
||||
{% endif %}
|
||||
|
@ -101,7 +101,7 @@
|
|||
<i class="right chevron icon"></i>
|
||||
{% endcall %}
|
||||
{% else %}
|
||||
{% call buttonform(form, "next", null) %}
|
||||
{% call buttonform(form, "next", none) %}
|
||||
<i class="right chevron icon"></i>
|
||||
{% endcall %}
|
||||
{% endif %}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{% extends theme('base.html') %}
|
||||
{% import 'macro/form.html' as fui %}
|
||||
{% import 'partial/profile_field.html' as profile %}
|
||||
|
||||
{%- block title -%}
|
||||
{%- trans %}User creation{% endtrans -%}
|
||||
|
@ -28,64 +29,14 @@
|
|||
</nav>
|
||||
{% endblock %}
|
||||
|
||||
{% macro render_field(field, noindicator=false) %}
|
||||
{% set lock_indicator = field.render_kw and ("readonly" in field.render_kw or "disabled" in field.render_kw) %}
|
||||
{% if not edited_user %}
|
||||
{{ fui.render_field(field, **kwargs) }}
|
||||
{% elif edited_user.user_name == user.user_name or lock_indicator or noindicator %}
|
||||
{{ fui.render_field(field, **kwargs) }}
|
||||
{% elif field.name in edited_user.write %}
|
||||
{{ fui.render_field(field, **kwargs) }}
|
||||
{% elif field.name in edited_user.read %}
|
||||
{{ fui.render_field(field, indicator_icon="eye", indicator_text=_("This user cannot edit this field"), **kwargs) }}
|
||||
{% else %}
|
||||
{{ fui.render_field(field, indicator_icon="eye slash", indicator_text=_("This user cannot see this field"), **kwargs) }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block content %}
|
||||
{% if self_deletion or (user.can_manage_users and edited_user) %}
|
||||
<div id="modal-delete" class="ui basic modal">
|
||||
<div class="ui icon header">
|
||||
<i class="user minus icon"></i>
|
||||
{% trans %}Account deletion{% endtrans %}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>
|
||||
{% if user.user_name != edited_user.user_name %}
|
||||
{{ _("Are you sure you want to delete this user? This action is unrevokable and all the data about this user will be removed.") }}
|
||||
{% else %}
|
||||
{{ _("Are you sure you want to delete your account? This action is unrevokable and all your data will be removed forever.") }}
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui inverted cancel button">{% trans %}Cancel{% endtrans %}</div>
|
||||
<div class="ui inverted red approve button">{% trans %}Delete{% endtrans %}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="ui clearing segment">
|
||||
<h2 class="ui center aligned header">
|
||||
<div class="content">
|
||||
{% if not edited_user %}
|
||||
{% trans %}User creation{% endtrans %}
|
||||
{% elif user.user_name == edited_user.user_name %}
|
||||
{% trans %}My profile{% endtrans %}
|
||||
{% else %}
|
||||
{% trans %}User profile edition{% endtrans %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<div class="sub header">
|
||||
{% if not edited_user %}
|
||||
{% trans %}Create a new user account{% endtrans %}
|
||||
{% elif user.user_name == edited_user.user_name %}
|
||||
{% trans %}Edit your personal information{% endtrans %}
|
||||
{% else %}
|
||||
{% trans %}Edit information about a user{% endtrans %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
|
@ -96,9 +47,8 @@
|
|||
<div class="ui grid">
|
||||
<div class="three wide column">
|
||||
{% block photo_field scoped %}
|
||||
{{ render_field(form.photo, display=false, class="photo-field") }}
|
||||
{{ render_field(form.photo_delete, display=false, class="photo-delete-button") }}
|
||||
{% set photo = edited_user.photo and edited_user.photo[0] %}
|
||||
{{ profile.render_field(form.photo, display=false, class="photo-field") }}
|
||||
{{ profile.render_field(form.photo_delete, display=false, class="photo-delete-button") }}
|
||||
<label
|
||||
class="ui small bordered image photo-content"
|
||||
for="{{ form.photo.id }}"
|
||||
|
@ -113,8 +63,7 @@
|
|||
<label
|
||||
class="ui centered photo-placeholder"
|
||||
for="{{ form.photo.id }}"
|
||||
title="{{ _("Click to upload a photo") }}"
|
||||
{% if photo %}style="display: none;"{% endif %}>
|
||||
title="{{ _("Click to upload a photo") }}">
|
||||
<i class="massive centered portrait icon"></i>
|
||||
</label>
|
||||
{% endblock %}
|
||||
|
@ -126,116 +75,107 @@
|
|||
{% if "given_name" in form or "family_name" in form %}
|
||||
<div class="equal width fields">
|
||||
{% if "given_name" in form %}
|
||||
{% block given_name_field scoped %}{{ render_field(form.given_name) }}{% endblock %}
|
||||
{% block given_name_field scoped %}{{ profile.render_field(form.given_name) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "family_name" in form %}
|
||||
{% block family_name_field scoped %}{{ render_field(form.family_name) }}{% endblock %}
|
||||
{% block family_name_field scoped %}{{ profile.render_field(form.family_name) }}{% endblock %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if "display_name" in form %}
|
||||
{% block display_name_field scoped %}{{ render_field(form.display_name) }}{% endblock %}
|
||||
{% block display_name_field scoped %}{{ profile.render_field(form.display_name) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "photo" in form %}</div></div>{% endif %}
|
||||
|
||||
{% if "emails" in form %}
|
||||
{% block emails_field scoped %}{{ render_field(form.emails) }}{% endblock %}
|
||||
{% block emails_field scoped %}{{ profile.render_field(form.emails) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "phone_numbers" in form %}
|
||||
{% block phone_numbers_field scoped %}{{ render_field(form.phone_numbers) }}{% endblock %}
|
||||
{% block phone_numbers_field scoped %}{{ profile.render_field(form.phone_numbers) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "formatted_address" in form %}
|
||||
{% block formatted_address_field scoped %}{{ render_field(form.formatted_address) }}{% endblock %}
|
||||
{% block formatted_address_field scoped %}{{ profile.render_field(form.formatted_address) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "street" in form %}
|
||||
{% block street_field scoped %}{{ render_field(form.street) }}{% endblock %}
|
||||
{% block street_field scoped %}{{ profile.render_field(form.street) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
<div class="equal width fields">
|
||||
{% if "postal_code" in form %}
|
||||
{% block postal_code_field scoped %}{{ render_field(form.postal_code) }}{% endblock %}
|
||||
{% block postal_code_field scoped %}{{ profile.render_field(form.postal_code) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "locality" in form %}
|
||||
{% block locality_field scoped %}{{ render_field(form.locality) }}{% endblock %}
|
||||
{% block locality_field scoped %}{{ profile.render_field(form.locality) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "region" in form %}
|
||||
{% block region_field scoped %}{{ render_field(form.region) }}{% endblock %}
|
||||
{% block region_field scoped %}{{ profile.render_field(form.region) }}{% endblock %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="equal width fields">
|
||||
|
||||
{% if "department" in form %}
|
||||
{% block department_field scoped %}{{ render_field(form.department) }}{% endblock %}
|
||||
{% block department_field scoped %}{{ profile.render_field(form.department) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "employee_number" in form %}
|
||||
{% block employee_number_field scoped %}{{ render_field(form.employee_number) }}{% endblock %}
|
||||
{% block employee_number_field scoped %}{{ profile.render_field(form.employee_number) }}{% endblock %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="equal width fields">
|
||||
|
||||
{% if "title" in form %}
|
||||
{% block title_field scoped %}{{ render_field(form.title) }}{% endblock %}
|
||||
{% block title_field scoped %}{{ profile.render_field(form.title) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "organization" in form %}
|
||||
{% block organization_field scoped %}{{ render_field(form.organization) }}{% endblock %}
|
||||
{% block organization_field scoped %}{{ profile.render_field(form.organization) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
{% if "profile_url" in form %}
|
||||
{% block profile_uri_field scoped %}{{ render_field(form.profile_url) }}{% endblock %}
|
||||
{% block profile_uri_field scoped %}{{ profile.render_field(form.profile_url) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "preferred_language" in form %}
|
||||
{% block preferred_language_field scoped %}{{ render_field(form.preferred_language) }}{% endblock %}
|
||||
{% block preferred_language_field scoped %}{{ profile.render_field(form.preferred_language) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
<h4 class="ui dividing header">{% trans %}Account settings{% endtrans %}</h4>
|
||||
|
||||
{% if "user_name" in form %}
|
||||
{% block user_name_field scoped %}{{ render_field(form.user_name) }}{% endblock %}
|
||||
{% block user_name_field scoped %}{{ profile.render_field(form.user_name) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "groups" in form %}
|
||||
{% block groups_field scoped %}{{ render_field(form.groups) }}{% endblock %}
|
||||
{% block groups_field scoped %}{{ profile.render_field(form.groups) }}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if "password1" in form %}
|
||||
{% block password_field scoped %}
|
||||
<div class="two fields">
|
||||
{{ render_field(form.password1, noindicator=true) }}
|
||||
{{ render_field(form.password2, noindicator=true) }}
|
||||
{{ profile.render_field(form.password1, noindicator=true) }}
|
||||
{{ profile.render_field(form.password2, noindicator=true) }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% if user.can_manage_users %}
|
||||
|
||||
{% if user and user.can_manage_users %}
|
||||
|
||||
<div class="ui message info">
|
||||
<div class="header">
|
||||
{% trans %}User password is not mandatory{% endtrans %}
|
||||
</div>
|
||||
{% if has_password %}
|
||||
<p>{% trans %}The user password can be set:{% endtrans %}</p>
|
||||
<ul class="ui list">
|
||||
<li>{% trans %}by filling this form;{% endtrans %}</li>
|
||||
<li>{% trans %}by sending the user a password initialization mail, after the account creation;{% endtrans %}</li>
|
||||
<li>{% trans %}or simply waiting for the user to sign-in a first time, and then receive a password initialization mail.{% endtrans %}</li>
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>
|
||||
{% if has_smtp %}
|
||||
{% trans %}The user will not be able to authenticate unless the password is set, but they will be able to ask for a password initialization mail.{% endtrans %}
|
||||
|
@ -243,7 +183,6 @@
|
|||
{% trans %}The user will not be able to authenticate unless the password is set.{% endtrans %}
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
@ -255,6 +194,7 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endcall %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -30,35 +30,35 @@
|
|||
{% endif %}
|
||||
|
||||
{% if user.can_edit_self %}
|
||||
<a class="item {% if menuitem == "profile" %}active{% endif %}"
|
||||
<a class="item {% if menuitem is defined and menuitem == "profile" %}active{% endif %}"
|
||||
href="{{ url_for('account.profile_edition', edited_user=user) }}">
|
||||
<i class="id card icon"></i>
|
||||
{% trans %}Profile{% endtrans %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if user.can_use_oidc %}
|
||||
<a class="item {% if menuitem == "consents" %}active{% endif %}"
|
||||
<a class="item {% if menuitem is defined and menuitem == "consents" %}active{% endif %}"
|
||||
href="{{ url_for('oidc.consents.consents') }}">
|
||||
<i class="handshake icon"></i>
|
||||
{% trans %}Consents{% endtrans %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if user.can_manage_users %}
|
||||
<a class="item {% if menuitem == "users" %}active{% endif %}"
|
||||
<a class="item {% if menuitem is defined and menuitem == "users" %}active{% endif %}"
|
||||
href="{{ url_for('account.users') }}">
|
||||
<i class="address book icon"></i>
|
||||
{% trans %}Users{% endtrans %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if user.can_manage_groups %}
|
||||
<a class="item {% if menuitem == "groups" %}active{% endif %}"
|
||||
<a class="item {% if menuitem is defined and menuitem == "groups" %}active{% endif %}"
|
||||
href="{{ url_for('groups.groups') }}">
|
||||
<i class="users icon"></i>
|
||||
{% trans %}Groups{% endtrans %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if user.can_manage_oidc %}
|
||||
<a class="item {% if menuitem == "admin" %}active{% endif %}" href="{{ url_for('admin.mail_index') }}">
|
||||
<a class="item {% if menuitem is defined and menuitem == "admin" %}active{% endif %}" href="{{ url_for('admin.mail_index') }}">
|
||||
<i class="settings icon"></i>
|
||||
{% trans %}Admin{% endtrans %}
|
||||
</a>
|
||||
|
|
|
@ -2,6 +2,7 @@ import pytest
|
|||
from canaille import create_app
|
||||
from canaille.app import models
|
||||
from flask_webtest import TestApp
|
||||
from jinja2 import StrictUndefined
|
||||
from pytest_lazyfixture import lazy_fixture
|
||||
from werkzeug.security import gen_salt
|
||||
|
||||
|
@ -89,6 +90,7 @@ def app(configuration, backend):
|
|||
@pytest.fixture
|
||||
def testclient(app):
|
||||
app.config["TESTING"] = True
|
||||
app.jinja_env.undefined = StrictUndefined
|
||||
with app.app_context():
|
||||
yield TestApp(app)
|
||||
|
||||
|
|
Loading…
Reference in a new issue