From 7f522b918c9d4ab017edefafb832f69ff49f441f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 17:06:22 +0000 Subject: [PATCH 01/11] Bump word-wrap from 1.2.3 to 1.2.4 Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4. - [Release notes](https://github.com/jonschlinkert/word-wrap/releases) - [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4) --- updated-dependencies: - dependency-name: word-wrap dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6656ccc6b..9f99b0ea1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15716,9 +15716,9 @@ "dev": true }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -28109,9 +28109,9 @@ "dev": true }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true }, "wrap-ansi": { From 6188f7bc748defc6a155e14d3ee06023045e06d4 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 20 Jul 2023 13:20:22 -0700 Subject: [PATCH 02/11] notify-admin-638 adjust coverage report to fail under 96% --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 709e8fe02..8de3e0503 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,7 @@ py-lint: ## Run python linting scanners py-test: export NEW_RELIC_ENVIRONMENT=test py-test: ## Run python unit tests pipenv run coverage run --omit=*/notifications_utils/* -m pytest --maxfail=10 tests/ - pipenv run coverage report --fail-under=90 + pipenv run coverage report --fail-under=96 pipenv run coverage html -d .coverage_cache .PHONY: js-lint From 933a4808e443c62cbe2d41871c5fdfebb24bf417 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Fri, 21 Jul 2023 08:24:10 -0700 Subject: [PATCH 03/11] notify-admin-530 remove email info in service name settings --- .../views/service-settings/name-local.html | 6 ++---- app/templates/views/service-settings/name.html | 14 +++++++------- .../service_settings/test_service_settings.py | 7 +++---- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/app/templates/views/service-settings/name-local.html b/app/templates/views/service-settings/name-local.html index aaff84b1a..bff5403de 100644 --- a/app/templates/views/service-settings/name-local.html +++ b/app/templates/views/service-settings/name-local.html @@ -28,14 +28,12 @@
{% if current_service.prefix_sms %}

Users will see your service name at the start of every text message

- {% else %}

Users will see your service name as your email sender name.

{% endif %}
+

The service name you enter here will appear at the beginning of each text message, unless you turn off this off in Settings > Start text message with service name. + {% call form_wrapper() %} {{ form.name }} diff --git a/app/templates/views/service-settings/name.html b/app/templates/views/service-settings/name.html index 0bffb3b2d..6c0dc364f 100644 --- a/app/templates/views/service-settings/name.html +++ b/app/templates/views/service-settings/name.html @@ -22,17 +22,17 @@

You should only use an acronym or initialism if your users are already familiar with it.

-
+
{% if current_service.prefix_sms %} -

Users will see your service name:

-
    -
  • at the start of every text message
  • -
  • as your email sender name
  • -
+ +

Users will see your service name at the start of every text message

{% else %} -

Users will see your service name as your email sender name.

+

Users will see your service name as your email sender name.

{% endif %} +
+

The service name you enter here will appear at the beginning of each text message, unless you turn off this off in Settings > Start text message with service name. + {% call form_wrapper() %} {{ form.name }} diff --git a/tests/app/main/views/service_settings/test_service_settings.py b/tests/app/main/views/service_settings/test_service_settings.py index 1df4bba24..13c65c7a3 100644 --- a/tests/app/main/views/service_settings/test_service_settings.py +++ b/tests/app/main/views/service_settings/test_service_settings.py @@ -254,10 +254,9 @@ def test_should_show_service_name( assert page.select_one( 'main .govuk-body' ).text == 'Your service name should tell users what the message is about as well as who it’s from.' - assert normalize_spaces(page.select_one('main ul').text) == ( - 'at the start of every text message ' - 'as your email sender name' - ) + + assert "The service name you enter here will appear at the beginning of each text message, unless" in page.text + app.service_api_client.get_service.assert_called_with(SERVICE_ONE_ID) From 4aaf73ca7a6f593a85b7de9a1c0319e20090a660 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Jul 2023 23:38:55 +0000 Subject: [PATCH 04/11] Bump flake8-bugbear from 23.3.12 to 23.7.10 Bumps [flake8-bugbear](https://github.com/PyCQA/flake8-bugbear) from 23.3.12 to 23.7.10. - [Release notes](https://github.com/PyCQA/flake8-bugbear/releases) - [Commits](https://github.com/PyCQA/flake8-bugbear/compare/23.3.12...23.7.10) --- updated-dependencies: - dependency-name: flake8-bugbear dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Pipfile | 2 +- Pipfile.lock | 40 ++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Pipfile b/Pipfile index 4b0e3723f..93f9739cb 100644 --- a/Pipfile +++ b/Pipfile @@ -47,7 +47,7 @@ pytest-xdist = "==3.3.1" beautifulsoup4 = "==4.12.2" freezegun = "==1.2.2" flake8 = "==6.0.0" -flake8-bugbear = "==23.3.12" +flake8-bugbear = "==23.7.10" flake8-print = "==5.0.0" moto = "~=4.1" requests-mock = "==1.11.0" diff --git a/Pipfile.lock b/Pipfile.lock index 736bf0704..d6501d00b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e04b206789066f85bd531289b77e299b204d677f52ff65861e7793bcbca053dd" + "sha256": "7d90c44fa5dd863a7ebab1ec4fa02b8d5dc11050235d7bad87ee6cfde791720e" }, "pipfile-spec": 6, "requires": { @@ -50,19 +50,19 @@ }, "boto3": { "hashes": [ - "sha256:0fe7a35cf0041145c8eefebd3ae2ddf41baed62d7c963e5042b8ed8c297f648f", - "sha256:e24460d50001b517c6734dcf1c879feb43aa2062d88d9bdbb8703c986cb05941" + "sha256:cfcb20d5784428f31d89889e68b26efeda90f231c3119eef4af8b25ad405c55f", + "sha256:d5ac6599951fdd519ed26c6fe15c41a7aa4021cb9adce33167344f8ce5cdb07b" ], "markers": "python_version >= '3.7'", - "version": "==1.28.11" + "version": "==1.28.12" }, "botocore": { "hashes": [ - "sha256:b17ff973bb70b02b227928c2abe4992f1cfc46d13aee0228516c8f32572b88c6", - "sha256:d3cbffe554c9a1ba2ac6973734c43c21b8e7985a2ac4a4c31a09811b8029445c" + "sha256:7e5db466c762a071bb58c9a39d070f1333ce4f4ba6fdf9820ba21e87bd4c7e29", + "sha256:86380672151866b5e425636e3ebad74f2b83e7163e36ef5d38d11a04b9cba33b" ], "markers": "python_version >= '3.7'", - "version": "==1.31.11" + "version": "==1.31.12" }, "cachetools": { "hashes": [ @@ -235,7 +235,7 @@ "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==3.2.0" }, "click": { @@ -1215,19 +1215,19 @@ }, "boto3": { "hashes": [ - "sha256:0fe7a35cf0041145c8eefebd3ae2ddf41baed62d7c963e5042b8ed8c297f648f", - "sha256:e24460d50001b517c6734dcf1c879feb43aa2062d88d9bdbb8703c986cb05941" + "sha256:cfcb20d5784428f31d89889e68b26efeda90f231c3119eef4af8b25ad405c55f", + "sha256:d5ac6599951fdd519ed26c6fe15c41a7aa4021cb9adce33167344f8ce5cdb07b" ], "markers": "python_version >= '3.7'", - "version": "==1.28.11" + "version": "==1.28.12" }, "botocore": { "hashes": [ - "sha256:b17ff973bb70b02b227928c2abe4992f1cfc46d13aee0228516c8f32572b88c6", - "sha256:d3cbffe554c9a1ba2ac6973734c43c21b8e7985a2ac4a4c31a09811b8029445c" + "sha256:7e5db466c762a071bb58c9a39d070f1333ce4f4ba6fdf9820ba21e87bd4c7e29", + "sha256:86380672151866b5e425636e3ebad74f2b83e7163e36ef5d38d11a04b9cba33b" ], "markers": "python_version >= '3.7'", - "version": "==1.31.11" + "version": "==1.31.12" }, "cachecontrol": { "extras": [ @@ -1395,7 +1395,7 @@ "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==3.2.0" }, "cryptography": { @@ -1476,11 +1476,11 @@ }, "flake8-bugbear": { "hashes": [ - "sha256:beb5c7efcd7ccc2039ef66a77bb8db925e7be3531ff1cb4d0b7030d0e2113d72", - "sha256:e3e7f74c8a49ad3794a7183353026dabd68c74030d5f46571f84c1fb0eb79363" + "sha256:0ebdc7d8ec1ca8bd49347694562381f099f4de2f8ec6bda7a7dca65555d9e0d4", + "sha256:d99d005114020fbef47ed5e4aebafd22f167f9a0fbd0d8bf3c9e90612cb25c34" ], "index": "pypi", - "version": "==23.3.12" + "version": "==23.7.10" }, "flake8-print": { "hashes": [ @@ -1782,7 +1782,7 @@ "sha256:4659bc2a667783e7a15d190f6fccf8b2486685b6dba4c19c3876314769c57526", "sha256:b4fa3a7a0be38243123cf9d1f3518da10c51bdb165a2b2985566247f9155a7d3" ], - "markers": "python_full_version >= '3.6.0'", + "markers": "python_version >= '3.6'", "version": "==32.0.1" }, "pluggy": { @@ -1955,7 +1955,7 @@ "sha256:8f87bc7ee54675732fa66a05ebfe489e27264caeeff3728c945d25971b6485ec", "sha256:d653d6bccede5844304c605d5aac802c7cf9621efd700b46c7ec2b51ea914898" ], - "markers": "python_full_version >= '3.7.0'", + "markers": "python_version >= '3.7'", "version": "==13.4.2" }, "s3transfer": { From 185f98512b3c0df6c8d53ade67a8237ac1e8692b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 27 Jul 2023 07:29:30 -0700 Subject: [PATCH 05/11] fix flake8 --- app/navigation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/navigation.py b/app/navigation.py index 625164392..d2af07e68 100644 --- a/app/navigation.py +++ b/app/navigation.py @@ -267,7 +267,6 @@ class OrgNavigation(Navigation): 'edit_organization_billing_details', 'edit_organization_domains', 'edit_organization_email_branding', - 'edit_organization_domains', 'edit_organization_go_live_notes', 'edit_organization_name', 'edit_organization_notes', From 34fef6954c9e5c4e0bdf2dc958ac3ec95f8703f4 Mon Sep 17 00:00:00 2001 From: Andrew Shumway <90117200+A-Shumway42@users.noreply.github.com> Date: Thu, 27 Jul 2023 09:22:05 -0600 Subject: [PATCH 06/11] Added UTC to formatter return strings and appropriate tests (#617) Co-authored-by: Andrew Shumway --- app/formatters.py | 14 ++--- .../views/notifications/notification.html | 2 +- tests/app/main/test_formatters.py | 52 +++++++++---------- tests/app/main/views/test_activity.py | 22 ++++---- tests/app/main/views/test_conversation.py | 26 +++++----- tests/app/main/views/test_dashboard.py | 18 +++---- tests/app/main/views/test_jobs.py | 6 +-- tests/app/main/views/test_providers.py | 2 +- tests/app/main/views/test_templates.py | 4 +- .../app/main/views/uploads/test_upload_hub.py | 6 +-- 10 files changed, 76 insertions(+), 76 deletions(-) diff --git a/app/formatters.py b/app/formatters.py index 49411ddbf..6525ead4b 100644 --- a/app/formatters.py +++ b/app/formatters.py @@ -34,14 +34,14 @@ def convert_to_boolean(value): def format_datetime(date): - return '{} at {}'.format( + return '{} at {} UTC'.format( format_date(date), format_time_24h(date) ) def format_datetime_24h(date): - return '{} at {}'.format( + return '{} at {} UTC'.format( format_date(date), format_time_24h(date), ) @@ -52,28 +52,28 @@ def format_time(date): def format_datetime_normal(date): - return '{} at {}'.format( + return '{} at {} UTC'.format( format_date_normal(date), format_time_24h(date) ) def format_datetime_short(date): - return '{} at {}'.format( + return '{} at {} UTC'.format( format_date_short(date), format_time_24h(date) ) def format_datetime_relative(date): - return '{} at {}'.format( + return '{} at {} UTC'.format( get_human_day(date), format_time_24h(date) ) def format_datetime_numeric(date): - return '{} {}'.format( + return '{} {} UTC'.format( format_date_numeric(date), format_time_24h(date), ) @@ -134,7 +134,7 @@ def format_date_human(date): def format_datetime_human(date, date_prefix=''): - return '{} at {}'.format( + return '{} at {} UTC'.format( get_human_day(date, date_prefix='on'), format_time_24h(date), ) diff --git a/app/templates/views/notifications/notification.html b/app/templates/views/notifications/notification.html index b51c20fc2..1e637ead6 100644 --- a/app/templates/views/notifications/notification.html +++ b/app/templates/views/notifications/notification.html @@ -35,7 +35,7 @@ {% elif created_by %} by {{ created_by.name }} {% endif %} - {{ created_at|format_datetime_human }} UTC + {{ created_at|format_datetime_human }}

diff --git a/tests/app/main/test_formatters.py b/tests/app/main/test_formatters.py index 946b05cbc..89d8016da 100644 --- a/tests/app/main/test_formatters.py +++ b/tests/app/main/test_formatters.py @@ -57,38 +57,38 @@ def test_format_number_in_pounds_as_currency(input_number, formatted_number): @pytest.mark.parametrize('time, human_readable_datetime', [ # incoming in UTC, outgoing in "human formatted" UTC - ('2018-03-14 09:00', '14 March at 09:00'), - ('2018-03-14 19:00', '14 March at 19:00'), + ('2018-03-14 09:00', '14 March at 09:00 UTC'), + ('2018-03-14 19:00', '14 March at 19:00 UTC'), - ('2018-03-15 09:00', '15 March at 09:00'), - ('2018-03-15 19:00', '15 March at 19:00'), + ('2018-03-15 09:00', '15 March at 09:00 UTC'), + ('2018-03-15 19:00', '15 March at 19:00 UTC'), - ('2018-03-19 09:00', '19 March at 09:00'), - ('2018-03-19 19:00', '19 March at 19:00'), - ('2018-03-19 23:59', '19 March at 23:59'), + ('2018-03-19 09:00', '19 March at 09:00 UTC'), + ('2018-03-19 19:00', '19 March at 19:00 UTC'), + ('2018-03-19 23:59', '19 March at 23:59 UTC'), - ('2018-03-20 00:00', '19 March at 00:00'), # we specifically refer to 00:00 as belonging to the day before. - ('2018-03-20 04:01', 'yesterday at 04:01'), - ('2018-03-20 09:00', 'yesterday at 09:00'), - ('2018-03-20 19:00', 'yesterday at 19:00'), - ('2018-03-20 23:59', 'yesterday at 23:59'), + ('2018-03-20 00:00', '19 March at 00:00 UTC'), # we specifically refer to 00:00 as belonging to the day before. + ('2018-03-20 04:01', 'yesterday at 04:01 UTC'), + ('2018-03-20 09:00', 'yesterday at 09:00 UTC'), + ('2018-03-20 19:00', 'yesterday at 19:00 UTC'), + ('2018-03-20 23:59', 'yesterday at 23:59 UTC'), - ('2018-03-21 00:00', 'yesterday at 00:00'), # we specifically refer to 00:00 as belonging to the day before. - ('2018-03-21 04:01', 'today at 04:01'), - ('2018-03-21 09:00', 'today at 09:00'), - ('2018-03-21 12:00', 'today at 12:00'), - ('2018-03-21 19:00', 'today at 19:00'), - ('2018-03-21 23:59', 'today at 23:59'), + ('2018-03-21 00:00', 'yesterday at 00:00 UTC'), # we specifically refer to 00:00 as belonging to the day before. + ('2018-03-21 04:01', 'today at 04:01 UTC'), + ('2018-03-21 09:00', 'today at 09:00 UTC'), + ('2018-03-21 12:00', 'today at 12:00 UTC'), + ('2018-03-21 19:00', 'today at 19:00 UTC'), + ('2018-03-21 23:59', 'today at 23:59 UTC'), - ('2018-03-22 00:00', 'today at 00:00'), - ('2018-03-22 04:01', 'tomorrow at 04:01'), - ('2018-03-22 09:00', 'tomorrow at 09:00'), - ('2018-03-22 19:00', 'tomorrow at 19:00'), - ('2018-03-22 23:59', 'tomorrow at 23:59'), + ('2018-03-22 00:00', 'today at 00:00 UTC'), + ('2018-03-22 04:01', 'tomorrow at 04:01 UTC'), + ('2018-03-22 09:00', 'tomorrow at 09:00 UTC'), + ('2018-03-22 19:00', 'tomorrow at 19:00 UTC'), + ('2018-03-22 23:59', 'tomorrow at 23:59 UTC'), - ('2018-03-23 04:01', '23 March at 04:01'), - ('2018-03-23 09:00', '23 March at 09:00'), - ('2018-03-23 19:00', '23 March at 19:00'), + ('2018-03-23 04:01', '23 March at 04:01 UTC'), + ('2018-03-23 09:00', '23 March at 09:00 UTC'), + ('2018-03-23 19:00', '23 March at 19:00 UTC'), ]) def test_format_datetime_relative(time, human_readable_datetime): diff --git a/tests/app/main/views/test_activity.py b/tests/app/main/views/test_activity.py index a576ba3da..cdf1a5939 100644 --- a/tests/app/main/views/test_activity.py +++ b/tests/app/main/views/test_activity.py @@ -153,7 +153,7 @@ def test_can_show_notifications( assert normalize_spaces( first_row.select_one('.table-field-right-aligned .align-with-message-body').text ) == ( - 'Delivered 1 January at 06:01' + 'Delivered 1 January at 06:01 UTC' ) assert page_title in page.h1.text.strip() @@ -626,16 +626,16 @@ def test_redacts_templates_that_should_be_redacted( @freeze_time("2017-09-27 12:30:00.000000") @pytest.mark.parametrize( "message_type, status, expected_hint_status, single_line", [ - ('email', 'created', 'Sending since 27 September at 12:30', True), - ('email', 'sending', 'Sending since 27 September at 12:30', True), - ('email', 'temporary-failure', 'Inbox not accepting messages right now 27 September at 12:31', False), - ('email', 'permanent-failure', 'Email address does not exist 27 September at 12:31', False), - ('email', 'delivered', 'Delivered 27 September at 12:31', True), - ('sms', 'created', 'Sending since 27 September at 12:30', True), - ('sms', 'sending', 'Sending since 27 September at 12:30', True), - ('sms', 'temporary-failure', 'Phone not accepting messages right now 27 September at 12:31', False), - ('sms', 'permanent-failure', 'Not delivered 27 September at 12:31', False), - ('sms', 'delivered', 'Delivered 27 September at 12:31', True), + ('email', 'created', 'Sending since 27 September at 12:30 UTC', True), + ('email', 'sending', 'Sending since 27 September at 12:30 UTC', True), + ('email', 'temporary-failure', 'Inbox not accepting messages right now 27 September at 12:31 UTC', False), + ('email', 'permanent-failure', 'Email address does not exist 27 September at 12:31 UTC', False), + ('email', 'delivered', 'Delivered 27 September at 12:31 UTC', True), + ('sms', 'created', 'Sending since 27 September at 12:30 UTC', True), + ('sms', 'sending', 'Sending since 27 September at 12:30 UTC', True), + ('sms', 'temporary-failure', 'Phone not accepting messages right now 27 September at 12:31 UTC', False), + ('sms', 'permanent-failure', 'Not delivered 27 September at 12:31 UTC', False), + ('sms', 'delivered', 'Delivered 27 September at 12:31 UTC', True), ] ) def test_sending_status_hint_displays_correctly_on_notifications_page( diff --git a/tests/app/main/views/test_conversation.py b/tests/app/main/views/test_conversation.py index 04c3738ce..cc1eba09a 100644 --- a/tests/app/main/views/test_conversation.py +++ b/tests/app/main/views/test_conversation.py @@ -114,55 +114,55 @@ def test_view_conversation( for index, expected in enumerate([ ( 'message-8', - 'yesterday at 14:59', + 'yesterday at 14:59 UTC', ), ( 'message-7', - 'yesterday at 14:59', + 'yesterday at 14:59 UTC', ), ( 'message-6', - 'yesterday at 16:59', + 'yesterday at 16:59 UTC', ), ( 'message-5', - 'yesterday at 18:59', + 'yesterday at 18:59 UTC', ), ( 'message-4', - 'yesterday at 20:59', + 'yesterday at 20:59 UTC', ), ( 'message-3', - 'yesterday at 22:59', + 'yesterday at 22:59 UTC', ), ( 'message-2', - 'yesterday at 22:59', + 'yesterday at 22:59 UTC', ), ( 'message-1', - 'yesterday at 23:00', + 'yesterday at 23:00 UTC', ), ( expected_outbound_content, - 'yesterday at 00:00', + 'yesterday at 00:00 UTC', ), ( expected_outbound_content, - 'yesterday at 00:00', + 'yesterday at 00:00 UTC', ), ( expected_outbound_content, - 'yesterday at 00:00', + 'yesterday at 00:00 UTC', ), ( expected_outbound_content, - 'yesterday at 00:00', + 'yesterday at 00:00 UTC', ), ( expected_outbound_content, - 'yesterday at 00:00', + 'yesterday at 00:00 UTC', ), ]): assert ( diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 142db9a94..41f317135 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -389,14 +389,14 @@ def test_download_inbox( ) assert response.get_data(as_text=True) == ( 'Phone number,Message,Received\r\n' - '(202) 867-5300,message-1,2016-07-01 11:00\r\n' - '(202) 867-5300,message-2,2016-07-01 10:59\r\n' - '(202) 867-5300,message-3,2016-07-01 10:59\r\n' - '(202) 867-5302,message-4,2016-07-01 08:59\r\n' - '+33 1 12 34 56 78,message-5,2016-07-01 06:59\r\n' - '(202) 555-0104,message-6,2016-07-01 04:59\r\n' - '(202) 555-0104,message-7,2016-07-01 02:59\r\n' - '+682 12345,message-8,2016-07-01 02:59\r\n' + '(202) 867-5300,message-1,2016-07-01 11:00 UTC\r\n' + '(202) 867-5300,message-2,2016-07-01 10:59 UTC\r\n' + '(202) 867-5300,message-3,2016-07-01 10:59 UTC\r\n' + '(202) 867-5302,message-4,2016-07-01 08:59 UTC\r\n' + '+33 1 12 34 56 78,message-5,2016-07-01 06:59 UTC\r\n' + '(202) 555-0104,message-6,2016-07-01 04:59 UTC\r\n' + '(202) 555-0104,message-7,2016-07-01 02:59 UTC\r\n' + '+682 12345,message-8,2016-07-01 02:59 UTC\r\n' ) @@ -648,7 +648,7 @@ def test_should_show_upcoming_jobs_on_dashboard( page.select_one('a.banner-dashboard').text ) == ( '2 files waiting to send ' - 'sending starts today at 11:09' + 'sending starts today at 11:09 UTC' ) assert page.select_one('a.banner-dashboard')['href'] == url_for( diff --git a/tests/app/main/views/test_jobs.py b/tests/app/main/views/test_jobs.py index 5a017f8c9..470d85013 100644 --- a/tests/app/main/views/test_jobs.py +++ b/tests/app/main/views/test_jobs.py @@ -83,7 +83,7 @@ def test_should_show_page_for_one_job( assert page.h1.text.strip() == 'thisisatest.csv' assert ' '.join(page.find('tbody').find('tr').text.split()) == ( - '2021234567 template content Delivered 1 January at 11:10' + '2021234567 template content Delivered 1 January at 11:10 UTC' ) assert page.find('div', {'data-key': 'notifications'})['data-resource'] == url_for( 'main.view_job_updates', @@ -104,7 +104,7 @@ def test_should_show_page_for_one_job( assert normalize_spaces(page.select_one('tbody tr').text) == normalize_spaces( '2021234567 ' 'template content ' - 'Delivered 1 January at 11:10' + 'Delivered 1 January at 11:10 UTC' ) assert page.select_one('tbody tr a')['href'] == url_for( 'main.view_notification', @@ -329,7 +329,7 @@ def test_should_show_scheduled_job( ) assert normalize_spaces(page.select('main p')[1].text) == ( - 'Sending Two week reminder tomorrow at 05:00' + 'Sending Two week reminder tomorrow at 05:00 UTC' ) assert page.select('main p a')[0]['href'] == url_for( 'main.view_template_version', diff --git a/tests/app/main/views/test_providers.py b/tests/app/main/views/test_providers.py index cd04854ce..af36aaad8 100644 --- a/tests/app/main/views/test_providers.py +++ b/tests/app/main/views/test_providers.py @@ -188,7 +188,7 @@ def test_view_providers_shows_all_providers( assert table_data[1].text.strip() == "20" assert table_data[2].text.strip() == "42" assert table_data[3].text.strip() == "True" - assert table_data[4].text.strip() == "16 January at 15:20" + assert table_data[4].text.strip() == "16 January at 15:20 UTC" assert table_data[5].text.strip() == "Test User" domestic_sms_second_row = domestic_sms_table.tbody.find_all('tr')[1] diff --git a/tests/app/main/views/test_templates.py b/tests/app/main/views/test_templates.py index 61ff06f20..76bafdc97 100644 --- a/tests/app/main/views/test_templates.py +++ b/tests/app/main/views/test_templates.py @@ -472,7 +472,7 @@ def test_caseworker_sees_template_page_if_template_is_deleted( content = str(page) assert url_for("main.send_one_off", service_id=SERVICE_ONE_ID, template_id=fake_uuid) not in content - assert page.select('p.hint')[0].text.strip() == 'This template was deleted today at 15:00.' + assert page.select('p.hint')[0].text.strip() == 'This template was deleted today at 15:00 UTC.' mock_get_deleted_template.assert_called_with(SERVICE_ONE_ID, template_id, None) @@ -1571,7 +1571,7 @@ def test_should_show_page_for_a_deleted_template( content = str(page) assert url_for("main.edit_service_template", service_id=SERVICE_ONE_ID, template_id=fake_uuid) not in content assert url_for("main.send_one_off", service_id=SERVICE_ONE_ID, template_id=fake_uuid) not in content - assert page.select('p.hint')[0].text.strip() == 'This template was deleted today at 15:00.' + assert page.select('p.hint')[0].text.strip() == 'This template was deleted today at 15:00 UTC.' assert 'Delete this template' not in page.select_one('main').text mock_get_deleted_template.assert_called_with(SERVICE_ONE_ID, template_id, None) diff --git a/tests/app/main/views/uploads/test_upload_hub.py b/tests/app/main/views/uploads/test_upload_hub.py index 780c0d0c6..4cf2acb6d 100644 --- a/tests/app/main/views/uploads/test_upload_hub.py +++ b/tests/app/main/views/uploads/test_upload_hub.py @@ -48,7 +48,7 @@ def test_get_upload_hub_page( assert normalize_spaces(uploads[0].text.strip()) == ( 'some.csv ' - 'Sent 1 January 2016 at 11:09 ' + 'Sent 1 January 2016 at 11:09 UTC ' '0 pending 8 delivered 2 failed' ) assert uploads[0].select_one('a.file-list-filename-large')['href'] == ( @@ -79,12 +79,12 @@ def test_uploads_page_shows_scheduled_jobs( ), ( 'even_later.csv ' - 'Sending 1 January 2016 at 23:09 ' + 'Sending 1 January 2016 at 23:09 UTC ' '1 text message waiting to send' ), ( 'send_me_later.csv ' - 'Sending 1 January 2016 at 11:09 ' + 'Sending 1 January 2016 at 11:09 UTC ' '1 text message waiting to send' ), ] From b5664c3d20f3620bda191db35ff7d47a6ec16c5e Mon Sep 17 00:00:00 2001 From: Carlo Costino Date: Fri, 28 Jul 2023 09:31:45 -0400 Subject: [PATCH 07/11] Add support for E2E (end-to-end) tests (#625) This changeset lays the foundation for supporting E2E (end-to-end) integration tests for US Notify. It brings in the Playwright testing framework along with the Playwright pytest plugin to make this possible, and includes the following adjustments: - A new test session fixture for ensuring that Playwright authenticates with the sites that are currently behind HTTP Auth (requies env-var config) - A new end_to_end test directory specifically for E2E tests - Updates to the Makefile that make sure E2E tests are not run as a part of the normal test routine but can be run separately - A new command in the Makefile to run E2E tests that will run in Chromium, Firefox, and Webkit headless browsers Signed-off-by: Carlo Costino --- .github/workflows/checks.yml | 8 +- Makefile | 8 +- Pipfile | 1 + Pipfile.lock | 127 +++++++++++++++--- README.md | 21 ++- docs/end_to_end_tests.md | 120 +++++++++++++++++ tests/conftest.py | 12 ++ .../test_landing_and_sign_in_pages.py | 109 +++++++++++++++ 8 files changed, 385 insertions(+), 21 deletions(-) create mode 100644 docs/end_to_end_tests.md create mode 100644 tests/end_to_end/test_landing_and_sign_in_pages.py diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index cb1062e3c..1dc92d63f 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -41,7 +41,13 @@ jobs: - name: Run js tests run: npm test - name: Run py tests with coverage - run: pipenv run coverage run --omit=*/notifications_utils/* -m pytest --maxfail=10 + run: pipenv run coverage run --omit=*/notifications_utils/* -m pytest --maxfail=10 --ignore=tests/end_to_end tests/ + - name: Run E2E tests + run: pipenv run pytest -v --browser chromium --browser firefox --browser webkit tests/end_to_end + env: + NOTIFY_STAGING_HTTP_AUTH_PASSWORD: ${{ secrets.NOTIFY_STAGING_HTTP_AUTH_PASSWORD }} + NOTIFY_STAGING_HTTP_AUTH_USER: ${{ secrets.NOTIFY_STAGING_HTTP_AUTH_USER }} + NOTIFY_STAGING_URI: ${{ secrets.NOTIFY_STAGING_URI }} - name: Check coverage threshold run: pipenv run coverage report --fail-under=90 diff --git a/Makefile b/Makefile index 709e8fe02..2d0a1ee67 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ NVMSH := $(shell [ -f "$(HOME)/.nvm/nvm.sh" ] && echo "$(HOME)/.nvm/nvm.sh" || e .PHONY: bootstrap bootstrap: generate-version-file ## Set up everything to run the app pipenv install --dev + pipenv run playwright install --with-deps source $(NVMSH) --no-use && nvm install && npm ci --no-audit source $(NVMSH) && npm run build @@ -54,10 +55,15 @@ py-lint: ## Run python linting scanners .PHONY: py-test py-test: export NEW_RELIC_ENVIRONMENT=test py-test: ## Run python unit tests - pipenv run coverage run --omit=*/notifications_utils/* -m pytest --maxfail=10 tests/ + pipenv run coverage run --omit=*/notifications_utils/* -m pytest --maxfail=10 --ignore=tests/end_to_end tests/ pipenv run coverage report --fail-under=90 pipenv run coverage html -d .coverage_cache +.PHONY: e2e-test +e2e-test: export NEW_RELIC_ENVIRONMENT=test +e2e-test: ## Run end-to-end integration tests + pipenv run pytest -v --browser chromium --browser firefox --browser webkit tests/end_to_end + .PHONY: js-lint js-lint: ## Run javascript linting scanners source $(NVMSH) && npm run lint diff --git a/Pipfile b/Pipfile index 93f9739cb..325e2470d 100644 --- a/Pipfile +++ b/Pipfile @@ -37,6 +37,7 @@ newrelic = "*" flask-talisman = "*" notifications-utils = {editable = true, ref = "main", git = "https://github.com/GSA/notifications-utils.git"} coverage = "*" +pytest-playwright = "*" [dev-packages] isort = "==5.12.0" diff --git a/Pipfile.lock b/Pipfile.lock index d6501d00b..520f7b91c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "7d90c44fa5dd863a7ebab1ec4fa02b8d5dc11050235d7bad87ee6cfde791720e" + "sha256": "e6e49305bdee7cdd4605b8f6f7d0135cfe91e0c038abe6efdfa1784194ce3cdd" }, "pipfile-spec": 6, "requires": { @@ -50,19 +50,19 @@ }, "boto3": { "hashes": [ - "sha256:cfcb20d5784428f31d89889e68b26efeda90f231c3119eef4af8b25ad405c55f", - "sha256:d5ac6599951fdd519ed26c6fe15c41a7aa4021cb9adce33167344f8ce5cdb07b" + "sha256:b2d178c8a56fe3e4c9b123dccdff20e9555d12a597b72627fa659aa6295e238a", + "sha256:db6443fd2c65d9f35f671b03bacb0592b62d06884395ed65d75922ccddc34c2e" ], "markers": "python_version >= '3.7'", - "version": "==1.28.12" + "version": "==1.28.13" }, "botocore": { "hashes": [ - "sha256:7e5db466c762a071bb58c9a39d070f1333ce4f4ba6fdf9820ba21e87bd4c7e29", - "sha256:86380672151866b5e425636e3ebad74f2b83e7163e36ef5d38d11a04b9cba33b" + "sha256:78b96afbd88b8bd4c0967611a4cedddd9ea33d8601309dc351f81cbb5479d976", + "sha256:9a5080ea2a444f0447a7a1a79f64252ae2a1417b6c13a54656ee991cb610dd4e" ], "markers": "python_version >= '3.7'", - "version": "==1.31.12" + "version": "==1.31.13" }, "cachetools": { "hashes": [ @@ -235,7 +235,7 @@ "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==3.2.0" }, "click": { @@ -556,6 +556,14 @@ "markers": "python_version < '3.10'", "version": "==6.8.0" }, + "iniconfig": { + "hashes": [ + "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", + "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, "itsdangerous": { "hashes": [ "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", @@ -826,6 +834,14 @@ ], "version": "==2.0.3" }, + "packaging": { + "hashes": [ + "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", + "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" + ], + "markers": "python_version >= '3.7'", + "version": "==23.1" + }, "phonenumbers": { "hashes": [ "sha256:89671217c706cbaa3ced101deefafa779836feac3e059434d886ac31f09f32c0", @@ -833,6 +849,27 @@ ], "version": "==8.13.17" }, + "playwright": { + "hashes": [ + "sha256:428a719a6c7e40781c19860ed813840ac2d63678f7587abe12e800ea030d4b7e", + "sha256:4e396853034742b76654cdab27422155d238f46e4dc6369ea75854fafb935586", + "sha256:72e80076e595f5fcd8ebd89bf6635ad78e4bafa633119faed8b2568d17dbd398", + "sha256:84213339f179fd2a70f77ea7faea0616d74871349d556c53a1ecb7dd5097973c", + "sha256:89ca2261bb00b67d3dff97691cf18f4347ee0529a11e431e47df67b703d4d8fa", + "sha256:b7c6ddfca2b141b0385387cc56c125b14ea867902c39e3fc650ddd6c429b17da", + "sha256:ffbb927679b62fad5071439d5fe0840af46ad1844bc44bf80e1a0ad706140c98" + ], + "markers": "python_version >= '3.8'", + "version": "==1.36.0" + }, + "pluggy": { + "hashes": [ + "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849", + "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3" + ], + "markers": "python_version >= '3.7'", + "version": "==1.2.0" + }, "prometheus-client": { "hashes": [ "sha256:21e674f39831ae3f8acde238afd9a27a37d0d2fb5a28ea094f0ce25d2cbf2091", @@ -848,6 +885,13 @@ ], "version": "==2.21" }, + "pyee": { + "hashes": [ + "sha256:2770c4928abc721f46b705e6a72b0c59480c4a69c9a83ca0b00bb994f1ea4b32", + "sha256:9f066570130c554e9cc12de5a9d86f57c7ee47fece163bbdaa3e9c933cfbdfa5" + ], + "version": "==9.0.4" + }, "pyexcel": { "hashes": [ "sha256:ddc6904512bfa2ecda509fb3b58229bb30db14498632fd9e7a5ba7bbfb02ed1b", @@ -942,6 +986,30 @@ "index": "pypi", "version": "==3.6.0" }, + "pytest": { + "hashes": [ + "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32", + "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a" + ], + "markers": "python_version >= '3.7'", + "version": "==7.4.0" + }, + "pytest-base-url": { + "hashes": [ + "sha256:e1e88a4fd221941572ccdcf3bf6c051392d2f8b6cef3e0bc7da95abec4b5346e", + "sha256:ed36fd632c32af9f1c08f2c2835dcf42ca8fcd097d6ed44a09f253d365ad8297" + ], + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==2.0.0" + }, + "pytest-playwright": { + "hashes": [ + "sha256:83a896b1b28bfaa081ca9ea27229a06a114e106e2e62fb3d5f06544748fbc1fe", + "sha256:9bf79c633c97dd1405308b8d3600e6c8c2a200a733e2f36c5a150ba4701936f8" + ], + "index": "pypi", + "version": "==0.3.3" + }, "python-dateutil": { "hashes": [ "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", @@ -966,6 +1034,14 @@ "markers": "python_version >= '3.6'", "version": "==2.0.7" }, + "python-slugify": { + "hashes": [ + "sha256:70ca6ea68fe63ecc8fa4fcf00ae651fc8a5d02d93dcd12ae6d4fc7ca46c4d395", + "sha256:ce0d46ddb668b3be82f4ed5e503dbc33dd815d83e2eb6824211310d3fb172a27" + ], + "markers": "python_version >= '3.7'", + "version": "==8.0.1" + }, "pytz": { "hashes": [ "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588", @@ -1118,6 +1194,13 @@ ], "version": "==2.0.1" }, + "text-unidecode": { + "hashes": [ + "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", + "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93" + ], + "version": "==1.3" + }, "texttable": { "hashes": [ "sha256:290348fb67f7746931bcdfd55ac7584ecd4e5b0846ab164333f0794b121760f2", @@ -1125,6 +1208,14 @@ ], "version": "==1.6.7" }, + "tomli": { + "hashes": [ + "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" + ], + "markers": "python_version < '3.11'", + "version": "==2.0.1" + }, "typing-extensions": { "hashes": [ "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", @@ -1215,19 +1306,19 @@ }, "boto3": { "hashes": [ - "sha256:cfcb20d5784428f31d89889e68b26efeda90f231c3119eef4af8b25ad405c55f", - "sha256:d5ac6599951fdd519ed26c6fe15c41a7aa4021cb9adce33167344f8ce5cdb07b" + "sha256:b2d178c8a56fe3e4c9b123dccdff20e9555d12a597b72627fa659aa6295e238a", + "sha256:db6443fd2c65d9f35f671b03bacb0592b62d06884395ed65d75922ccddc34c2e" ], "markers": "python_version >= '3.7'", - "version": "==1.28.12" + "version": "==1.28.13" }, "botocore": { "hashes": [ - "sha256:7e5db466c762a071bb58c9a39d070f1333ce4f4ba6fdf9820ba21e87bd4c7e29", - "sha256:86380672151866b5e425636e3ebad74f2b83e7163e36ef5d38d11a04b9cba33b" + "sha256:78b96afbd88b8bd4c0967611a4cedddd9ea33d8601309dc351f81cbb5479d976", + "sha256:9a5080ea2a444f0447a7a1a79f64252ae2a1417b6c13a54656ee991cb610dd4e" ], "markers": "python_version >= '3.7'", - "version": "==1.31.12" + "version": "==1.31.13" }, "cachecontrol": { "extras": [ @@ -1395,7 +1486,7 @@ "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==3.2.0" }, "cryptography": { @@ -1782,7 +1873,7 @@ "sha256:4659bc2a667783e7a15d190f6fccf8b2486685b6dba4c19c3876314769c57526", "sha256:b4fa3a7a0be38243123cf9d1f3518da10c51bdb165a2b2985566247f9155a7d3" ], - "markers": "python_version >= '3.6'", + "markers": "python_full_version >= '3.6.0'", "version": "==32.0.1" }, "pluggy": { @@ -1845,7 +1936,7 @@ "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32", "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a" ], - "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==7.4.0" }, "pytest-env": { @@ -1955,7 +2046,7 @@ "sha256:8f87bc7ee54675732fa66a05ebfe489e27264caeeff3728c945d25971b6485ec", "sha256:d653d6bccede5844304c605d5aac802c7cf9621efd700b46c7ec2b51ea914898" ], - "markers": "python_version >= '3.7'", + "markers": "python_full_version >= '3.7.0'", "version": "==13.4.2" }, "s3transfer": { diff --git a/README.md b/README.md index bbb298684..202b69e17 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,9 @@ The [Notify API](https://github.com/GSA/notifications-api) provides the UI's bac ### Common steps -1. Install pre-requisites for setup: +1. Install pre-requisites for setup (on a Mac): + - Install XCode or at least the XCode Command Line Tools + - [Homebrew](https://brew.sh/) (follow instructions on page) - [jq](https://stedolan.github.io/jq/): `brew install jq` - [terraform](https://www.terraform.io/): `brew install terraform` or `brew install tfenv` and use `tfenv` to install `terraform ~> 1.4.0` - [cf-cli@8](https://docs.cloudfoundry.org/cf-cli/install-go-cli.html): `brew install cloudfoundry/tap/cf-cli@8` @@ -44,6 +46,23 @@ The [Notify API](https://github.com/GSA/notifications-api) provides the UI's bac `make bootstrap` + If you run into certificate errors at the `playwright install` step, try doing this: + + 1. Run `brew --prefix` to see Homebrew's root directory + + 1. Create or modify the local `.env` file in the project and add this line: + + `NODE_EXTRA_CA_CERTS=/CHANGE-TO-HOMEBREW-INSTALL-PATH/etc/ca-certificates/cert.pem` + + Make sure to change `CHANGE-TO-HOMEBREW-INSTALL-PATH` to the path given by `brew --prefix` in the step above. + For example, if `brew --prefix` gave `/opt/homebrew` as output, then the line would look like this: + + `NODE_EXTRA_CA_CERTS=/opt/homebrew/etc/ca-certificates/cert.pem` + + 1. Save the changes to the `.env` file + + 1. Run `make bootstrap` again + 1. Run the Flask server `make run-flask` diff --git a/docs/end_to_end_tests.md b/docs/end_to_end_tests.md new file mode 100644 index 000000000..906200a1c --- /dev/null +++ b/docs/end_to_end_tests.md @@ -0,0 +1,120 @@ +# Working with End-to-End Tests + +End-to-End (E2E) tests are an important part of a assessing the overall +integrity and stability of a system. They are a part of the overall +test suite and serve the function of simulating a user working through +the application. By having comprehensive E2E tests in place, we can +instill higher confidence that future changes and refactorings won't +negatively impact any user experience or break existing functionality. + +The US Notify project leverages [`pytest`](https://pytest.org/) for its +existing test suite (at least on the Python side of things) and is now +leveraging [Playwright for Python](https://playwright.dev/python/) +along with its `pytest` plugin for the E2E tests. + + +## Getting Started + +To work with the E2E tests in US Notify, you need to make sure you have +all of the necessary components installed. The quick and easy way to do +this is to use the Makefile as you did for the initial project setup. In +fact, if you've already done this, you are already set to go! If not, +then run the bootstrap command in your shell: + +```sh +make bootstrap +``` + +This takes care of installing all of your dependencies, including those +now needed for Playwright. + +If you run into certificate errors at the `playwright install` step, try +doing this: + +1. Run `brew --prefix` to see Homebrew's root directory + +1. Create or modify the local `.env` file in the project and add this line: + + `NODE_EXTRA_CA_CERTS=/CHANGE-TO-HOMEBREW-INSTALL-PATH/etc/ca-certificates/cert.pem` + + Make sure to change `CHANGE-TO-HOMEBREW-INSTALL-PATH` to the path + given by `brew --prefix` in the step above. For example, if `brew --prefix` + gave `/opt/homebrew` as output, then the line would look like this: + + `NODE_EXTRA_CA_CERTS=/opt/homebrew/etc/ca-certificates/cert.pem` + +1. Save the changes to the `.env` file + +1. Run `make bootstrap` again + + +### Manual Installation + +If you need to install things separately, you'll still need to make sure +your environment is set up and configured as outlined in the README. + +At your shell in the project root folder, run the following commands: + +```sh +pipenv install pytest-playwright +pipenv run playwright install --with-deps +``` + +This will install Playwright and its `pytest` plugin, then the +additional dependencies that Playwright requires. + +See more details on the [Playwright for Python Installation page](https://playwright.dev/python/docs/intro). + + +## Local Configuration + +In order to run the E2E tests successfully on your local machine, you'll also +need to make sure you have a `.env` file in the root project folder, and that it +has at least these environment variables set in it: + +``` +NOTIFY_STAGING_URI +NOTIFY_STAGING_HTTP_AUTH_USER +NOTIFY_STAGING_HTTP_AUTH_PASSWORD +``` + +This file is **not** checked into source control and is configured to be +ignored in the project's `.gitignore` file; please be careful that it is +not committed to the repo and pushed! + + +## Running E2E Tests Locally + +To run the E2E tests on your local machine, type this command in your +shell at the project root directory: + +```sh +make e2e-test +``` + +You should see `pytest` start producing output and the existing E2E +tests run in multiple headless browsers. + + +## How to Create and Maintain E2E Tests + +All of the E2E tests are found in the `tests/end_to_end` folder and are +written as `pytest` scripts using [Playwright's Python Framework](https://playwright.dev/python/docs/writing-tests). + + +## Maintaining E2E Tests with GitHub + +The E2E tests are configured to run as a separate GitHub action as a +part of our other checks found in `.github/workflows/checks.yml`. + +The E2E tests are not run as a part of the regular unit test suite; if +you look at the `Makefile` you'll see that the tests are two separate +commands, with the E2E tests configured separately. + +This is done for a couple of reasons: + +- Keeps unit tests isolated from the E2E tests +- Allows us to configure E2E tests separately + +The environment variables are managed as a part of the GitHub +repository settings. diff --git a/tests/conftest.py b/tests/conftest.py index 79aa06b8c..69ab8864e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3384,3 +3384,15 @@ def webauthn_credential_2(): 'registration_response': 'stuff', 'created_at': '2021-05-14T16:57:14.154185Z', } + + +@pytest.fixture(scope='session') +def end_to_end_auth_context(browser): + # Create a context with HTTP Authentication credentials for Playwright E2E + # tests. + context = browser.new_context(http_credentials={ + 'username': os.environ.get('NOTIFY_STAGING_HTTP_AUTH_USER'), + 'password': os.environ.get('NOTIFY_STAGING_HTTP_AUTH_PASSWORD'), + }) + + yield context diff --git a/tests/end_to_end/test_landing_and_sign_in_pages.py b/tests/end_to_end/test_landing_and_sign_in_pages.py new file mode 100644 index 000000000..82e7d02eb --- /dev/null +++ b/tests/end_to_end/test_landing_and_sign_in_pages.py @@ -0,0 +1,109 @@ +import os +import re + +from playwright.sync_api import expect + + +def test_landing_page(end_to_end_auth_context): + # Open a new page and go to the staging site. + page = end_to_end_auth_context.new_page() + page.goto(os.environ.get('NOTIFY_STAGING_URI')) + + # Check the page title exists and matches what we expect. + expect(page).to_have_title(re.compile('U.S. Notify')) + + # Retrieve some prominent elements on the page for testing. + main_header = page.get_by_role( + 'heading', + name='Send text messages to your participants' + ) + sign_in_button = page.get_by_role('link', name='Sign in') + benefits_studio_email = page.get_by_role( + 'link', + name='tts-benefits-studio@gsa.gov' + ) + + # Check to make sure the elements are visible. + expect(main_header).to_be_visible() + expect(sign_in_button).to_be_visible() + expect(benefits_studio_email).to_be_visible() + + # Check to make sure the sign-in button and email links are correct. + expect(sign_in_button).to_have_attribute('href', '/sign-in') + expect(benefits_studio_email).to_have_attribute( + 'href', + 'mailto:tts-benefits-studio@gsa.gov' + ) + + # Retrieve all other main content headers and check that they're + # visible. + content_headers = [ + 'Control your content', + 'See how your messages perform', + 'No technical integration needed', + 'About the product', + ] + + for content_header in content_headers: + expect( + page.get_by_role('heading', name=re.compile(content_header)) + ).to_be_visible() + + +def test_sign_in_page(end_to_end_auth_context): + # Open a new page and go to the staging site. + page = end_to_end_auth_context.new_page() + page.goto(os.environ.get('NOTIFY_STAGING_URI')) + + sign_in_button = page.get_by_role('link', name='Sign in') + + # Test trying to sign in. + sign_in_button.click() + + # Check the page title exists and matches what we expect. + # NOTE: The dash is a special character! It had to be copied from + # the template itself. + # TODO: Improve this check, or change it so no special character is + # needed. Better yet, fix the template(s) character too. + expect(page).to_have_title(re.compile('Sign in – U.S. Notify')) + + # Check for the sign in heading. + sign_in_heading = page.get_by_role('heading', name='Sign in') + expect(sign_in_heading).to_be_visible() + + # Check for the sign in form elements. + # NOTE: Playwright cannot find input elements by role and recommends using + # get_by_label() instead; however, hidden form elements do not have + # labels associated with them, hence the XPath! + # See https://playwright.dev/python/docs/api/class-page#page-get-by-label + # and https://playwright.dev/python/docs/locators#locate-by-css-or-xpath + # for more information. + email_address_input = page.get_by_label('Email address') + password_input = page.get_by_label('Password') + csrf_token = page.locator('xpath=//input[@name="csrf_token"]') + continue_button = page.get_by_role('button', name=re.compile('Continue')) + forgot_password_link = page.get_by_role( + 'link', + name='Forgot your password?' + ) + + # Make sure form elements are visible and not visible as expected. + expect(email_address_input).to_be_visible() + expect(password_input).to_be_visible() + expect(continue_button).to_be_visible() + expect(forgot_password_link).to_be_visible() + + expect(csrf_token).to_be_hidden() + + # Make sure form elements are configured correctly with the right + # attributes. + expect(email_address_input).to_have_attribute('type', 'email') + expect(password_input).to_have_attribute('type', 'password') + expect(csrf_token).to_have_attribute('type', 'hidden') + expect(continue_button).to_have_attribute('type', 'submit') + expect(forgot_password_link).to_have_attribute( + 'href', + '/forgot-password' + ) + + # TODO: Figure out how to actually sign in... From 27a193160f6f8f118a90e15288124181a4381db4 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Fri, 28 Jul 2023 11:03:37 -0400 Subject: [PATCH 08/11] 619 - Removing all mention of emails from the pilot (#615) --- app/templates/views/dashboard/_totals.html | 6 ++--- app/templates/views/dashboard/_usage.html | 6 ++--- app/templates/views/usage.html | 8 +++--- tests/app/main/views/test_dashboard.py | 31 +++++++++++----------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/app/templates/views/dashboard/_totals.html b/app/templates/views/dashboard/_totals.html index 6ea69e13f..62d4af437 100644 --- a/app/templates/views/dashboard/_totals.html +++ b/app/templates/views/dashboard/_totals.html @@ -2,7 +2,7 @@
-
+
{{ big_number_with_status( statistics['sms']['requested'], statistics['sms']['requested']|message_count_label('sms', suffix='sent'), @@ -14,7 +14,7 @@ smaller=True, ) }}
-
+
diff --git a/app/templates/views/dashboard/_usage.html b/app/templates/views/dashboard/_usage.html index 61dc279d7..34e63c496 100644 --- a/app/templates/views/dashboard/_usage.html +++ b/app/templates/views/dashboard/_usage.html @@ -1,7 +1,7 @@ {% from "components/big-number.html" import big_number %}
-
+
{% if sms_cost %} {{ big_number( @@ -15,9 +15,9 @@ {% endif %}
-
+
diff --git a/app/templates/views/usage.html b/app/templates/views/usage.html index b759ceae2..44dd72a43 100644 --- a/app/templates/views/usage.html +++ b/app/templates/views/usage.html @@ -39,16 +39,16 @@ {% endfor %}
-
+ {#

Emails

{{ big_number(emails_sent, 'email disabled during SMS pilot', smaller=True) }} {{ big_number("", '', smaller=True) }}
-
+
#}
- +
#} {% if months %}
diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 41f317135..beb7c87e9 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -746,12 +746,12 @@ def test_correct_font_size_for_big_numbers( ) assert ( - len(page.select_one('[data-key=totals]').select('.grid-col-6')) - ) == ( - len(page.select_one('[data-key=usage]').select('.grid-col-6')) + len(page.select_one('[data-key=totals]').select('.grid-col-12')) ) == ( + # len(page.select_one('[data-key=usage]').select('.grid-col-6')) + # ) == ( len(page.select('.big-number-with-status .big-number-smaller')) - ) == 2 + ) == 1 def test_should_not_show_jobs_on_dashboard_for_users_with_uploads_page( @@ -804,14 +804,13 @@ def test_usage_page( assert normalize_spaces(unselected_nav_links[1].text) == '2009 to 2010 fiscal year' annual_usage = page.find_all('div', {'class': 'govuk-grid-column-one-half'}) - # print(annual_usage) # annual stats are shown in two rows, each with three column; email is col 1 # email_column = normalize_spaces(annual_usage[0].text + annual_usage[2].text) # assert 'Emails' in email_column # assert '1,000 sent' in email_column - sms_column = normalize_spaces(annual_usage[0].text + annual_usage[1].text) + sms_column = normalize_spaces(annual_usage[0].text) assert 'Text messages' in sms_column assert '251,800 sent' in sms_column assert '250,000 free allowance' in sms_column @@ -845,8 +844,9 @@ def test_usage_page_no_sms_spend( ) annual_usage = page.find_all('div', {'class': 'govuk-grid-column-one-half'}) - sms_column = normalize_spaces(annual_usage[0].text + annual_usage[1].text) + sms_column = normalize_spaces(annual_usage[0].text) assert 'Text messages' in sms_column + assert '1,000 sent' in sms_column assert '250,000 free allowance' in sms_column assert '249,000 free allowance remaining' in sms_column assert '$0.00 spent' not in sms_column @@ -879,7 +879,7 @@ def test_usage_page_monthly_breakdown( assert '1,230 text messages at 1.70p' in monthly_breakdown -@pytest.mark.parametrize( +@ pytest.mark.parametrize( 'now, expected_number_of_months', [ (freeze_time("2017-03-31 11:09:00.061258"), 6), (freeze_time("2017-01-01 11:09:00.061258"), 4) @@ -954,7 +954,7 @@ def test_usage_page_for_invalid_year( ) -@freeze_time("2012-03-31 12:12:12") +@ freeze_time("2012-03-31 12:12:12") def test_future_usage_page( client_request, mock_get_annual_usage_for_service_in_future, @@ -1199,7 +1199,7 @@ def test_get_dashboard_totals_adds_percentages(): assert get_dashboard_totals(stats)['email']['failed_percentage'] == '0' -@pytest.mark.parametrize( +@ pytest.mark.parametrize( 'failures,expected', [ (2, False), (3, False), @@ -1253,7 +1253,7 @@ def _stats(requested, delivered, failed): return {'requested': requested, 'delivered': delivered, 'failed': failed} -@pytest.mark.parametrize('dict_in, expected_failed, expected_requested', [ +@ pytest.mark.parametrize('dict_in, expected_failed, expected_requested', [ ( {}, 0, @@ -1433,7 +1433,7 @@ def test_breadcrumb_shows_if_service_is_suspended( assert 'Suspended' in page.select_one('.navigation-service-name').text -@pytest.mark.parametrize('permissions', ( +@ pytest.mark.parametrize('permissions', ( ['email', 'sms'], )) def test_service_dashboard_shows_usage( @@ -1453,9 +1453,10 @@ def test_service_dashboard_shows_usage( page.select_one('[data-key=usage]').text ) == ( '$29.85 ' - 'spent on text messages ' - '0 ' - 'email disabled during SMS pilot' + 'spent on text messages' + # Disabled for pilot + # '0 ' + # 'email disabled during SMS pilot' ) From 817ebbe923a2e28fcbfccc9aa89ab2a235bcd54e Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Fri, 28 Jul 2023 11:10:02 -0400 Subject: [PATCH 09/11] Small class rearrangement on landing page (#646) --- app/templates/views/signedout.html | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/templates/views/signedout.html b/app/templates/views/signedout.html index a7ebe74f9..706e0d1ec 100644 --- a/app/templates/views/signedout.html +++ b/app/templates/views/signedout.html @@ -12,10 +12,10 @@ U.S. Notify {% block content %} -
-
+
+
-
+

Send text messages to your participants

U.S. Notify is a text messaging service that helps federal, state, local, tribal, and territorial governments more effectively communicate with their program participants.

@@ -26,7 +26,7 @@ U.S. Notify

If you are interested in using U.S. Notify in the future, please contact
tts-benefits-studio@gsa.gov to learn more.

-
+ @@ -35,13 +35,13 @@ U.S. Notify
-
+

Control your content

You do not need any technical knowledge to create message templates.

-
+
Example screenshot of adding a new text message template
@@ -49,13 +49,13 @@ U.S. Notify
-
+

See how your messages perform

Track how many messages you’ve sent and find out which ones are not being delivered.

-
+
A screenshot of U.S. Notify showing counts of emails and text messages sent
@@ -63,13 +63,13 @@ U.S. Notify
-
+

No technical integration needed

Upload a spreadsheet of phone numbers and U.S. Notify sends batches of messages for you.

-
+
A screenshot of a spreadsheet with phone numbers, names, and a reference number
From 242c7acd3409b8bca0f71af8a83ff09c2098af2e Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Fri, 28 Jul 2023 11:12:46 -0400 Subject: [PATCH 10/11] Changing U.S. Notify to Notify.gov (#656) --- app/assets/error_pages/5xx.html | 2 +- .../images/product/01-templates-no-chrome.svg | 9 ++---- .../images/product/02-reporting-no-chrome.svg | 9 ++---- .../product/03-spreadsheet-no-chrome.svg | 13 +++----- .../uswds/_uswds-theme-custom-styles.scss | 3 +- app/main/views/add_service.py | 2 +- app/main/views/feedback.py | 4 +-- app/templates/admin_template.html | 2 +- .../uk_components/header/template.njk | 6 ++-- app/templates/error/401.html | 2 +- app/templates/error/500.html | 2 +- app/templates/main_template.html | 2 +- app/templates/partials/jobs/status.html | 2 +- .../views/accessibility_statement.html | 10 +++--- app/templates/views/cookies.html | 4 +-- app/templates/views/documentation.html | 2 +- app/templates/views/features.html | 2 +- app/templates/views/features/emails.html | 2 +- .../views/features/text-messages.html | 2 +- app/templates/views/get-started.html | 2 +- .../guidance/branding-and-customisation.html | 4 +-- app/templates/views/guidance/index.html | 4 +-- .../organizations/organization/index.html | 2 +- app/templates/views/pricing/how-to-pay.html | 2 +- app/templates/views/pricing/index.html | 2 +- app/templates/views/privacy.html | 16 +++++----- app/templates/views/security.html | 2 +- .../branding/email-branding-govuk-org.html | 4 +-- .../branding/email-branding-govuk.html | 4 +-- .../views/service-settings/set-email.html | 2 +- app/templates/views/signedout.html | 32 +++++++++---------- app/templates/views/support/form.html | 2 +- app/templates/views/support/index.html | 2 +- app/templates/views/support/public.html | 6 ++-- app/templates/views/support/triage.html | 4 +-- .../views/templates/action_blocked.html | 2 +- app/templates/views/terms-of-use.html | 4 +-- app/templates/views/trial-mode.html | 2 +- paas-failwhale/index.html | 2 +- tests/app/main/test_errorhandlers.py | 12 +++---- .../views/organizations/test_organizations.py | 2 +- .../service_settings/test_service_settings.py | 4 +-- tests/app/main/views/test_add_service.py | 2 +- tests/app/main/views/test_conversation.py | 2 +- tests/app/main/views/test_feedback.py | 6 ++-- tests/app/main/views/test_index.py | 16 +++++----- tests/app/main/views/test_jobs.py | 6 ++-- tests/app/main/views/test_template_folders.py | 32 +++++++++---------- tests/app/main/views/test_templates.py | 2 +- 49 files changed, 125 insertions(+), 139 deletions(-) diff --git a/app/assets/error_pages/5xx.html b/app/assets/error_pages/5xx.html index a6bf68571..fcf9db915 100644 --- a/app/assets/error_pages/5xx.html +++ b/app/assets/error_pages/5xx.html @@ -4,7 +4,7 @@ - Sorry, there is a problem with the service – U.S. Notify + Sorry, there is a problem with the service – Notify.gov diff --git a/app/assets/images/product/01-templates-no-chrome.svg b/app/assets/images/product/01-templates-no-chrome.svg index ceadfd829..1f5bf9ad0 100644 --- a/app/assets/images/product/01-templates-no-chrome.svg +++ b/app/assets/images/product/01-templates-no-chrome.svg @@ -1,4 +1,4 @@ - + @@ -69,8 +69,7 @@ - - + @@ -86,12 +85,8 @@ - - - - diff --git a/app/assets/images/product/02-reporting-no-chrome.svg b/app/assets/images/product/02-reporting-no-chrome.svg index d6ef5e90b..e82ec8303 100644 --- a/app/assets/images/product/02-reporting-no-chrome.svg +++ b/app/assets/images/product/02-reporting-no-chrome.svg @@ -1,4 +1,4 @@ - + @@ -69,8 +69,7 @@ - - + @@ -80,12 +79,8 @@ - - - - diff --git a/app/assets/images/product/03-spreadsheet-no-chrome.svg b/app/assets/images/product/03-spreadsheet-no-chrome.svg index 6c5a6f074..8580fa9ff 100644 --- a/app/assets/images/product/03-spreadsheet-no-chrome.svg +++ b/app/assets/images/product/03-spreadsheet-no-chrome.svg @@ -97,12 +97,11 @@ - - + - + @@ -110,16 +109,12 @@ - - - - + - - + diff --git a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss index 3a6a43dd0..ed7b9aa70 100644 --- a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss +++ b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss @@ -22,8 +22,9 @@ i.e. @use "uswds-core" as *; -.usa-logo { +.usa-header--extended .usa-logo { font-family: family("sans"); + margin: units(4) 0; img { @include at-media($theme-header-min-width) { width: 80px; diff --git a/app/main/views/add_service.py b/app/main/views/add_service.py index 88f498969..f42331f43 100644 --- a/app/main/views/add_service.py +++ b/app/main/views/add_service.py @@ -35,7 +35,7 @@ def _create_example_template(service_id): example_sms_template = service_api_client.create_service_template( 'Example text message template', 'sms', - 'Hi, I’m trying out U.S. Notify. Today is ((day of week)) and my favorite color is ((color)).', + 'Hi, I’m trying out Notify.gov. Today is ((day of week)) and my favorite color is ((color)).', service_id, ) return example_sms_template diff --git a/app/main/views/feedback.py b/app/main/views/feedback.py index ab0bd3328..d117affbe 100644 --- a/app/main/views/feedback.py +++ b/app/main/views/feedback.py @@ -76,7 +76,7 @@ def triage(ticket_type=PROBLEM_TICKET_TYPE): form=form, page_title={ PROBLEM_TICKET_TYPE: 'Report a problem', - GENERAL_TICKET_TYPE: 'Contact U.S. Notify support', + GENERAL_TICKET_TYPE: 'Contact Notify.gov support', }.get(ticket_type) ) @@ -151,7 +151,7 @@ def feedback(ticket_type): ), show_status_page_banner=(ticket_type == PROBLEM_TICKET_TYPE), page_title={ - GENERAL_TICKET_TYPE: 'Contact U.S. Notify support', + GENERAL_TICKET_TYPE: 'Contact Notify.gov support', PROBLEM_TICKET_TYPE: 'Report a problem', QUESTION_TICKET_TYPE: 'Ask a question or give feedback', }.get(ticket_type), diff --git a/app/templates/admin_template.html b/app/templates/admin_template.html index f56108e5c..703719a73 100644 --- a/app/templates/admin_template.html +++ b/app/templates/admin_template.html @@ -35,7 +35,7 @@ {% endblock %} {% block pageTitle %} - {% block per_page_title %}{% endblock %} – U.S. Notify + {% block per_page_title %}{% endblock %} – Notify.gov {% endblock %} {% block bodyStart %} diff --git a/app/templates/components/uk_components/header/template.njk b/app/templates/components/uk_components/header/template.njk index 6464705b1..439165036 100644 --- a/app/templates/components/uk_components/header/template.njk +++ b/app/templates/components/uk_components/header/template.njk @@ -60,13 +60,13 @@
diff --git a/app/templates/error/401.html b/app/templates/error/401.html index 64f9b155b..b579650dc 100644 --- a/app/templates/error/401.html +++ b/app/templates/error/401.html @@ -4,6 +4,6 @@

You’re not authorised to see this page

-

Sign in to U.S. Notify and try again.

+

Sign in to Notify.gov and try again.

{% endblock %} diff --git a/app/templates/error/500.html b/app/templates/error/500.html index 76890ce0e..db505a014 100644 --- a/app/templates/error/500.html +++ b/app/templates/error/500.html @@ -4,7 +4,7 @@

- Sorry, there’s a problem with U.S. Notify + Sorry, there’s a problem with Notify.gov

Try again later. diff --git a/app/templates/main_template.html b/app/templates/main_template.html index 54535b88d..51f0c2369 100644 --- a/app/templates/main_template.html +++ b/app/templates/main_template.html @@ -7,7 +7,7 @@ - {% block pageTitle %}U.S. Notify{% endblock %} + {% block pageTitle %}Notify.gov{% endblock %} {# Hardcoded value of $govuk-black #} {% if config['NR_MONITOR_ON'] %} diff --git a/app/templates/partials/jobs/status.html b/app/templates/partials/jobs/status.html index ce0245a6d..e826fc0cf 100644 --- a/app/templates/partials/jobs/status.html +++ b/app/templates/partials/jobs/status.html @@ -15,7 +15,7 @@ Notify cannot send these messages because you have reached a limit. You can only send {{ current_service.message_limit|format_thousands }} messages per day and {{ 250000|format_thousands }} messages in total.

- Upload this spreadsheet again tomorrow or contact the U.S. Notify team to raise the limit. + Upload this spreadsheet again tomorrow or contact the Notify.gov team to raise the limit.

{% endif %}
diff --git a/app/templates/views/accessibility_statement.html b/app/templates/views/accessibility_statement.html index 3b09eec3a..6cd07dc22 100644 --- a/app/templates/views/accessibility_statement.html +++ b/app/templates/views/accessibility_statement.html @@ -19,7 +19,7 @@ ) }}

- This accessibility statement applies to the U.S. Notify domain. + This accessibility statement applies to the Notify.gov domain.

@@ -66,7 +66,7 @@

Feedback and contact information

- If you need any part of this service in a different format like large print, audio recording or braille, contact the U.S. Notify team. + If you need any part of this service in a different format like large print, audio recording or braille, contact the Notify.gov team.

@@ -76,7 +76,7 @@

Reporting accessibility problems with this website

- We’re always looking to improve the accessibility of this website. If you find any problems not listed on this page or think we’re not meeting accessibility requirements, contact the U.S. Notify team. + We’re always looking to improve the accessibility of this website. If you find any problems not listed on this page or think we’re not meeting accessibility requirements, contact the Notify.gov team.

Technical information about this website’s accessibility

@@ -88,7 +88,7 @@

- U.S. Notify is partially compliant with the Web Content Accessibility Guidelines (WCAG) version 2.1 AA standard, due to the non-compliances listed below. + Notify.gov is partially compliant with the Web Content Accessibility Guidelines (WCAG) version 2.1 AA standard, due to the non-compliances listed below.

Non-accessible content

@@ -195,6 +195,6 @@

- We decided which pages to test based on the most common tasks that U.S. Notify users need to complete. We also tested a sample of pages with common user interface components. + We decided which pages to test based on the most common tasks that Notify.gov users need to complete. We also tested a sample of pages with common user interface components.

--> {% endblock %} diff --git a/app/templates/views/cookies.html b/app/templates/views/cookies.html index 1263b91e6..11f918c05 100644 --- a/app/templates/views/cookies.html +++ b/app/templates/views/cookies.html @@ -21,7 +21,7 @@

Cookies are small files saved on your phone, tablet, or computer when you visit a website.

-

We use cookies to make U.S. Notify work and collect information about how you use our service.

+

We use cookies to make Notify.gov work and collect information about how you use our service.

Essential cookies

@@ -73,7 +73,7 @@ Google Analytics stores anonymized information about:

    -
  • how you got to U.S. Notify
  • +
  • how you got to Notify.gov
  • the pages you visit on Notify and how long you spend on them
  • any errors you see while using Notify
diff --git a/app/templates/views/documentation.html b/app/templates/views/documentation.html index 9ebb68219..e0ac1452b 100644 --- a/app/templates/views/documentation.html +++ b/app/templates/views/documentation.html @@ -7,7 +7,7 @@ {% block content_column_content %}

Documentation

-

This documentation is for developers who want to integrate the U.S. Notify API with a web application or back office system.

+

This documentation is for developers who want to integrate the Notify.gov API with a web application or back office system.

Client libraries

Links to documentation open in a new tab.

    diff --git a/app/templates/views/features.html b/app/templates/views/features.html index 1e03dd923..7c529d57d 100644 --- a/app/templates/views/features.html +++ b/app/templates/views/features.html @@ -10,7 +10,7 @@ {% block content_column_content %}

    Features

    -

    If you work for the government, you can use U.S. Notify to keep your users updated.

    +

    If you work for the government, you can use Notify.gov to keep your users updated.

    Notify makes it easy to create, customize, and send text messages.

    +