mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-11 02:23:19 -04:00
Merge branch 'main' of https://github.com/GSA/notifications-admin into notify-871
This commit is contained in:
@@ -1279,6 +1279,23 @@ class ChangeNameForm(StripWhitespaceForm):
|
|||||||
new_name = GovukTextInputField("Your name")
|
new_name = GovukTextInputField("Your name")
|
||||||
|
|
||||||
|
|
||||||
|
class ChangePreferredTimezoneForm(StripWhitespaceForm):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(ChangePreferredTimezoneForm, self).__init__(*args, **kwargs)
|
||||||
|
self.new_preferred_timezone.choices = [
|
||||||
|
("US/Eastern", "US/Eastern"),
|
||||||
|
("US/Central", "US/Central"),
|
||||||
|
("US/Mountain", "US/Mountain"),
|
||||||
|
("US/Pacific", "US/Pacific"),
|
||||||
|
("US/Hawaii", "US/Hawaii"),
|
||||||
|
]
|
||||||
|
|
||||||
|
new_preferred_timezone = GovukRadiosField(
|
||||||
|
"What timezone would you like to use?",
|
||||||
|
default="US/Eastern",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ChangeEmailForm(StripWhitespaceForm):
|
class ChangeEmailForm(StripWhitespaceForm):
|
||||||
def __init__(self, validate_email_func, *args, **kwargs):
|
def __init__(self, validate_email_func, *args, **kwargs):
|
||||||
self.validate_email_func = validate_email_func
|
self.validate_email_func = validate_email_func
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from functools import partial
|
|||||||
|
|
||||||
from flask import abort, flash, jsonify, redirect, render_template, request, url_for
|
from flask import abort, flash, jsonify, redirect, render_template, request, url_for
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
from markupsafe import Markup
|
||||||
from notifications_python_client.errors import HTTPError
|
from notifications_python_client.errors import HTTPError
|
||||||
from notifications_utils import SMS_CHAR_COUNT_LIMIT
|
from notifications_utils import SMS_CHAR_COUNT_LIMIT
|
||||||
|
|
||||||
@@ -679,8 +680,23 @@ def count_content_length(service_id, template_type):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_latin1(s):
|
||||||
|
return bool(s.encode(encoding="latin-1", errors="strict"))
|
||||||
|
|
||||||
|
|
||||||
def _get_content_count_error_and_message_for_template(template):
|
def _get_content_count_error_and_message_for_template(template):
|
||||||
|
url = "https://en.wikipedia.org/wiki/ISO/IEC_8859-1"
|
||||||
if template.template_type == "sms":
|
if template.template_type == "sms":
|
||||||
|
s1 = f"<html><body>Use of characters outside the <a href='{url}'>IEC_8859-1</a> character set may increase "
|
||||||
|
s2 = "the message fragment count, resulting in additional charges, and these IEC_8859-1 "
|
||||||
|
s3 = "characters may not display properly on some older mobile devices.</body></html>"
|
||||||
|
|
||||||
|
warning = ""
|
||||||
|
try:
|
||||||
|
_is_latin1(template.content)
|
||||||
|
except UnicodeEncodeError:
|
||||||
|
warning = f"{s1}{s2}{s3}"
|
||||||
|
|
||||||
if template.is_message_too_long():
|
if template.is_message_too_long():
|
||||||
return True, (
|
return True, (
|
||||||
f"You have "
|
f"You have "
|
||||||
@@ -689,11 +705,16 @@ def _get_content_count_error_and_message_for_template(template):
|
|||||||
)
|
)
|
||||||
if template.placeholders:
|
if template.placeholders:
|
||||||
return False, (
|
return False, (
|
||||||
f"Will be charged as {message_count(template.fragment_count, template.template_type)} "
|
Markup(
|
||||||
f"(not including personalization)"
|
f"Will be charged as {message_count(template.fragment_count, template.template_type)} "
|
||||||
|
f"(not including personalization). {warning}"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
return False, (
|
return False, (
|
||||||
f"Will be charged as {message_count(template.fragment_count, template.template_type)} "
|
# Markup marks html contents safe so that they render properly. Don't use it if there is user input.
|
||||||
|
Markup(
|
||||||
|
f"Will be charged as {message_count(template.fragment_count, template.template_type)}. {warning} "
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ from app.main.forms import (
|
|||||||
ChangeMobileNumberForm,
|
ChangeMobileNumberForm,
|
||||||
ChangeNameForm,
|
ChangeNameForm,
|
||||||
ChangePasswordForm,
|
ChangePasswordForm,
|
||||||
|
ChangePreferredTimezoneForm,
|
||||||
ConfirmPasswordForm,
|
ConfirmPasswordForm,
|
||||||
ServiceOnOffSettingForm,
|
ServiceOnOffSettingForm,
|
||||||
TwoFactorForm,
|
TwoFactorForm,
|
||||||
@@ -61,6 +62,22 @@ def user_profile_name():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/user-profile/preferred_timezone", methods=["GET", "POST"])
|
||||||
|
@user_is_logged_in
|
||||||
|
def user_profile_preferred_timezone():
|
||||||
|
form = ChangePreferredTimezoneForm(new_name=current_user.preferred_timezone)
|
||||||
|
|
||||||
|
if form.validate_on_submit():
|
||||||
|
current_user.update(preferred_timezone=form.new_preferred_timezone.data)
|
||||||
|
current_user.preferred_timezone = form.new_preferred_timezone.data
|
||||||
|
return redirect(url_for(".user_profile"))
|
||||||
|
return render_template(
|
||||||
|
"views/user-profile/change.html",
|
||||||
|
thing="preferred timezone",
|
||||||
|
form_field=form.new_preferred_timezone,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@main.route("/user-profile/email", methods=["GET", "POST"])
|
@main.route("/user-profile/email", methods=["GET", "POST"])
|
||||||
@user_is_logged_in
|
@user_is_logged_in
|
||||||
@user_is_gov_user
|
@user_is_gov_user
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,6 @@ class User(JSONModel, UserMixin):
|
|||||||
super().__init__(_dict)
|
super().__init__(_dict)
|
||||||
self.permissions = _dict.get("permissions", {})
|
self.permissions = _dict.get("permissions", {})
|
||||||
self._platform_admin = _dict["platform_admin"]
|
self._platform_admin = _dict["platform_admin"]
|
||||||
self.preferred_timezone = "US/Eastern"
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_id(cls, user_id):
|
def from_id(cls, user_id):
|
||||||
@@ -366,6 +365,7 @@ class User(JSONModel, UserMixin):
|
|||||||
"permissions": [x for x in self._permissions],
|
"permissions": [x for x in self._permissions],
|
||||||
"organizations": self.organization_ids,
|
"organizations": self.organization_ids,
|
||||||
"current_session_id": self.current_session_id,
|
"current_session_id": self.current_session_id,
|
||||||
|
"preferred_timezone": self.preferred_timezone,
|
||||||
}
|
}
|
||||||
if hasattr(self, "_password"):
|
if hasattr(self, "_password"):
|
||||||
dct["password"] = self._password
|
dct["password"] = self._password
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ class HeaderNavigation(Navigation):
|
|||||||
"user_profile_mobile_number_delete",
|
"user_profile_mobile_number_delete",
|
||||||
"user_profile_name",
|
"user_profile_name",
|
||||||
"user_profile_password",
|
"user_profile_password",
|
||||||
|
"user_profile_preferred_timezone",
|
||||||
"user_profile_disable_platform_admin_view",
|
"user_profile_disable_platform_admin_view",
|
||||||
},
|
},
|
||||||
"platform-admin": {
|
"platform-admin": {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ ALLOWED_ATTRIBUTES = {
|
|||||||
"updated_by",
|
"updated_by",
|
||||||
"current_session_id",
|
"current_session_id",
|
||||||
"email_access_validated_at",
|
"email_access_validated_at",
|
||||||
|
"preferred_timezone",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="grid-row">
|
<div class="grid-row">
|
||||||
<div class="grid-col-12">
|
<div class="grid-col-12">
|
||||||
<div class="template-content-count">
|
<div class="template-content-count" bg-color="red">
|
||||||
<div data-module="update-status" data-target="template_content"
|
<div data-module="update-status" data-target="template_content"
|
||||||
data-updates-url="{{ url_for('.count_content_length', service_id=current_service.id, template_type='sms') }}"
|
data-updates-url="{{ url_for('.count_content_length', service_id=current_service.id, template_type='sms') }}"
|
||||||
aria-live="polite">
|
aria-live="polite">
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tablet:grid-col-9 mobile-lg:grid-col-12">
|
<div class="tablet:grid-col-9 mobile-lg:grid-col-12">
|
||||||
<h2 id="help" class="font-body-xl margin-top-2">How to customize your message</h2>
|
<h2 id="help" class="font-body-xl margin-top-2">How to customize your message</h2>
|
||||||
<div class="usa-accordion usa-accordion--bordered usa-accordion--multiselectable maxw-mobile-lg" data-allow-multiple>
|
<div class="usa-accordion usa-accordion--bordered usa-accordion--multiselectable maxw-mobile-lg" data-allow-multiple>
|
||||||
|
|||||||
@@ -219,7 +219,7 @@
|
|||||||
<p>
|
<p>
|
||||||
You can send up to
|
You can send up to
|
||||||
{{ "{:,}".format(current_service.message_limit) }} messages
|
{{ "{:,}".format(current_service.message_limit) }} messages
|
||||||
per day.
|
per year.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Problems or comments?
|
Problems or comments?
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
<div class="">
|
<div class="">
|
||||||
<h1 class="font-body-2xl margin-bottom-3">{{ page_title }}</h1>
|
<h1 class="font-body-2xl margin-y-0">{{ page_title }}</h1>
|
||||||
{{ copy_folder_path(template_folder_path, current_service.id, from_service, current_user) }}
|
{{ copy_folder_path(template_folder_path, current_service.id, from_service, current_user) }}
|
||||||
</div>
|
</div>
|
||||||
{% if not services_templates_and_folders.templates_to_show %}
|
{% if not services_templates_and_folders.templates_to_show %}
|
||||||
@@ -28,32 +28,24 @@
|
|||||||
<nav id="template-list">
|
<nav id="template-list">
|
||||||
<ul>
|
<ul>
|
||||||
{% for item in services_templates_and_folders %}
|
{% for item in services_templates_and_folders %}
|
||||||
<li class="template-list-item {% if item.ancestors %}template-list-item-hidden-by-default{% endif %} {% if not item.ancestors %}template-list-item-without-ancestors{% endif %}">
|
|
||||||
{% for ancestor in item.ancestors %}
|
<li class="template-list-item margin-bottom-2 {% if item.ancestors %}template-list-item-hidden-by-default{% endif %} {% if not item.ancestors %}template-list-item-without-ancestors{% endif %}">
|
||||||
{% if ancestor.is_service %}
|
|
||||||
<a href="{{ url_for('.choose_template_to_copy', service_id=current_service.id, from_service=ancestor.service_id) }}" class="usa-link template-list-folder">
|
|
||||||
{% else %}
|
|
||||||
<a href="{{ url_for('.choose_template_to_copy', service_id=current_service.id, from_folder=ancestor.id) }}" class="usa-link template-list-folder">
|
|
||||||
{% endif %}
|
|
||||||
{{ ancestor.name }}
|
|
||||||
</a> <span class="message-name-separator"></span>
|
|
||||||
{% endfor %}
|
|
||||||
{% if item.is_service %}
|
{% if item.is_service %}
|
||||||
<a href="{{ url_for('.choose_template_to_copy', service_id=current_service.id, from_service=item.service_id) }}" class="usa-link template-list-folder">
|
|
||||||
<span class="live-search-relevant">{{ item.name }}</span>
|
|
||||||
</a>
|
|
||||||
{% elif item.is_folder %}
|
{% elif item.is_folder %}
|
||||||
<a href="{{ url_for('.choose_template_to_copy', service_id=current_service.id, from_service=item.service_id, from_folder=item.id) }}" class="usa-link template-list-folder">
|
|
||||||
<span class="live-search-relevant">{{ item.name }}</span>
|
|
||||||
</a>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
{% for ancestor in item.ancestors %}
|
||||||
|
{% if ancestor.is_service %}
|
||||||
|
<a href="{{ url_for('.choose_template_to_copy', service_id=current_service.id, from_service=ancestor.service_id) }}" class="usa-link template-list-folder">
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('.choose_template_to_copy', service_id=current_service.id, from_folder=ancestor.id) }}" class="usa-link template-list-folder">
|
||||||
|
{% endif %}
|
||||||
|
{{ ancestor.name }}
|
||||||
|
</a> <span class="message-name-separator"></span>
|
||||||
|
{% endfor %}
|
||||||
<a class="usa-link template-list-template" href="{{ url_for('.copy_template', service_id=current_service.id, template_id=item.id, from_service=item.service_id) }}">
|
<a class="usa-link template-list-template" href="{{ url_for('.copy_template', service_id=current_service.id, template_id=item.id, from_service=item.service_id) }}">
|
||||||
<span class="live-search-relevant">{{ item.name }}</span>
|
<span class="live-search-relevant">{{ item.name }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p class="template-list-item-hint usa-hint usa-checkbox__label-description">
|
|
||||||
{{ item.hint }}
|
|
||||||
</p>
|
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -63,6 +63,16 @@
|
|||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
|
{% call row() %}
|
||||||
|
{{ text_field('Preferred Timezone') }}
|
||||||
|
{{ optional_text_field(current_user.preferred_timezone) }}
|
||||||
|
{{ edit_field(
|
||||||
|
'Change',
|
||||||
|
url_for('.user_profile_preferred_timezone'),
|
||||||
|
suffix='preferred timezone'
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{% endcall %}
|
||||||
|
|
||||||
{% if current_user.platform_admin or session.get('disable_platform_admin_view') %}
|
{% if current_user.platform_admin or session.get('disable_platform_admin_view') %}
|
||||||
{% call row(id='disable-platform-admin') %}
|
{% call row(id='disable-platform-admin') %}
|
||||||
|
|||||||
Generated
+21
-11
@@ -722,13 +722,13 @@ pyflakes = ">=3.1.0,<3.2.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flake8-bugbear"
|
name = "flake8-bugbear"
|
||||||
version = "23.11.28"
|
version = "23.12.2"
|
||||||
description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle."
|
description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8.1"
|
python-versions = ">=3.8.1"
|
||||||
files = [
|
files = [
|
||||||
{file = "flake8-bugbear-23.11.28.tar.gz", hash = "sha256:0ba6c44eaa0e4782da94c5c2607159a0e73569369246cd179cc143a0e16b78ba"},
|
{file = "flake8-bugbear-23.12.2.tar.gz", hash = "sha256:32b2903e22331ae04885dae25756a32a8c666c85142e933f43512a70f342052a"},
|
||||||
{file = "flake8_bugbear-23.11.28-py3-none-any.whl", hash = "sha256:8d0f351d954fd860851710cd8b5b28742b2339c0e58848b103418dd9cddb9aa4"},
|
{file = "flake8_bugbear-23.12.2-py3-none-any.whl", hash = "sha256:83324bad4d90fee4bf64dd69c61aff94debf8073fbd807c8b6a36eec7a2f0719"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -880,13 +880,13 @@ email = ["email-validator"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "freezegun"
|
name = "freezegun"
|
||||||
version = "1.2.2"
|
version = "1.3.1"
|
||||||
description = "Let your Python tests travel through time"
|
description = "Let your Python tests travel through time"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "freezegun-1.2.2-py3-none-any.whl", hash = "sha256:ea1b963b993cb9ea195adbd893a48d573fda951b0da64f60883d7e988b606c9f"},
|
{file = "freezegun-1.3.1-py3-none-any.whl", hash = "sha256:065e77a12624d05531afa87ade12a0b9bdb53495c4573893252a055b545ce3ea"},
|
||||||
{file = "freezegun-1.2.2.tar.gz", hash = "sha256:cd22d1ba06941384410cd967d8a99d5ae2442f57dfafeff2fda5de8dc5c05446"},
|
{file = "freezegun-1.3.1.tar.gz", hash = "sha256:48984397b3b58ef5dfc645d6a304b0060f612bcecfdaaf45ce8aff0077a6cb6a"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -1432,6 +1432,16 @@ files = [
|
|||||||
{file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
|
{file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
|
||||||
{file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
|
{file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
|
||||||
{file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
|
{file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
|
||||||
|
{file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
|
||||||
|
{file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
|
||||||
|
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
|
||||||
|
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
|
||||||
|
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
|
||||||
|
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
|
||||||
|
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
|
||||||
|
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
|
||||||
|
{file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
|
||||||
|
{file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
|
||||||
{file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
|
{file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
|
||||||
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
|
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
|
||||||
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
|
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
|
||||||
@@ -1499,13 +1509,13 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "moto"
|
name = "moto"
|
||||||
version = "4.2.10"
|
version = "4.2.11"
|
||||||
description = ""
|
description = ""
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "moto-4.2.10-py2.py3-none-any.whl", hash = "sha256:5cf0736d1f43cb887498d00b00ae522774bfddb7db1f4994fedea65b290b9f0e"},
|
{file = "moto-4.2.11-py2.py3-none-any.whl", hash = "sha256:58c12ab9ee69b6a5d1cddf83611ba4071508f07894317c57844b3ae6dc5bcd38"},
|
||||||
{file = "moto-4.2.10.tar.gz", hash = "sha256:92595fe287474a31ac3ef847941ebb097e8ffb0c3d6c106e47cf573db06933b2"},
|
{file = "moto-4.2.11.tar.gz", hash = "sha256:2da62d52eaa765dfe2762c920f0a88a58f3a09e04581c91db967d92faec848f1"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -3078,4 +3088,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = ">=3.9,<3.12"
|
python-versions = ">=3.9,<3.12"
|
||||||
content-hash = "aba218ed57ec710326788e1b916016923f398e1694ca2fba113e6b9347d2ce04"
|
content-hash = "cbc1f1bd362257b864862976a30c1c80c8e2117378074593c46cdb96c32eae4c"
|
||||||
|
|||||||
+2
-2
@@ -43,9 +43,9 @@ bandit = "*"
|
|||||||
beautifulsoup4 = "^4.12.2"
|
beautifulsoup4 = "^4.12.2"
|
||||||
black = "^23.11.0"
|
black = "^23.11.0"
|
||||||
coverage = "*"
|
coverage = "*"
|
||||||
freezegun = "^1.2.2"
|
freezegun = "^1.3.1"
|
||||||
flake8 = "^6.1.0"
|
flake8 = "^6.1.0"
|
||||||
flake8-bugbear = "^23.11.28"
|
flake8-bugbear = "^23.12.2"
|
||||||
flake8-print = "^5.0.0"
|
flake8-print = "^5.0.0"
|
||||||
flake8-pytest-style = "^1.7.2"
|
flake8-pytest-style = "^1.7.2"
|
||||||
isort = "^5.12.0"
|
isort = "^5.12.0"
|
||||||
|
|||||||
@@ -322,7 +322,7 @@ def test_register_from_invite(
|
|||||||
"+12024900460",
|
"+12024900460",
|
||||||
"somreallyhardthingtoguess",
|
"somreallyhardthingtoguess",
|
||||||
"sms_auth",
|
"sms_auth",
|
||||||
),
|
)
|
||||||
mock_get_invited_user_by_id.assert_called_once_with(sample_invite["id"])
|
mock_get_invited_user_by_id.assert_called_once_with(sample_invite["id"])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -739,16 +739,16 @@ def test_choose_a_template_to_copy(
|
|||||||
assert page.select(".folder-heading") == []
|
assert page.select(".folder-heading") == []
|
||||||
|
|
||||||
expected = [
|
expected = [
|
||||||
("Service 1 " "4 templates"),
|
(""),
|
||||||
("Service 1 sms_template_one " "Text message template"),
|
("Service 1 sms_template_one"),
|
||||||
("Service 1 sms_template_two " "Text message template"),
|
("Service 1 sms_template_two"),
|
||||||
("Service 1 email_template_one " "Email template"),
|
("Service 1 email_template_one"),
|
||||||
("Service 1 email_template_two " "Email template"),
|
("Service 1 email_template_two"),
|
||||||
("Service 2 " "4 templates"),
|
(""),
|
||||||
("Service 2 sms_template_one " "Text message template"),
|
("Service 2 sms_template_one"),
|
||||||
("Service 2 sms_template_two " "Text message template"),
|
("Service 2 sms_template_two"),
|
||||||
("Service 2 email_template_one " "Email template"),
|
("Service 2 email_template_one"),
|
||||||
("Service 2 email_template_two " "Email template"),
|
("Service 2 email_template_two"),
|
||||||
]
|
]
|
||||||
actual = page.select(".template-list-item")
|
actual = page.select(".template-list-item")
|
||||||
|
|
||||||
@@ -763,17 +763,6 @@ def test_choose_a_template_to_copy(
|
|||||||
service_id=SERVICE_ONE_ID,
|
service_id=SERVICE_ONE_ID,
|
||||||
from_service=SERVICE_TWO_ID,
|
from_service=SERVICE_TWO_ID,
|
||||||
)
|
)
|
||||||
assert links[1]["href"] == url_for(
|
|
||||||
"main.choose_template_to_copy",
|
|
||||||
service_id=SERVICE_ONE_ID,
|
|
||||||
from_service=SERVICE_TWO_ID,
|
|
||||||
)
|
|
||||||
assert links[2]["href"] == url_for(
|
|
||||||
"main.copy_template",
|
|
||||||
service_id=SERVICE_ONE_ID,
|
|
||||||
template_id=TEMPLATE_ONE_ID,
|
|
||||||
from_service=SERVICE_TWO_ID,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_choose_a_template_to_copy_when_user_has_one_service(
|
def test_choose_a_template_to_copy_when_user_has_one_service(
|
||||||
@@ -791,10 +780,10 @@ def test_choose_a_template_to_copy_when_user_has_one_service(
|
|||||||
assert page.select(".folder-heading") == []
|
assert page.select(".folder-heading") == []
|
||||||
|
|
||||||
expected = [
|
expected = [
|
||||||
("sms_template_one " "Text message template"),
|
("sms_template_one"),
|
||||||
("sms_template_two " "Text message template"),
|
("sms_template_two"),
|
||||||
("email_template_one " "Email template"),
|
("email_template_one"),
|
||||||
("email_template_two " "Email template"),
|
("email_template_two"),
|
||||||
]
|
]
|
||||||
actual = page.select(".template-list-item")
|
actual = page.select(".template-list-item")
|
||||||
|
|
||||||
@@ -821,7 +810,7 @@ def test_choose_a_template_to_copy_from_folder_within_service(
|
|||||||
):
|
):
|
||||||
mock_get_template_folders.return_value = [
|
mock_get_template_folders.return_value = [
|
||||||
_folder("Parent folder", PARENT_FOLDER_ID),
|
_folder("Parent folder", PARENT_FOLDER_ID),
|
||||||
_folder("Child folder empty", CHILD_FOLDER_ID, parent=PARENT_FOLDER_ID),
|
_folder("", CHILD_FOLDER_ID, parent=PARENT_FOLDER_ID),
|
||||||
_folder("Child folder non-empty", FOLDER_TWO_ID, parent=PARENT_FOLDER_ID),
|
_folder("Child folder non-empty", FOLDER_TWO_ID, parent=PARENT_FOLDER_ID),
|
||||||
]
|
]
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
@@ -865,13 +854,10 @@ def test_choose_a_template_to_copy_from_folder_within_service(
|
|||||||
)
|
)
|
||||||
|
|
||||||
expected = [
|
expected = [
|
||||||
("Child folder empty " "Empty"),
|
(""),
|
||||||
("Child folder non-empty " "1 template"),
|
(""),
|
||||||
(
|
("Child folder non-empty Should appear in list (nested)"),
|
||||||
"Child folder non-empty Should appear in list (nested) "
|
("Should appear in list (at same level)"),
|
||||||
"Text message template"
|
|
||||||
),
|
|
||||||
("Should appear in list (at same level) " "Text message template"),
|
|
||||||
]
|
]
|
||||||
actual = page.select(".template-list-item")
|
actual = page.select(".template-list-item")
|
||||||
|
|
||||||
@@ -885,26 +871,25 @@ def test_choose_a_template_to_copy_from_folder_within_service(
|
|||||||
assert links[0]["href"] == url_for(
|
assert links[0]["href"] == url_for(
|
||||||
"main.choose_template_to_copy",
|
"main.choose_template_to_copy",
|
||||||
service_id=SERVICE_ONE_ID,
|
service_id=SERVICE_ONE_ID,
|
||||||
from_service=SERVICE_ONE_ID,
|
|
||||||
from_folder=CHILD_FOLDER_ID,
|
|
||||||
)
|
|
||||||
assert links[1]["href"] == url_for(
|
|
||||||
"main.choose_template_to_copy",
|
|
||||||
service_id=SERVICE_ONE_ID,
|
|
||||||
from_service=SERVICE_ONE_ID,
|
|
||||||
from_folder=FOLDER_TWO_ID,
|
from_folder=FOLDER_TWO_ID,
|
||||||
)
|
)
|
||||||
assert links[2]["href"] == url_for(
|
# assert links[1]["href"] == url_for(
|
||||||
"main.choose_template_to_copy",
|
# "main.choose_template_to_copy",
|
||||||
service_id=SERVICE_ONE_ID,
|
# service_id=SERVICE_ONE_ID,
|
||||||
from_folder=FOLDER_TWO_ID,
|
# from_service=SERVICE_ONE_ID,
|
||||||
)
|
# from_folder=PARENT_FOLDER_ID,
|
||||||
assert links[3]["href"] == url_for(
|
# )
|
||||||
"main.copy_template",
|
# assert links[2]["href"] == url_for(
|
||||||
service_id=SERVICE_ONE_ID,
|
# "main.choose_template_to_copy",
|
||||||
template_id=TEMPLATE_ONE_ID,
|
# service_id=SERVICE_ONE_ID,
|
||||||
from_service=SERVICE_ONE_ID,
|
# from_folder=FOLDER_TWO_ID,
|
||||||
)
|
# )
|
||||||
|
# assert links[3]["href"] == url_for(
|
||||||
|
# "main.copy_template",
|
||||||
|
# service_id=SERVICE_ONE_ID,
|
||||||
|
# template_id=TEMPLATE_ONE_ID,
|
||||||
|
# from_service=SERVICE_ONE_ID,
|
||||||
|
# )
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@@ -2112,7 +2097,7 @@ def test_content_count_json_endpoint(
|
|||||||
html = json.loads(response.get_data(as_text=True))["html"]
|
html = json.loads(response.get_data(as_text=True))["html"]
|
||||||
snippet = BeautifulSoup(html, "html.parser").select_one("span")
|
snippet = BeautifulSoup(html, "html.parser").select_one("span")
|
||||||
|
|
||||||
assert normalize_spaces(snippet.text) == expected_message
|
assert expected_message in normalize_spaces(snippet.text)
|
||||||
|
|
||||||
if snippet.has_attr("class"):
|
if snippet.has_attr("class"):
|
||||||
assert snippet["class"] == [expected_class]
|
assert snippet["class"] == [expected_class]
|
||||||
|
|||||||
@@ -253,6 +253,7 @@ EXCLUDED_ENDPOINTS = tuple(
|
|||||||
"user_profile_mobile_number_delete",
|
"user_profile_mobile_number_delete",
|
||||||
"user_profile_name",
|
"user_profile_name",
|
||||||
"user_profile_password",
|
"user_profile_password",
|
||||||
|
"user_profile_preferred_timezone",
|
||||||
"using_notify",
|
"using_notify",
|
||||||
"verify",
|
"verify",
|
||||||
"verify_email",
|
"verify_email",
|
||||||
|
|||||||
Reference in New Issue
Block a user