From 927f810dde06d382272bf7f77e4a33c63aec1472 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Mon, 18 Dec 2023 15:38:36 -0500 Subject: [PATCH 01/53] 1031 - Creating cards of the Team Member area so they're easier to scroll through if there are a lot of Team Members --- .../uswds/_uswds-theme-custom-styles.scss | 105 ++++++++++------- app/templates/views/manage-users.html | 106 +++++++++--------- tests/app/main/views/test_manage_users.py | 19 ++-- tests/app/main/views/test_templates.py | 4 +- 4 files changed, 122 insertions(+), 112 deletions(-) diff --git a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss index 9b88d44a7..a1e15b995 100644 --- a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss +++ b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss @@ -45,12 +45,12 @@ i.e. font-size: size("body", 4); } &> .usa-nav__primary-item:last-child { - margin-left: auto; + margin-left: auto; @include u-margin-right(-4); } } -.usa-nav__primary +.usa-nav__primary h1 { @@ -120,6 +120,25 @@ td.table-empty-message { border: 0; } +.user-list { + display: inline-flex; + flex-wrap: wrap; + gap: units(2); + .user-list-item { + flex: 1 1 calc(50% - units(2)); + border: 1px solid color('gray-cool-10'); + padding: units(2); + .tick-cross-list-permissions { + padding-left: units(2); + } + .hint { + display: block; + font-size: size("body", "sm"); + font-weight: normal; + } + } +} + .template-list-item-without-ancestors .template-list-folder:active, .template-list-item-without-ancestors .template-list-folder:active::before, .template-list-item-without-ancestors .template-list-folder:focus, @@ -136,7 +155,7 @@ td.table-empty-message { .template-list-folder { background: url(../img/material-icons/folder.svg) no-repeat; padding-left: units(4); - display: inline-block; + display: inline-block; background-position: 0; } @@ -166,7 +185,7 @@ td.table-empty-message { .template-list-template { background: url(../img/material-icons/description.svg) no-repeat; padding-left: units(4); - display: inline-flex; + display: inline-flex; } .js-enabled .live-search { @@ -214,7 +233,7 @@ td.table-empty-message { } .usa-hero { - background-image: none; + background-image: none; } .usa-prose { @@ -232,7 +251,7 @@ td.table-empty-message { } .navigation-service.usa-breadcrumb { - -bottom: 0; + -bottom: 0; } // Dashboard @@ -246,13 +265,13 @@ td.table-empty-message { text-decoration: none; &:hover{ background: color("blue-warm-70v"); - } + } } span { - color: white; + color: white; } .big-number-smaller { - display: flex; + display: flex; flex-direction: column; .big-number-number { font-size: units(5); @@ -264,15 +283,15 @@ td.table-empty-message { } .big-number-status { background: color("green-cool-40v"); - display: flex; + display: flex; padding: units(1) units(2); &--failing { - padding: 0; + padding: 0; a.usa-link { color: white; background: color("red-warm-50v"); padding: units(1) units(2); - margin: 0; + margin: 0; width: 100%; &:hover { background: color("red-warm-60v"); @@ -282,12 +301,12 @@ td.table-empty-message { } } .usa-table { - width: 100%; + width: 100%; caption { - margin-bottom: 0; + margin-bottom: 0; } .table-field-center-aligned { - text-align: center; + text-align: center; } .template-statistics-table-template-name { padding-left: units(4); @@ -300,32 +319,32 @@ td.table-empty-message { .dashboard-table { table { - width: 100%; + width: 100%; } .file-list-filename { font-weight: bold; } .file-list-hint { - margin: 0; + margin: 0; } .table-field, .table-field-right-aligned { - width: 50%; + width: 50%; } &.usage-table { .table-field, .table-field-left-aligned, .table-field-right-aligned { - width: auto; + width: auto; } } } .usage-table { ul { - list-style: none; - padding: 0; - margin: 0; + list-style: none; + padding: 0; + margin: 0; } .big-number-smallest { - display: flex; + display: flex; flex-direction: column; } } @@ -336,27 +355,27 @@ td.table-empty-message { padding: units(1) 0 units(1) units(1); margin: units(2) 0 units(5); ul { - padding: 0; - margin: 0; - list-style: none; - } + padding: 0; + margin: 0; + list-style: none; + } } // Tabs .tabs { .pill { - display: flex; + display: flex; list-style: none; - padding: 0; + padding: 0; .pill-item__container { border: 1px solid color("gray-cool-10"); - flex: 1; - display: flex; - flex-direction: column; - text-align: center; + flex: 1; + display: flex; + flex-direction: column; + text-align: center; font-size: units(2); - a { + a { padding: units(4); .big-number-smaller { font-size: units(5); @@ -367,7 +386,7 @@ td.table-empty-message { } &:not(.pill-item--selected):hover { background: color("blue-warm-70v"); - } + } &.pill-item--selected:hover { color: color("blue-60v"); } @@ -379,12 +398,12 @@ td.table-empty-message { // Etc .email-brand, .browse-list { - padding: 0; - margin: 0; - list-style: none; + padding: 0; + margin: 0; + list-style: none; margin-bottom: units(2); li { - padding: 8px 0; + padding: 8px 0; } } @@ -392,7 +411,7 @@ details form { box-sizing:border-box; } -// Textbox highlight +// Textbox highlight .textbox-highlight { @@ -440,7 +459,7 @@ details form { .placeholder, .placeholder-conditional { background-color: #fff; - position: relative; + position: relative; &:after { content: ""; background-color: color("yellow-20v"); @@ -449,9 +468,9 @@ details form { position: absolute; top: 0; left: 5px; - right: 6px; + right: 6px; height: 100%; - border-radius: 7px; + border-radius: 7px; } } diff --git a/app/templates/views/manage-users.html b/app/templates/views/manage-users.html index f8585870e..432f2a9b8 100644 --- a/app/templates/views/manage-users.html +++ b/app/templates/views/manage-users.html @@ -32,64 +32,58 @@
{% for user in users %}
-
-
-

- {%- if user.name -%} - {{ user.name }}  - {%- endif -%} - - {%- if user.status == 'pending' -%} - {{ user.email_address }} (invited) - {%- elif user.status == 'cancelled' -%} - {{ user.email_address }} (cancelled invite) - {%- elif user.id == current_user.id -%} - (you) - {% else %} - {{ user.email_address }} - {% endif %} - -

-

Permissions

-
    - {% for permission, label in permissions %} - {{ tick_cross( - user.has_permission_for_service(current_service.id, permission), - label - ) }} - {% endfor %} -
- {# only show if the service has folders #} - {% if current_service.all_template_folders %} -

- {% set folder_count = user.template_folders_for_service(current_service) | length %} +

+ {%- if user.name -%} + {{ user.name }} + {%- endif -%} + {%- if user.status == 'pending' -%} + {{ user.email_address }}(invited) + {%- elif user.status == 'cancelled' -%} + {{ user.email_address }}(cancelled invite) + {%- elif user.id == current_user.id -%} + (you) + {% else %} + {{ user.email_address }} + {% endif %} +

+

Permissions

+
    + {% for permission, label in permissions %} + {{ tick_cross( + user.has_permission_for_service(current_service.id, permission), + label + ) }} + {% endfor %} +
+ {# only show if the service has folders #} + {% if current_service.all_template_folders %} +

+ {% set folder_count = user.template_folders_for_service(current_service) | length %} - {% if folder_count == 0 %} - Cannot see any folders - {% elif folder_count != current_service.all_template_folders | length %} - Can see {{ folder_count }} folder{% if folder_count > 1 %}s{% endif %} - {% else %} - Can see all folders - {% endif%} -

+ {% if folder_count == 0 %} + Cannot see any folders + {% elif folder_count != current_service.all_template_folders | length %} + Can see {{ folder_count }} folder{% if folder_count > 1 %}s{% endif %} + {% else %} + Can see all folders + {% endif%} +

+ {% endif %} + {% if current_service.has_permission('email_auth') %} +

+ Signs in with + {{ user.auth_type | format_auth_type(with_indefinite_article=True) }} +

+ {% endif %} +
+ {% if current_user.has_permissions('manage_service') %} + {% if user.status == 'pending' %} + Cancel invitation for {{ user.email_address }} + {% elif user.is_editable_by(current_user) %} + Change details for {{ user.name }} {{ user.email_address }} {% endif %} - {% if current_service.has_permission('email_auth') %} -

- Signs in with - {{ user.auth_type | format_auth_type(with_indefinite_article=True) }} -

- {% endif %} -
-
- {% if current_user.has_permissions('manage_service') %} - {% if user.status == 'pending' %} - Cancel invitation for {{ user.email_address }} - {% elif user.is_editable_by(current_user) %} - Change details for {{ user.name }} {{ user.email_address }} - {% endif %} - {% endif %} -
-
+ {% endif %} +
{% endfor %}
diff --git a/tests/app/main/views/test_manage_users.py b/tests/app/main/views/test_manage_users.py index c5d97bd03..01e873700 100644 --- a/tests/app/main/views/test_manage_users.py +++ b/tests/app/main/views/test_manage_users.py @@ -27,7 +27,7 @@ from tests.conftest import ( ( create_active_user_with_permissions(), ( - "Test User (you) " + "Test User(you) " "Permissions " "Can See dashboard " "Can Send messages " @@ -39,18 +39,18 @@ from tests.conftest import ( ), ( create_active_user_empty_permissions(), - ("Test User With Empty Permissions (you) " "Permissions"), + ("Test User With Empty Permissions(you) " "Permissions"), False, ), ( create_active_user_view_permissions(), - ("Test User With Permissions (you) " "Permissions " "Can See dashboard"), + ("Test User With Permissions(you) " "Permissions " "Can See dashboard"), False, ), ( create_active_user_manage_template_permissions(), ( - "Test User With Permissions (you) " + "Test User With Permissions(you) " "Permissions " "Can See dashboard " "Can Add and edit templates" @@ -232,7 +232,7 @@ def test_should_show_caseworker_on_overview_page( assert normalize_spaces(page.select_one("h1").text) == "Team members" assert normalize_spaces(page.select(".user-list-item")[0].text) == ( - "Test User With Permissions (you) " "Permissions " "Can See dashboard" + "Test User With Permissions(you) " "Permissions " "Can See dashboard" ) # [1:5] are invited users assert normalize_spaces(page.select(".user-list-item")[6].text) == ( @@ -1210,7 +1210,7 @@ def test_cancel_invited_user_doesnt_work_if_user_not_invited_to_this_service( ( "pending", ( - "invited_user@test.gsa.gov (invited) " + "invited_user@test.gsa.gov(invited) " "Permissions " "Can See dashboard " "Can Send messages " @@ -1222,7 +1222,7 @@ def test_cancel_invited_user_doesnt_work_if_user_not_invited_to_this_service( ( "cancelled", ( - "invited_user@test.gsa.gov (cancelled invite) " + "invited_user@test.gsa.gov(cancelled invite) " "Permissions" # all permissions are greyed out ), @@ -1383,10 +1383,7 @@ def test_manage_user_page_shows_how_many_folders_user_can_view( user_div = page.select_one( "h2[title='notify@digital.cabinet-office.gov.uk']" ).parent - assert ( - user_div.select_one(".tick-cross-list-hint:last-child").text.strip() - == expected_message - ) + assert user_div.select_one(".tick-cross-list-hint").text.strip() == expected_message def test_manage_user_page_doesnt_show_folder_hint_if_service_has_no_folders( diff --git a/tests/app/main/views/test_templates.py b/tests/app/main/views/test_templates.py index b74b5b6d7..244b7cb40 100644 --- a/tests/app/main/views/test_templates.py +++ b/tests/app/main/views/test_templates.py @@ -631,8 +631,8 @@ def test_should_show_sms_template_with_downgraded_unicode_characters( mock_get_template_folders, fake_uuid, ): - msg = "here:\tare some “fancy quotes” and zero\u200Bwidth\u200Bspaces" - rendered_msg = "here: are some “fancy quotes” and zerowidthspaces" + msg = "hey" + rendered_msg = "hey" mocker.patch( "app.service_api_client.get_service_template", From 0eb00bb613ec827fa406efe588c83773a9376ca7 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Tue, 19 Dec 2023 11:32:19 -0500 Subject: [PATCH 02/53] Adjusted responsive styles --- .../sass/uswds/_uswds-theme-custom-styles.scss | 16 +++++++++++++++- app/templates/views/manage-users.html | 10 +++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss index a1e15b995..f7c226761 100644 --- a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss +++ b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss @@ -114,6 +114,17 @@ td.table-empty-message { text-decoration: none !important; } +.button-flex-header { + flex-direction: column; + align-items: flex-start; + @include at-media(desktop) { + flex-direction: row; + display: flex; + align-items: center; + justify-content: space-between; + } +} + .user-list-edit-link:active:before, .user-list-edit-link:focus:before { box-shadow: none; @@ -125,7 +136,10 @@ td.table-empty-message { flex-wrap: wrap; gap: units(2); .user-list-item { - flex: 1 1 calc(50% - units(2)); + @include at-media(desktop) { + flex: 1 1 calc(50% - units(2)); + } + flex: 1 1 calc(100% - units(2)); border: 1px solid color('gray-cool-10'); padding: units(2); .tick-cross-list-permissions { diff --git a/app/templates/views/manage-users.html b/app/templates/views/manage-users.html index 432f2a9b8..1e5641f2a 100644 --- a/app/templates/views/manage-users.html +++ b/app/templates/views/manage-users.html @@ -9,10 +9,10 @@ {% block maincolumn_content %} -
-

- Team members -

+
+

+ Team members +

{% if current_user.has_permissions('manage_service') %} {{ usaButton({ "element": "a", @@ -41,7 +41,7 @@ {%- elif user.status == 'cancelled' -%} {{ user.email_address }}(cancelled invite) {%- elif user.id == current_user.id -%} - (you) + (you) {% else %} {{ user.email_address }} {% endif %} From 2cf232f7570668d728adcd60853b775368fb81b6 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Tue, 19 Dec 2023 11:35:44 -0500 Subject: [PATCH 03/53] Small style update --- app/assets/sass/uswds/_uswds-theme-custom-styles.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss index f7c226761..908c69d44 100644 --- a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss +++ b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss @@ -143,6 +143,7 @@ td.table-empty-message { border: 1px solid color('gray-cool-10'); padding: units(2); .tick-cross-list-permissions { + margin: units(1) 0; padding-left: units(2); } .hint { From 068ffb7f3ae80a9fe20edec3ee642782fdabff89 Mon Sep 17 00:00:00 2001 From: Tim Lowden Date: Wed, 20 Dec 2023 09:09:04 -0500 Subject: [PATCH 04/53] Update sprint-goals.md --- docs/sprint-goals.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/sprint-goals.md b/docs/sprint-goals.md index 598305e0e..8a4f44a2c 100644 --- a/docs/sprint-goals.md +++ b/docs/sprint-goals.md @@ -1,8 +1,18 @@ # Notify Sprint Goals Log -## Sprint: Y (12/6/23) -(Sprint X was canceled due to Thanksgiving) +## Sprint: Z (12/21/23) + +| | Goals | Impact | Milestone(s) | +|-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|--------------| +| Engineering | Spend time [identifying](https://github.com/GSA/notifications-api/issues/656), [fixing](https://github.com/GSA/notifications-api/issues/645), and [displaying](https://github.com/GSA/notifications-admin/issues/964) various applicable message part limits, devise ways to [create better access to reports](https://github.com/GSA/notifications-admin/issues/855), implement Login.gov on staging environment, advance epic to [remove phone numbers from db](https://github.com/GSA/notifications-api/issues/667) | Better track annual and smart-retention limits, install required auth, make reports easier to find, expand message send volume for partners | Building Notify.gov | +| UX | [Re-think Notify IA](https://github.com/GSA/notifications-admin/issues/910), start implementing dashboard changes, improve [team member section](https://github.com/GSA/notifications-admin/issues/1031)| Improve UX | Building Notify.gov| +| Security | Complete necessary control families | Aim to have package completed with enough time to allow for long assessment| Secure ATO | +| Content | Make content [more clear about limits](https://github.com/GSA/notifications-admin/issues/963), test making [editing content easier](https://github.com/GSA/notifications-admin/issues/976) with existing templates | Improve clarity of message parts for users, streamline content editing for the team| Building Notify.gov | +| Ops | | + +## Sprint: Xingu Scale-Backed Antbird (12/6/23) +(Sprint X was canceled due to Thanksgiving, so this is X & Y) | | Goals | Impact | Milestone(s) | |-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|--------------| From 007b33e313f4146dcee528923abe9e21bd6236c2 Mon Sep 17 00:00:00 2001 From: Tim Lowden Date: Thu, 21 Dec 2023 13:07:41 -0500 Subject: [PATCH 05/53] Update sprint-goals.md --- docs/sprint-goals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sprint-goals.md b/docs/sprint-goals.md index 8a4f44a2c..df3b7712f 100644 --- a/docs/sprint-goals.md +++ b/docs/sprint-goals.md @@ -9,7 +9,7 @@ | UX | [Re-think Notify IA](https://github.com/GSA/notifications-admin/issues/910), start implementing dashboard changes, improve [team member section](https://github.com/GSA/notifications-admin/issues/1031)| Improve UX | Building Notify.gov| | Security | Complete necessary control families | Aim to have package completed with enough time to allow for long assessment| Secure ATO | | Content | Make content [more clear about limits](https://github.com/GSA/notifications-admin/issues/963), test making [editing content easier](https://github.com/GSA/notifications-admin/issues/976) with existing templates | Improve clarity of message parts for users, streamline content editing for the team| Building Notify.gov | -| Ops | | +| Ops | Assist in Tech to Gov process | ## Sprint: Xingu Scale-Backed Antbird (12/6/23) (Sprint X was canceled due to Thanksgiving, so this is X & Y) From 904a1d21ca0945861084d5b84e32af0218324ec9 Mon Sep 17 00:00:00 2001 From: Tim Lowden Date: Thu, 21 Dec 2023 13:08:11 -0500 Subject: [PATCH 06/53] Update sprint-goals.md --- docs/sprint-goals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sprint-goals.md b/docs/sprint-goals.md index df3b7712f..f2a06f875 100644 --- a/docs/sprint-goals.md +++ b/docs/sprint-goals.md @@ -9,7 +9,7 @@ | UX | [Re-think Notify IA](https://github.com/GSA/notifications-admin/issues/910), start implementing dashboard changes, improve [team member section](https://github.com/GSA/notifications-admin/issues/1031)| Improve UX | Building Notify.gov| | Security | Complete necessary control families | Aim to have package completed with enough time to allow for long assessment| Secure ATO | | Content | Make content [more clear about limits](https://github.com/GSA/notifications-admin/issues/963), test making [editing content easier](https://github.com/GSA/notifications-admin/issues/976) with existing templates | Improve clarity of message parts for users, streamline content editing for the team| Building Notify.gov | -| Ops | Assist in Tech to Gov process | +| Ops | Assist in Tech to Gov process | | ## Sprint: Xingu Scale-Backed Antbird (12/6/23) (Sprint X was canceled due to Thanksgiving, so this is X & Y) From dc3d5c452456b44afcd542f37ac737110150c108 Mon Sep 17 00:00:00 2001 From: Tim Lowden Date: Thu, 21 Dec 2023 14:53:22 -0500 Subject: [PATCH 07/53] Update sprint-goals.md --- docs/sprint-goals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sprint-goals.md b/docs/sprint-goals.md index f2a06f875..cfae21996 100644 --- a/docs/sprint-goals.md +++ b/docs/sprint-goals.md @@ -8,7 +8,7 @@ | Engineering | Spend time [identifying](https://github.com/GSA/notifications-api/issues/656), [fixing](https://github.com/GSA/notifications-api/issues/645), and [displaying](https://github.com/GSA/notifications-admin/issues/964) various applicable message part limits, devise ways to [create better access to reports](https://github.com/GSA/notifications-admin/issues/855), implement Login.gov on staging environment, advance epic to [remove phone numbers from db](https://github.com/GSA/notifications-api/issues/667) | Better track annual and smart-retention limits, install required auth, make reports easier to find, expand message send volume for partners | Building Notify.gov | | UX | [Re-think Notify IA](https://github.com/GSA/notifications-admin/issues/910), start implementing dashboard changes, improve [team member section](https://github.com/GSA/notifications-admin/issues/1031)| Improve UX | Building Notify.gov| | Security | Complete necessary control families | Aim to have package completed with enough time to allow for long assessment| Secure ATO | -| Content | Make content [more clear about limits](https://github.com/GSA/notifications-admin/issues/963), test making [editing content easier](https://github.com/GSA/notifications-admin/issues/976) with existing templates | Improve clarity of message parts for users, streamline content editing for the team| Building Notify.gov | +| Content | Make content [more clear about limits](https://github.com/GSA/notifications-admin/issues/963), make content clearer by [adding `parts` where necessary](https://github.com/GSA/notifications-admin/issues/963), test making [editing content easier](https://github.com/GSA/notifications-admin/issues/976) with existing templates | Improve clarity of message parts for users, streamline content editing for the team| Building Notify.gov | | Ops | Assist in Tech to Gov process | | ## Sprint: Xingu Scale-Backed Antbird (12/6/23) From 86af8fcaa42e7f806db2db23d0a1f6d2173855a5 Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Thu, 21 Dec 2023 20:43:52 -0700 Subject: [PATCH 08/53] Updated get-started to render from markdown --- app/content/get-started.md | 50 +++++++++++++++++++++++++++ app/main/views/index.py | 23 +++++++++++-- app/templates/views/get-started.html | 51 +--------------------------- 3 files changed, 72 insertions(+), 52 deletions(-) create mode 100644 app/content/get-started.md diff --git a/app/content/get-started.md b/app/content/get-started.md new file mode 100644 index 000000000..ab5cffdac --- /dev/null +++ b/app/content/get-started.md @@ -0,0 +1,50 @@ +

Get started

+ +
    +
  1. +

    Check if Notify.gov is right for you

    +

    Read about our features, pricing and roadmap.

    +
  2. + +
  3. +

    Create an account

    + {% if not current_user.is_authenticated %} +

    Create an account for free and add your first Notify service. When you add a new service it will start in trial mode.

    + {% else %} +

    Create an account for free and add your first Notify service. When you add a new service, it will start in trial mode.

    + {% endif %} +
  4. + +
  5. +

    Write some messages

    +

    Add message templates with examples of the content you plan to send. You can use our guidance to help you.

    +
  6. + +
  7. +

    Set up your service

    + {% if not current_user.is_authenticated or not current_service %} +

    Review your settings to add message branding and sender information.

    +

    Add team members and check their permissions.

    + {% else %} +

    Review your settings to add message branding and sender information.

    +

    Add team members and check their permissions.

    + {% endif %} +
  8. + + + +
  9. +

    Start sending messages

    + {% if not current_user.is_authenticated or not current_service %} +

    When you’re ready to send messages to people outside your team, go to the Settings page and select Request to go live. We’ll approve your request within one working day.

    + {% else %} +

    You should request to go live when you’re ready to send messages to people outside your team. We’ll approve your request within one working day.

    + {% endif %} + +
  10. + +
diff --git a/app/main/views/index.py b/app/main/views/index.py index 30818db99..b26086e84 100644 --- a/app/main/views/index.py +++ b/app/main/views/index.py @@ -4,12 +4,17 @@ from flask import ( make_response, redirect, render_template, + render_template_string, request, - url_for, + url_for ) from flask_login import current_user +from flask.helpers import get_root_path from notifications_utils.template import HTMLEmailTemplate +import markdown +import os + from app import email_branding_client, status_api_client from app.main import main from app.main.forms import FieldWithNoneOption @@ -17,6 +22,19 @@ from app.main.views.pricing import CURRENT_SMS_RATE from app.main.views.sub_navigation_dictionaries import features_nav, using_notify_nav from app.utils.user import user_is_logged_in +#Should find a better home +def get_md(mdf): + APP_ROOT = get_root_path('notifications-admin') + file = 'app/content/' + mdf + '.md' + md_file = os.path.join(APP_ROOT, file) + with open(md_file) as f: + content_text = f.read() + + md_render = markdown.markdown(content_text) + jn_render = render_template_string(md_render) + + return jn_render + @main.route("/") def index(): @@ -256,7 +274,7 @@ def get_started_old(): def get_started(): return render_template( "views/get-started.html", - navigation_links=using_notify_nav(), + navigation_links=using_notify_nav(), content=get_md('get-started') ) @@ -324,6 +342,7 @@ def send_files_by_email(): ) + # --- Redirects --- # diff --git a/app/templates/views/get-started.html b/app/templates/views/get-started.html index 7b6ad500c..e1da9961e 100644 --- a/app/templates/views/get-started.html +++ b/app/templates/views/get-started.html @@ -9,55 +9,6 @@ {% block content_column_content %} -

Get started

- -
    -
  1. -

    Check if Notify.gov is right for you

    -

    Read about our features, pricing and roadmap.

    -
  2. - -
  3. -

    Create an account

    - {% if not current_user.is_authenticated %} -

    Create an account for free and add your first Notify service. When you add a new service it will start in trial mode.

    - {% else %} -

    Create an account for free and add your first Notify service. When you add a new service, it will start in trial mode.

    - {% endif %} -
  4. - -
  5. -

    Write some messages

    -

    Add message templates with examples of the content you plan to send. You can use our guidance to help you.

    -
  6. - -
  7. -

    Set up your service

    - {% if not current_user.is_authenticated or not current_service %} -

    Review your settings to add message branding and sender information.

    -

    Add team members and check their permissions.

    - {% else %} -

    Review your settings to add message branding and sender information.

    -

    Add team members and check their permissions.

    - {% endif %} -
  8. - - - -
  9. -

    Start sending messages

    - {% if not current_user.is_authenticated or not current_service %} -

    When you’re ready to send messages to people outside your team, go to the Settings page and select Request to go live. We’ll approve your request within one working day.

    - {% else %} -

    You should request to go live when you’re ready to send messages to people outside your team. We’ll approve your request within one working day.

    - {% endif %} - -
  10. - -
+{{ content | safe }} {% endblock %} From 09892463349ca6901f6c327cfbd4205de98d9745 Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Fri, 22 Dec 2023 10:03:43 -0700 Subject: [PATCH 09/53] Moved convert_markdown_template to formatters --- app/formatters.py | 17 ++++++++++++++++- app/main/views/index.py | 23 +++-------------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/app/formatters.py b/app/formatters.py index 2442e70d0..4da95ae5c 100644 --- a/app/formatters.py +++ b/app/formatters.py @@ -6,11 +6,14 @@ from functools import partial from math import floor, log10 from numbers import Number +import markdown +import os import ago import dateutil import humanize import pytz -from flask import Markup, url_for +from flask import Markup, url_for, render_template_string +from flask.helpers import get_root_path from notifications_utils.field import Field from notifications_utils.formatters import make_quotes_smart from notifications_utils.formatters import nl2br as utils_nl2br @@ -21,6 +24,18 @@ from app.utils.csv import get_user_preferred_timezone from app.utils.time import parse_naive_dt +def convert_markdown_template(mdf): + APP_ROOT = get_root_path('notifications-admin') + file = 'app/content/' + mdf + '.md' + md_file = os.path.join(APP_ROOT, file) + with open(md_file) as f: + content_text = f.read() + + md_render = markdown.markdown(content_text) + jn_render = render_template_string(md_render) + + return jn_render + def convert_to_boolean(value): if isinstance(value, str): if value.lower() in ["t", "true", "on", "yes", "1"]: diff --git a/app/main/views/index.py b/app/main/views/index.py index b26086e84..d768c6f74 100644 --- a/app/main/views/index.py +++ b/app/main/views/index.py @@ -4,37 +4,19 @@ from flask import ( make_response, redirect, render_template, - render_template_string, request, url_for ) from flask_login import current_user -from flask.helpers import get_root_path from notifications_utils.template import HTMLEmailTemplate -import markdown -import os - from app import email_branding_client, status_api_client from app.main import main from app.main.forms import FieldWithNoneOption from app.main.views.pricing import CURRENT_SMS_RATE from app.main.views.sub_navigation_dictionaries import features_nav, using_notify_nav from app.utils.user import user_is_logged_in - -#Should find a better home -def get_md(mdf): - APP_ROOT = get_root_path('notifications-admin') - file = 'app/content/' + mdf + '.md' - md_file = os.path.join(APP_ROOT, file) - with open(md_file) as f: - content_text = f.read() - - md_render = markdown.markdown(content_text) - jn_render = render_template_string(md_render) - - return jn_render - +from app.formatters import convert_markdown_template @main.route("/") def index(): @@ -274,7 +256,8 @@ def get_started_old(): def get_started(): return render_template( "views/get-started.html", - navigation_links=using_notify_nav(), content=get_md('get-started') + navigation_links=using_notify_nav(), + content=convert_markdown_template('get-started') ) From ed6471be61fd1fe69e436636a2aa00eb97a8314f Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Fri, 22 Dec 2023 10:13:18 -0700 Subject: [PATCH 10/53] corrected build errors --- app/formatters.py | 3 ++- app/main/views/index.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/formatters.py b/app/formatters.py index 4da95ae5c..da9a4659b 100644 --- a/app/formatters.py +++ b/app/formatters.py @@ -29,13 +29,14 @@ def convert_markdown_template(mdf): file = 'app/content/' + mdf + '.md' md_file = os.path.join(APP_ROOT, file) with open(md_file) as f: - content_text = f.read() + content_text = f.read() md_render = markdown.markdown(content_text) jn_render = render_template_string(md_render) return jn_render + def convert_to_boolean(value): if isinstance(value, str): if value.lower() in ["t", "true", "on", "yes", "1"]: diff --git a/app/main/views/index.py b/app/main/views/index.py index d768c6f74..97844fe2b 100644 --- a/app/main/views/index.py +++ b/app/main/views/index.py @@ -18,6 +18,7 @@ from app.main.views.sub_navigation_dictionaries import features_nav, using_notif from app.utils.user import user_is_logged_in from app.formatters import convert_markdown_template + @main.route("/") def index(): if current_user and current_user.is_authenticated: @@ -325,7 +326,6 @@ def send_files_by_email(): ) - # --- Redirects --- # From 5d91fb6838528aac331b30255d2e2798ac7bbd85 Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Fri, 22 Dec 2023 10:21:42 -0700 Subject: [PATCH 11/53] fixed isort issue --- app/formatters.py | 6 +++--- app/main/views/index.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/formatters.py b/app/formatters.py index da9a4659b..241172650 100644 --- a/app/formatters.py +++ b/app/formatters.py @@ -1,3 +1,4 @@ +import os import re import unicodedata import urllib @@ -6,13 +7,12 @@ from functools import partial from math import floor, log10 from numbers import Number -import markdown -import os import ago import dateutil import humanize +import markdown import pytz -from flask import Markup, url_for, render_template_string +from flask import Markup, render_template_string, url_for from flask.helpers import get_root_path from notifications_utils.field import Field from notifications_utils.formatters import make_quotes_smart diff --git a/app/main/views/index.py b/app/main/views/index.py index 97844fe2b..69934c893 100644 --- a/app/main/views/index.py +++ b/app/main/views/index.py @@ -5,18 +5,18 @@ from flask import ( redirect, render_template, request, - url_for + url_for, ) from flask_login import current_user from notifications_utils.template import HTMLEmailTemplate from app import email_branding_client, status_api_client +from app.formatters import convert_markdown_template from app.main import main from app.main.forms import FieldWithNoneOption from app.main.views.pricing import CURRENT_SMS_RATE from app.main.views.sub_navigation_dictionaries import features_nav, using_notify_nav from app.utils.user import user_is_logged_in -from app.formatters import convert_markdown_template @main.route("/") From 9d7d7e66b5b635a66441cf16e325630a258ac5ab Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Fri, 22 Dec 2023 10:48:39 -0700 Subject: [PATCH 12/53] adding build dependency --- poetry.lock | 20 +++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 2d927be40..4871b2259 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1382,6 +1382,24 @@ six = "*" [package.extras] restructuredtext = ["rst2ansi"] +[[package]] +name = "markdown" +version = "3.5.1" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Markdown-3.5.1-py3-none-any.whl", hash = "sha256:5874b47d4ee3f0b14d764324d2c94c03ea66bee56f2d929da9f2508d65e722dc"}, + {file = "Markdown-3.5.1.tar.gz", hash = "sha256:b65d7beb248dc22f2e8a31fb706d93798093c308dc1aba295aedeb9d41a813bd"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + [[package]] name = "markdown-it-py" version = "3.0.0" @@ -3089,4 +3107,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "8a6fa375211952359f5993261b082558dae34ce3d80ee113ae51d10ecd426937" +content-hash = "06cc93098e0294887fdce7d80fd03cbb0117c9546244a340de589fa682f11799" diff --git a/pyproject.toml b/pyproject.toml index 1d6f1dca9..c0146d1f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,7 @@ pytz = "==2023.3.post1" rtreelib = "==0.2.0" werkzeug = "^3.0.1" wtforms = "~=3.1" +markdown = "^3.5.1" [tool.poetry.group.dev.dependencies] From 1d140a0d0b14e35346de4a3c18bb42c7239fc055 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Dec 2023 23:35:33 +0000 Subject: [PATCH 13/53] Bump black from 23.12.0 to 23.12.1 Bumps [black](https://github.com/psf/black) from 23.12.0 to 23.12.1. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/23.12.0...23.12.1) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 48 ++++++++++++++++++++++++------------------------ pyproject.toml | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/poetry.lock b/poetry.lock index dd52f645e..5f986c742 100644 --- a/poetry.lock +++ b/poetry.lock @@ -82,33 +82,33 @@ lxml = ["lxml"] [[package]] name = "black" -version = "23.12.0" +version = "23.12.1" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:67f19562d367468ab59bd6c36a72b2c84bc2f16b59788690e02bbcb140a77175"}, - {file = "black-23.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bbd75d9f28a7283b7426160ca21c5bd640ca7cd8ef6630b4754b6df9e2da8462"}, - {file = "black-23.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:593596f699ca2dcbbbdfa59fcda7d8ad6604370c10228223cd6cf6ce1ce7ed7e"}, - {file = "black-23.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:12d5f10cce8dc27202e9a252acd1c9a426c83f95496c959406c96b785a92bb7d"}, - {file = "black-23.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e73c5e3d37e5a3513d16b33305713237a234396ae56769b839d7c40759b8a41c"}, - {file = "black-23.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ba09cae1657c4f8a8c9ff6cfd4a6baaf915bb4ef7d03acffe6a2f6585fa1bd01"}, - {file = "black-23.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace64c1a349c162d6da3cef91e3b0e78c4fc596ffde9413efa0525456148873d"}, - {file = "black-23.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:72db37a2266b16d256b3ea88b9affcdd5c41a74db551ec3dd4609a59c17d25bf"}, - {file = "black-23.12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fdf6f23c83078a6c8da2442f4d4eeb19c28ac2a6416da7671b72f0295c4a697b"}, - {file = "black-23.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39dda060b9b395a6b7bf9c5db28ac87b3c3f48d4fdff470fa8a94ab8271da47e"}, - {file = "black-23.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7231670266ca5191a76cb838185d9be59cfa4f5dd401b7c1c70b993c58f6b1b5"}, - {file = "black-23.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:193946e634e80bfb3aec41830f5d7431f8dd5b20d11d89be14b84a97c6b8bc75"}, - {file = "black-23.12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bcf91b01ddd91a2fed9a8006d7baa94ccefe7e518556470cf40213bd3d44bbbc"}, - {file = "black-23.12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:996650a89fe5892714ea4ea87bc45e41a59a1e01675c42c433a35b490e5aa3f0"}, - {file = "black-23.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdbff34c487239a63d86db0c9385b27cdd68b1bfa4e706aa74bb94a435403672"}, - {file = "black-23.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:97af22278043a6a1272daca10a6f4d36c04dfa77e61cbaaf4482e08f3640e9f0"}, - {file = "black-23.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ead25c273adfad1095a8ad32afdb8304933efba56e3c1d31b0fee4143a1e424a"}, - {file = "black-23.12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c71048345bdbced456cddf1622832276d98a710196b842407840ae8055ade6ee"}, - {file = "black-23.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a832b6e00eef2c13b3239d514ea3b7d5cc3eaa03d0474eedcbbda59441ba5d"}, - {file = "black-23.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:6a82a711d13e61840fb11a6dfecc7287f2424f1ca34765e70c909a35ffa7fb95"}, - {file = "black-23.12.0-py3-none-any.whl", hash = "sha256:a7c07db8200b5315dc07e331dda4d889a56f6bf4db6a9c2a526fa3166a81614f"}, - {file = "black-23.12.0.tar.gz", hash = "sha256:330a327b422aca0634ecd115985c1c7fd7bdb5b5a2ef8aa9888a82e2ebe9437a"}, + {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, + {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, + {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, + {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, + {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, + {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, + {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, + {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, + {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, + {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, + {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, + {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, + {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, + {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, + {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, + {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, + {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, + {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, + {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, + {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, + {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, + {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, ] [package.dependencies] @@ -3089,4 +3089,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "f06451d8cf0d8f4d59b67f06d2ede8153a19055403a81b90afc700dcf60d139b" +content-hash = "f92abb1eca6bdad11491d05a6340400dbd9d31be955d737e0e719dc0b2826503" diff --git a/pyproject.toml b/pyproject.toml index 94da0306f..73c5f964a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ wtforms = "~=3.1" [tool.poetry.group.dev.dependencies] bandit = "*" beautifulsoup4 = "^4.12.2" -black = "^23.12.0" +black = "^23.12.1" coverage = "*" freezegun = "^1.4.0" flake8 = "^6.1.0" From a5ec03302e7799db4e330559b6cdaba7f5fba8d4 Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Tue, 26 Dec 2023 22:04:06 -0700 Subject: [PATCH 14/53] Built py.test cases for convert_markdown_template --- app/formatters.py | 15 +++++++++------ tests/app/main/test_formatters.py | 22 +++++++++++++++++++++- tests/conftest.py | 10 ++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/app/formatters.py b/app/formatters.py index 241172650..02b0061d4 100644 --- a/app/formatters.py +++ b/app/formatters.py @@ -24,12 +24,15 @@ from app.utils.csv import get_user_preferred_timezone from app.utils.time import parse_naive_dt -def convert_markdown_template(mdf): - APP_ROOT = get_root_path('notifications-admin') - file = 'app/content/' + mdf + '.md' - md_file = os.path.join(APP_ROOT, file) - with open(md_file) as f: - content_text = f.read() +def convert_markdown_template(mdf, test=False): + if not test: + APP_ROOT = get_root_path('notifications-admin') + file = 'app/content/' + mdf + '.md' + md_file = os.path.join(APP_ROOT, file) + with open(md_file) as f: + content_text = f.read() + else: + content_text = mdf md_render = markdown.markdown(content_text) jn_render = render_template_string(md_render) diff --git a/tests/app/main/test_formatters.py b/tests/app/main/test_formatters.py index 46e76da0d..b48f64316 100644 --- a/tests/app/main/test_formatters.py +++ b/tests/app/main/test_formatters.py @@ -1,8 +1,9 @@ from datetime import datetime from functools import partial + import pytest -from flask import url_for +from flask import url_for, Flask from freezegun import freeze_time from app.formatters import ( @@ -12,6 +13,13 @@ from app.formatters import ( format_notification_status_as_url, format_number_in_pounds_as_currency, round_to_significant_figures, + convert_markdown_template +) + +from tests.conftest import ( + fake_markdown_file, + fake_jinja_template, + notify_admin ) @@ -166,3 +174,15 @@ def test_email_safe_return_dot_separated_email_domain(service_name, safe_email): def test_format_delta(): naive_now_utc = datetime.utcnow().isoformat() assert format_delta(naive_now_utc) == "just now" + +@pytest.mark.usefixtures("fake_jinja_template") +def test_jinja_format(fake_jinja_template): + app = Flask("app") + with app.app_context(): + assert convert_markdown_template(fake_jinja_template, test=True) == "

True

" + +@pytest.mark.usefixtures("fake_markdown_file") +def test_markdown_format(fake_markdown_file): + app = Flask("app") + with app.app_context(): + assert convert_markdown_template(fake_markdown_file, test=True) == "

Test

" diff --git a/tests/conftest.py b/tests/conftest.py index 9bab089f8..9f9424b96 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3594,3 +3594,13 @@ def end_to_end_authenticated_context(browser): context = browser.new_context(storage_state=auth_state_path) return context + +@pytest.fixture() +def fake_markdown_file(): + input = "#Test" + return input + +@pytest.fixture() +def fake_jinja_template(): + input = "{% if True %}True{% endif %}" + return input From c06d752f65e61ce7aceb8916634b44369536b3e0 Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Tue, 26 Dec 2023 22:10:50 -0700 Subject: [PATCH 15/53] Style correction on conftest and test_formatters --- tests/app/main/test_formatters.py | 6 ------ tests/conftest.py | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/app/main/test_formatters.py b/tests/app/main/test_formatters.py index b48f64316..e390b9027 100644 --- a/tests/app/main/test_formatters.py +++ b/tests/app/main/test_formatters.py @@ -16,12 +16,6 @@ from app.formatters import ( convert_markdown_template ) -from tests.conftest import ( - fake_markdown_file, - fake_jinja_template, - notify_admin -) - @pytest.mark.parametrize( ("status", "notification_type", "expected"), diff --git a/tests/conftest.py b/tests/conftest.py index 9f9424b96..936bb8a79 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3595,11 +3595,13 @@ def end_to_end_authenticated_context(browser): return context + @pytest.fixture() def fake_markdown_file(): input = "#Test" return input + @pytest.fixture() def fake_jinja_template(): input = "{% if True %}True{% endif %}" From f72e4e618a65f5b5f1ff70eff5d9ea17e6e60917 Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Tue, 26 Dec 2023 22:14:22 -0700 Subject: [PATCH 16/53] Style updates --- tests/app/main/test_formatters.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/app/main/test_formatters.py b/tests/app/main/test_formatters.py index e390b9027..156edb0cd 100644 --- a/tests/app/main/test_formatters.py +++ b/tests/app/main/test_formatters.py @@ -169,12 +169,14 @@ def test_format_delta(): naive_now_utc = datetime.utcnow().isoformat() assert format_delta(naive_now_utc) == "just now" + @pytest.mark.usefixtures("fake_jinja_template") def test_jinja_format(fake_jinja_template): app = Flask("app") with app.app_context(): assert convert_markdown_template(fake_jinja_template, test=True) == "

True

" + @pytest.mark.usefixtures("fake_markdown_file") def test_markdown_format(fake_markdown_file): app = Flask("app") From 051d7767d9ccccc6823c1bd7f2519d88ee8140cc Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Tue, 26 Dec 2023 22:19:59 -0700 Subject: [PATCH 17/53] isort format issue --- tests/app/main/test_formatters.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/app/main/test_formatters.py b/tests/app/main/test_formatters.py index 156edb0cd..eeded8c13 100644 --- a/tests/app/main/test_formatters.py +++ b/tests/app/main/test_formatters.py @@ -1,19 +1,18 @@ from datetime import datetime from functools import partial - import pytest -from flask import url_for, Flask +from flask import Flask, url_for from freezegun import freeze_time from app.formatters import ( + convert_markdown_template, email_safe, format_datetime_relative, format_delta, format_notification_status_as_url, format_number_in_pounds_as_currency, round_to_significant_figures, - convert_markdown_template ) From 7af656e9f9abd739592662a957f9e35461aec6ca Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Wed, 27 Dec 2023 12:59:45 -0700 Subject: [PATCH 18/53] registered convert_markdown formatter in __init__. --- app/__init__.py | 2 ++ app/formatters.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/app/__init__.py b/app/__init__.py index 4e53bbb76..08e449728 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -39,6 +39,7 @@ from app.asset_fingerprinter import asset_fingerprinter from app.config import configs from app.extensions import redis_client, zendesk_client from app.formatters import ( + convert_markdown_template, convert_to_boolean, format_auth_type, format_billions, @@ -582,6 +583,7 @@ def add_template_filters(application): format_mobile_network, format_yes_no, square_metres_to_square_miles, + convert_markdown_template ]: application.add_template_filter(fn) diff --git a/app/formatters.py b/app/formatters.py index 02b0061d4..4ea5d5104 100644 --- a/app/formatters.py +++ b/app/formatters.py @@ -25,6 +25,9 @@ from app.utils.time import parse_naive_dt def convert_markdown_template(mdf, test=False): + + content_text = "" + if not test: APP_ROOT = get_root_path('notifications-admin') file = 'app/content/' + mdf + '.md' From 7f7f55304139bbd7fe0146da71cec39e168e4a6e Mon Sep 17 00:00:00 2001 From: Andrew Shumway Date: Wed, 27 Dec 2023 14:14:22 -0700 Subject: [PATCH 19/53] Fix sms allowance switching to live --- app/main/views/service_settings.py | 8 ++++++++ tests/conftest.py | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index feb1e4388..1cac1410c 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -124,6 +124,14 @@ def service_switch_live(service_id): if form.validate_on_submit(): current_service.update_status(live=form.enabled.data) + if form.enabled.data is True: + billing_api_client.create_or_update_free_sms_fragment_limit( + service_id, 250000 + ) + else: + billing_api_client.create_or_update_free_sms_fragment_limit( + service_id, 40000 + ) return redirect(url_for(".service_settings", service_id=service_id)) return render_template( diff --git a/tests/conftest.py b/tests/conftest.py index 9bab089f8..b64b4243c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2323,6 +2323,10 @@ def client_request(logged_in_client, mocker, service_one): # noqa (C901 too com "app.service_api_client.get_global_notification_count", side_effect=_get ) + mocker.patch( + "app.billing_api_client.create_or_update_free_sms_fragment_limit", autospec=True + ) + class ClientRequest: @staticmethod @contextmanager From aa8529b5bbeffbf3229aed6fc8ae4ef04e55844e Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Mon, 1 Jan 2024 10:34:59 -0500 Subject: [PATCH 20/53] Quick commit before pulling latest --- .../uswds/_uswds-theme-custom-styles.scss | 36 +++++++++-------- app/templates/admin_template.html | 40 ++++++++++++------- .../components/components/header/template.njk | 18 ++++----- app/templates/main_nav.html | 4 +- app/templates/settings_nav.html | 20 ++++++++++ 5 files changed, 77 insertions(+), 41 deletions(-) create mode 100644 app/templates/settings_nav.html diff --git a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss index 516fa6c89..56771faed 100644 --- a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss +++ b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss @@ -22,16 +22,23 @@ i.e. @use "uswds-core" as *; -.usa-header--extended .usa-logo { - font-family: family("sans"); - margin: units(4) 0; - @include at-media-max('mobile-lg') { - margin: units(4) 0 units(4) units(2); +.usa-header--extended { + .usa-logo { + font-family: family("sans"); + margin: units(4) 0; + @include at-media-max('mobile-lg') { + margin: units(4) 0 units(4) units(2); + } + img { + @include at-media($theme-header-min-width) { + width: 80px; + height: 70px; + } + } } - img { - @include at-media($theme-header-min-width) { - width: 80px; - height: 70px; + .usa-nav__secondary { + .usa-nav__link { + padding: 0; } } } @@ -44,15 +51,12 @@ i.e. &> .usa-nav__primary-item > a { font-size: size("body", 4); } - &> .usa-nav__primary-item:last-child { - margin-left: auto; - @include u-margin-right(-4); - } + // &> .usa-nav__primary-item:last-child { + // margin-left: auto; + // @include u-margin-right(-4); + // } } -.usa-nav__primary - - h1 { font-weight: bold !important; } diff --git a/app/templates/admin_template.html b/app/templates/admin_template.html index 86482f829..0feae28e7 100644 --- a/app/templates/admin_template.html +++ b/app/templates/admin_template.html @@ -58,26 +58,32 @@ "text": "Features", "active": header_navigation.is_selected('features') }, - { - "href": url_for('main.user_profile'), - "text": current_user.name, - "active": header_navigation.is_selected('user-profile') - }, { "href": url_for('main.platform_admin_splash_page'), "text": "Platform admin", "active": header_navigation.is_selected('platform-admin') }, - { - "href": url_for('main.sign_out'), - "text": "Sign out" - }, { "href": url_for('main.support'), "text": "Contact us", "active": header_navigation.is_selected('support') } ] %} + {% set secondaryNavigation = [ + { + "href": url_for('main.user_profile'), + "text": current_user.name, + "active": header_navigation.is_selected('user-profile') + }, + { + "href": url_for('.service_settings', service_id=current_service.id), + "text": "Settings" + }, + { + "href": url_for('main.sign_out'), + "text": "Sign out" + } + ] %} {% else %} {% set navigation = [ { @@ -104,10 +110,17 @@ "href": url_for('main.user_profile'), "text": "User profile", "active": header_navigation.is_selected('user-profile') + } + ] %} + {% set secondaryNavigation = [ + { + "href": url_for('main.user_profile'), + "text": current_user.name, + "active": header_navigation.is_selected('user-profile') }, { - "href": url_for('main.sign_out'), - "text": "Sign out" + "href": url_for('main.sign_out'), + "text": "Sign out" } ] %} {% endif %} @@ -142,6 +155,7 @@ "productName": "Notify", "navigation": navigation, "navigationClasses": "govuk-header__navigation--end", + "secondaryNavigation": secondaryNavigation, "assetsPath": asset_path + "images" }) }} {% endblock %} @@ -236,7 +250,7 @@ Please choose to extend your session or sign out. Your session will expire in 5 minutes or less.
-

You have been inactive for too long. +

You have been inactive for too long. Your session will expire in .

@@ -273,5 +287,3 @@ {% endblock %} - - diff --git a/app/templates/components/components/header/template.njk b/app/templates/components/components/header/template.njk index 1c817ea1c..f32df0cd9 100644 --- a/app/templates/components/components/header/template.njk +++ b/app/templates/components/components/header/template.njk @@ -76,18 +76,18 @@ {% endif %} {% endfor %} -
+
+ +{% endif %} From 69d5c8258be82adcd2ad8a9eda4fa65e63236c70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:51:04 +0000 Subject: [PATCH 21/53] Bump pytest from 7.4.3 to 7.4.4 Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.3 to 7.4.4. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.4.3...7.4.4) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5f986c742..a5e7e0e04 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2268,13 +2268,13 @@ certifi = "*" [[package]] name = "pytest" -version = "7.4.3" +version = "7.4.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, - {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] [package.dependencies] @@ -3089,4 +3089,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "f92abb1eca6bdad11491d05a6340400dbd9d31be955d737e0e719dc0b2826503" +content-hash = "4aa275f2b22f27a69188a7475652862d942e788f5abaf1e37e52484d2ba2fd8f" diff --git a/pyproject.toml b/pyproject.toml index 73c5f964a..dc8b0e723 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,7 +53,7 @@ jinja2-cli = {version = "==0.8.2", extras = ["yaml"]} moto = "^4.2" pip-audit = "*" pre-commit = "^3.6.0" -pytest = "^7.4.3" +pytest = "^7.4.4" pytest-env = "^1.1.3" pytest-mock = "^3.12.0" pytest-playwright = "^0.4.3" From 766933329e69a3b3742c81063de796645fded191 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:04:50 +0000 Subject: [PATCH 22/53] Bump coverage from 7.3.4 to 7.4.0 Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.3.4 to 7.4.0. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.3.4...7.4.0) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 106 ++++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5f986c742..1a4d3fadd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -462,63 +462,63 @@ files = [ [[package]] name = "coverage" -version = "7.3.4" +version = "7.4.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.3.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:aff2bd3d585969cc4486bfc69655e862028b689404563e6b549e6a8244f226df"}, - {file = "coverage-7.3.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4353923f38d752ecfbd3f1f20bf7a3546993ae5ecd7c07fd2f25d40b4e54571"}, - {file = "coverage-7.3.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea473c37872f0159294f7073f3fa72f68b03a129799f3533b2bb44d5e9fa4f82"}, - {file = "coverage-7.3.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5214362abf26e254d749fc0c18af4c57b532a4bfde1a057565616dd3b8d7cc94"}, - {file = "coverage-7.3.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f99b7d3f7a7adfa3d11e3a48d1a91bb65739555dd6a0d3fa68aa5852d962e5b1"}, - {file = "coverage-7.3.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:74397a1263275bea9d736572d4cf338efaade2de9ff759f9c26bcdceb383bb49"}, - {file = "coverage-7.3.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f154bd866318185ef5865ace5be3ac047b6d1cc0aeecf53bf83fe846f4384d5d"}, - {file = "coverage-7.3.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e0d84099ea7cba9ff467f9c6f747e3fc3906e2aadac1ce7b41add72e8d0a3712"}, - {file = "coverage-7.3.4-cp310-cp310-win32.whl", hash = "sha256:3f477fb8a56e0c603587b8278d9dbd32e54bcc2922d62405f65574bd76eba78a"}, - {file = "coverage-7.3.4-cp310-cp310-win_amd64.whl", hash = "sha256:c75738ce13d257efbb6633a049fb2ed8e87e2e6c2e906c52d1093a4d08d67c6b"}, - {file = "coverage-7.3.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:997aa14b3e014339d8101b9886063c5d06238848905d9ad6c6eabe533440a9a7"}, - {file = "coverage-7.3.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8a9c5bc5db3eb4cd55ecb8397d8e9b70247904f8eca718cc53c12dcc98e59fc8"}, - {file = "coverage-7.3.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27ee94f088397d1feea3cb524e4313ff0410ead7d968029ecc4bc5a7e1d34fbf"}, - {file = "coverage-7.3.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ce03e25e18dd9bf44723e83bc202114817f3367789052dc9e5b5c79f40cf59d"}, - {file = "coverage-7.3.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85072e99474d894e5df582faec04abe137b28972d5e466999bc64fc37f564a03"}, - {file = "coverage-7.3.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a877810ef918d0d345b783fc569608804f3ed2507bf32f14f652e4eaf5d8f8d0"}, - {file = "coverage-7.3.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9ac17b94ab4ca66cf803f2b22d47e392f0977f9da838bf71d1f0db6c32893cb9"}, - {file = "coverage-7.3.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:36d75ef2acab74dc948d0b537ef021306796da551e8ac8b467810911000af66a"}, - {file = "coverage-7.3.4-cp311-cp311-win32.whl", hash = "sha256:47ee56c2cd445ea35a8cc3ad5c8134cb9bece3a5cb50bb8265514208d0a65928"}, - {file = "coverage-7.3.4-cp311-cp311-win_amd64.whl", hash = "sha256:11ab62d0ce5d9324915726f611f511a761efcca970bd49d876cf831b4de65be5"}, - {file = "coverage-7.3.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:33e63c578f4acce1b6cd292a66bc30164495010f1091d4b7529d014845cd9bee"}, - {file = "coverage-7.3.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:782693b817218169bfeb9b9ba7f4a9f242764e180ac9589b45112571f32a0ba6"}, - {file = "coverage-7.3.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c4277ddaad9293454da19121c59f2d850f16bcb27f71f89a5c4836906eb35ef"}, - {file = "coverage-7.3.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3d892a19ae24b9801771a5a989fb3e850bd1ad2e2b6e83e949c65e8f37bc67a1"}, - {file = "coverage-7.3.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3024ec1b3a221bd10b5d87337d0373c2bcaf7afd86d42081afe39b3e1820323b"}, - {file = "coverage-7.3.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1c3e9d2bbd6f3f79cfecd6f20854f4dc0c6e0ec317df2b265266d0dc06535f1"}, - {file = "coverage-7.3.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e91029d7f151d8bf5ab7d8bfe2c3dbefd239759d642b211a677bc0709c9fdb96"}, - {file = "coverage-7.3.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:6879fe41c60080aa4bb59703a526c54e0412b77e649a0d06a61782ecf0853ee1"}, - {file = "coverage-7.3.4-cp312-cp312-win32.whl", hash = "sha256:fd2f8a641f8f193968afdc8fd1697e602e199931012b574194052d132a79be13"}, - {file = "coverage-7.3.4-cp312-cp312-win_amd64.whl", hash = "sha256:d1d0ce6c6947a3a4aa5479bebceff2c807b9f3b529b637e2b33dea4468d75fc7"}, - {file = "coverage-7.3.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:36797b3625d1da885b369bdaaa3b0d9fb8865caed3c2b8230afaa6005434aa2f"}, - {file = "coverage-7.3.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bfed0ec4b419fbc807dec417c401499ea869436910e1ca524cfb4f81cf3f60e7"}, - {file = "coverage-7.3.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f97ff5a9fc2ca47f3383482858dd2cb8ddbf7514427eecf5aa5f7992d0571429"}, - {file = "coverage-7.3.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:607b6c6b35aa49defaebf4526729bd5238bc36fe3ef1a417d9839e1d96ee1e4c"}, - {file = "coverage-7.3.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8e258dcc335055ab59fe79f1dec217d9fb0cdace103d6b5c6df6b75915e7959"}, - {file = "coverage-7.3.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a02ac7c51819702b384fea5ee033a7c202f732a2a2f1fe6c41e3d4019828c8d3"}, - {file = "coverage-7.3.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b710869a15b8caf02e31d16487a931dbe78335462a122c8603bb9bd401ff6fb2"}, - {file = "coverage-7.3.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c6a23ae9348a7a92e7f750f9b7e828448e428e99c24616dec93a0720342f241d"}, - {file = "coverage-7.3.4-cp38-cp38-win32.whl", hash = "sha256:758ebaf74578b73f727acc4e8ab4b16ab6f22a5ffd7dd254e5946aba42a4ce76"}, - {file = "coverage-7.3.4-cp38-cp38-win_amd64.whl", hash = "sha256:309ed6a559bc942b7cc721f2976326efbfe81fc2b8f601c722bff927328507dc"}, - {file = "coverage-7.3.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:aefbb29dc56317a4fcb2f3857d5bce9b881038ed7e5aa5d3bcab25bd23f57328"}, - {file = "coverage-7.3.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:183c16173a70caf92e2dfcfe7c7a576de6fa9edc4119b8e13f91db7ca33a7923"}, - {file = "coverage-7.3.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a4184dcbe4f98d86470273e758f1d24191ca095412e4335ff27b417291f5964"}, - {file = "coverage-7.3.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93698ac0995516ccdca55342599a1463ed2e2d8942316da31686d4d614597ef9"}, - {file = "coverage-7.3.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb220b3596358a86361139edce40d97da7458412d412e1e10c8e1970ee8c09ab"}, - {file = "coverage-7.3.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d5b14abde6f8d969e6b9dd8c7a013d9a2b52af1235fe7bebef25ad5c8f47fa18"}, - {file = "coverage-7.3.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:610afaf929dc0e09a5eef6981edb6a57a46b7eceff151947b836d869d6d567c1"}, - {file = "coverage-7.3.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d6ed790728fb71e6b8247bd28e77e99d0c276dff952389b5388169b8ca7b1c28"}, - {file = "coverage-7.3.4-cp39-cp39-win32.whl", hash = "sha256:c15fdfb141fcf6a900e68bfa35689e1256a670db32b96e7a931cab4a0e1600e5"}, - {file = "coverage-7.3.4-cp39-cp39-win_amd64.whl", hash = "sha256:38d0b307c4d99a7aca4e00cad4311b7c51b7ac38fb7dea2abe0d182dd4008e05"}, - {file = "coverage-7.3.4-pp38.pp39.pp310-none-any.whl", hash = "sha256:b1e0f25ae99cf247abfb3f0fac7ae25739e4cd96bf1afa3537827c576b4847e5"}, - {file = "coverage-7.3.4.tar.gz", hash = "sha256:020d56d2da5bc22a0e00a5b0d54597ee91ad72446fa4cf1b97c35022f6b6dbf0"}, + {file = "coverage-7.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a"}, + {file = "coverage-7.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516"}, + {file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae"}, + {file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43"}, + {file = "coverage-7.4.0-cp310-cp310-win32.whl", hash = "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451"}, + {file = "coverage-7.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137"}, + {file = "coverage-7.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca"}, + {file = "coverage-7.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc"}, + {file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09"}, + {file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26"}, + {file = "coverage-7.4.0-cp311-cp311-win32.whl", hash = "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614"}, + {file = "coverage-7.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590"}, + {file = "coverage-7.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143"}, + {file = "coverage-7.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446"}, + {file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a"}, + {file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa"}, + {file = "coverage-7.4.0-cp312-cp312-win32.whl", hash = "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450"}, + {file = "coverage-7.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0"}, + {file = "coverage-7.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e"}, + {file = "coverage-7.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1"}, + {file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e"}, + {file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105"}, + {file = "coverage-7.4.0-cp38-cp38-win32.whl", hash = "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2"}, + {file = "coverage-7.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555"}, + {file = "coverage-7.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42"}, + {file = "coverage-7.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed"}, + {file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058"}, + {file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f"}, + {file = "coverage-7.4.0-cp39-cp39-win32.whl", hash = "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932"}, + {file = "coverage-7.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e"}, + {file = "coverage-7.4.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6"}, + {file = "coverage-7.4.0.tar.gz", hash = "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e"}, ] [package.extras] From 25806a3440f513846c34e6b38586fb273776b5e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:13:07 +0000 Subject: [PATCH 23/53] Bump notifications-python-client from 8.1.0 to 8.2.0 Bumps [notifications-python-client](https://github.com/alphagov/notifications-python-client) from 8.1.0 to 8.2.0. - [Changelog](https://github.com/alphagov/notifications-python-client/blob/main/CHANGELOG.md) - [Commits](https://github.com/alphagov/notifications-python-client/compare/8.1.0...8.2.0) --- updated-dependencies: - dependency-name: notifications-python-client dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index a5e7e0e04..49ce90080 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1676,12 +1676,12 @@ setuptools = "*" [[package]] name = "notifications-python-client" -version = "8.1.0" +version = "8.2.0" description = "Python API client for GOV.UK Notify." optional = false python-versions = ">=3.7" files = [ - {file = "notifications_python_client-8.1.0-py3-none-any.whl", hash = "sha256:8aec1f7a4ba592fd699eae899df8ccca9ccafb614f47826c07b318ca903c9c13"}, + {file = "notifications_python_client-8.2.0-py3-none-any.whl", hash = "sha256:8cd8bd01ae603a972a5413c430ca42b16f6481f37d98406c3e9b68c1c192f59e"}, ] [package.dependencies] @@ -3089,4 +3089,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "4aa275f2b22f27a69188a7475652862d942e788f5abaf1e37e52484d2ba2fd8f" +content-hash = "b4223b62fe62c0dca55cafab817f7527081865b6f1e1c0a8c306c3eb0332b1e9" diff --git a/pyproject.toml b/pyproject.toml index dc8b0e723..06cb7c342 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ humanize = "~=4.9" itsdangerous = "~=2.1" jinja2 = "~=3.1" newrelic = "*" -notifications-python-client = "==8.1.0" +notifications-python-client = "==8.2.0" notifications-utils = {git = "https://github.com/GSA/notifications-utils.git"} pyexcel = "==0.7.0" pyexcel-io = "==0.6.6" From 0b22c53ea38765ade685ec8d1082eb7ea2826d90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:42:23 +0000 Subject: [PATCH 24/53] Bump tj-actions/changed-files from 1.1.2 to 41.0.0 in /.github/workflows Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 1.1.2 to 41.0.0. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v1.1.2...v41.0.0) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/deploy-demo.yml | 4 ++-- .github/workflows/deploy-prod.yml | 4 ++-- .github/workflows/deploy.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-demo.yml b/.github/workflows/deploy-demo.yml index 771209267..c308cd71a 100644 --- a/.github/workflows/deploy-demo.yml +++ b/.github/workflows/deploy-demo.yml @@ -18,7 +18,7 @@ jobs: - name: Check for changes to Terraform id: changed-terraform-files - uses: tj-actions/changed-files@v1.1.2 + uses: tj-actions/changed-files@v41.0.0 with: files: | terraform/demo @@ -72,7 +72,7 @@ jobs: - name: Check for changes to egress config id: changed-egress-config - uses: tj-actions/changed-files@v34 + uses: tj-actions/changed-files@v41.0.0 with: files: | deploy-config/egress_proxy/notify-admin-demo.*.acl diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml index 0f696de36..3c1ab8b8a 100644 --- a/.github/workflows/deploy-prod.yml +++ b/.github/workflows/deploy-prod.yml @@ -18,7 +18,7 @@ jobs: - name: Check for changes to Terraform id: changed-terraform-files - uses: tj-actions/changed-files@v1.1.2 + uses: tj-actions/changed-files@v41.0.0 with: files: | terraform/production @@ -73,7 +73,7 @@ jobs: - name: Check for changes to egress config id: changed-egress-config - uses: tj-actions/changed-files@v34 + uses: tj-actions/changed-files@v41.0.0 with: files: | deploy-config/egress_proxy/notify-admin-production.*.acl diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 8ef41c2a7..767acae72 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -23,7 +23,7 @@ jobs: - name: Check for changes to Terraform id: changed-terraform-files - uses: tj-actions/changed-files@v1.1.2 + uses: tj-actions/changed-files@v41.0.0 with: files: | terraform/staging @@ -93,7 +93,7 @@ jobs: - name: Check for changes to egress config id: changed-egress-config - uses: tj-actions/changed-files@v34 + uses: tj-actions/changed-files@v41.0.0 with: files: | deploy-config/egress_proxy/notify-admin-staging.*.acl From 2ad234e33807f5135643f7508c7262a9d2c86d3e Mon Sep 17 00:00:00 2001 From: Tim Lowden Date: Wed, 3 Jan 2024 10:08:04 -0500 Subject: [PATCH 25/53] Update sprint-goals.md --- docs/sprint-goals.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/sprint-goals.md b/docs/sprint-goals.md index cfae21996..17b405d7c 100644 --- a/docs/sprint-goals.md +++ b/docs/sprint-goals.md @@ -1,7 +1,18 @@ # Notify Sprint Goals Log +## Sprint: A (1/3/24) +2024 Sprints will be named after mythical creatures -## Sprint: Z (12/21/23) +| | Goals | Impact | Milestone(s) | +|-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|--------------| +| Engineering | Continue [identifying](https://github.com/GSA/notifications-api/issues/656), [fixing](https://github.com/GSA/notifications-api/issues/645), and [displaying](https://github.com/GSA/notifications-admin/issues/964) various applicable message part limits, devise ways to [create better access to reports](https://github.com/GSA/notifications-admin/issues/855), implement Login.gov on staging environment, advance epic to [remove phone numbers from db](https://github.com/GSA/notifications-api/issues/667) | Better track annual and smart-retention limits, install required auth, make reports easier to find, expand message send volume for partners | Building Notify.gov | +| UX | Spin up weekly [redesign syncs](https://github.com/GSA/notifications-admin/issues/1061), identify necessary dashboard metrics to visualize, improve [team member section](https://github.com/GSA/notifications-admin/issues/1031)| Improve UX | Building Notify.gov| +| Security | Complete necessary control families | Aim to have package completed with enough time to allow for long assessment| Secure ATO | +| Content | Finish making [editing content easier](https://github.com/GSA/notifications-admin/issues/976) with existing templates, finalize decision on terminology regarding [batch/campaign/job](https://github.com/GSA/notifications-admin/issues/1060), make content [more clear about limits](https://github.com/GSA/notifications-admin/issues/963), make content clearer by [adding `parts` where necessary](https://github.com/GSA/notifications-admin/issues/963) | Improve clarity of message parts for users, streamline content editing for the team| Building Notify.gov | +| Ops | Assist in Tech to Gov process | | + +## Sprint: Zoe's Imperial Pigeon (12/21/23) +Sprint velocity was very low due to holiday OOO | | Goals | Impact | Milestone(s) | |-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|--------------| From a884bef77bea79f99865e2d275b38d6b4f38a794 Mon Sep 17 00:00:00 2001 From: Anastasia Gradova <108748167+anagradova@users.noreply.github.com> Date: Wed, 3 Jan 2024 10:08:14 -0700 Subject: [PATCH 26/53] Update app/content/get-started.md Co-authored-by: Steven Reilly --- app/content/get-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/content/get-started.md b/app/content/get-started.md index ab5cffdac..c9668e70c 100644 --- a/app/content/get-started.md +++ b/app/content/get-started.md @@ -42,7 +42,7 @@ {% if not current_user.is_authenticated or not current_service %}

When you’re ready to send messages to people outside your team, go to the Settings page and select Request to go live. We’ll approve your request within one working day.

{% else %} -

You should request to go live when you’re ready to send messages to people outside your team. We’ll approve your request within one working day.

+

You should request to go live when you’re ready to send messages to people outside your team. We’ll approve your request within one working day.

{% endif %} From 7a1d9cf705aefcfe22436ad4d92735bc3c902080 Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Wed, 3 Jan 2024 22:01:07 -0700 Subject: [PATCH 27/53] built new beautifulsoup function to apply html tags to markdown file once processed with test cases. --- app/content/get-started.md | 41 +++++++++++++------------------ app/formatters.py | 27 +++++++++++++++++--- app/main/views/index.py | 10 ++++++-- tests/app/main/test_formatters.py | 5 ++++ tests/conftest.py | 6 +++++ 5 files changed, 60 insertions(+), 29 deletions(-) diff --git a/app/content/get-started.md b/app/content/get-started.md index c9668e70c..7846c0fe6 100644 --- a/app/content/get-started.md +++ b/app/content/get-started.md @@ -1,27 +1,23 @@ -

Get started

+# Get started -
    -
  1. -

    Check if Notify.gov is right for you

    + +1. ## Check if Notify.gov is right for you

    Read about our features, pricing and roadmap.

    -
  2. -
  3. -

    Create an account

    + +2. ## Create an account {% if not current_user.is_authenticated %}

    Create an account for free and add your first Notify service. When you add a new service it will start in trial mode.

    {% else %}

    Create an account for free and add your first Notify service. When you add a new service, it will start in trial mode.

    {% endif %} -
  4. -
  5. -

    Write some messages

    +3. ## Write some messages + {% if True %}

    Add message templates with examples of the content you plan to send. You can use our guidance to help you.

    -
  6. + {% endif %} -
  7. -

    Set up your service

    +4. ## Set up your service {% if not current_user.is_authenticated or not current_service %}

    Review your settings to add message branding and sender information.

    Add team members and check their permissions.

    @@ -29,22 +25,19 @@

    Review your settings to add message branding and sender information.

    Add team members and check their permissions.

    {% endif %} -
  8. - -
  9. -

    Start sending messages

    +5. ## Start sending messages {% if not current_user.is_authenticated or not current_service %}

    When you’re ready to send messages to people outside your team, go to the Settings page and select Request to go live. We’ll approve your request within one working day.

    {% else %}

    You should request to go live when you’re ready to send messages to people outside your team. We’ll approve your request within one working day.

    {% endif %} - -
  10. -
+ + + diff --git a/app/formatters.py b/app/formatters.py index 4ea5d5104..ed4198395 100644 --- a/app/formatters.py +++ b/app/formatters.py @@ -12,6 +12,7 @@ import dateutil import humanize import markdown import pytz +from bs4 import BeautifulSoup from flask import Markup, render_template_string, url_for from flask.helpers import get_root_path from notifications_utils.field import Field @@ -24,6 +25,25 @@ from app.utils.csv import get_user_preferred_timezone from app.utils.time import parse_naive_dt +def apply_html_class(tags, html_file): + + new_html = html_file + + for tag in tags: + + element = tag[0] + class_name = tag[1] + + soup = BeautifulSoup(new_html, 'html.parser') + + for xtag in soup.find_all(element): + xtag['class'] = class_name + + new_html = str(soup) + + return new_html + + def convert_markdown_template(mdf, test=False): content_text = "" @@ -37,10 +57,11 @@ def convert_markdown_template(mdf, test=False): else: content_text = mdf - md_render = markdown.markdown(content_text) - jn_render = render_template_string(md_render) + jn_render = render_template_string(content_text) + md_render = markdown.markdown(jn_render) - return jn_render + + return md_render def convert_to_boolean(value): diff --git a/app/main/views/index.py b/app/main/views/index.py index d6d08150d..ef5c1a5da 100644 --- a/app/main/views/index.py +++ b/app/main/views/index.py @@ -2,7 +2,7 @@ from flask import abort, redirect, render_template, request, url_for from flask_login import current_user from app import status_api_client -from app.formatters import convert_markdown_template +from app.formatters import apply_html_class, convert_markdown_template from app.main import main from app.main.views.pricing import CURRENT_SMS_RATE from app.main.views.sub_navigation_dictionaries import features_nav, using_notify_nav @@ -138,10 +138,16 @@ def get_started_old(): @main.route("/using-notify/get-started") @user_is_logged_in def get_started(): + markdown = convert_markdown_template('get-started') + html_style = apply_html_class([['ol', 'usa-process-list'], + ['li', 'usa-process-list__item padding-bottom-4 margin-top-2'], + ['h2', 'usa-process-list__heading line-height-sans-3']], + markdown) + return render_template( "views/get-started.html", navigation_links=using_notify_nav(), - content=convert_markdown_template('get-started') + content=html_style ) diff --git a/tests/app/main/test_formatters.py b/tests/app/main/test_formatters.py index eeded8c13..f50bd71ff 100644 --- a/tests/app/main/test_formatters.py +++ b/tests/app/main/test_formatters.py @@ -7,6 +7,7 @@ from freezegun import freeze_time from app.formatters import ( convert_markdown_template, + apply_html_class, email_safe, format_datetime_relative, format_delta, @@ -181,3 +182,7 @@ def test_markdown_format(fake_markdown_file): app = Flask("app") with app.app_context(): assert convert_markdown_template(fake_markdown_file, test=True) == "

Test

" + +@pytest.mark.usefixtures("fake_soup_template") +def test_soup_format(fake_soup_template): + assert apply_html_class([['h1', 'testClass']], fake_soup_template) == '

Test

' diff --git a/tests/conftest.py b/tests/conftest.py index 936bb8a79..5a9057cf3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3606,3 +3606,9 @@ def fake_markdown_file(): def fake_jinja_template(): input = "{% if True %}True{% endif %}" return input + + +@pytest.fixture() +def fake_soup_template(): + input = "

Test

" + return input From df4ee859e5081caffea28ba5bc5320dd3f1e712b Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Wed, 3 Jan 2024 22:08:42 -0700 Subject: [PATCH 28/53] style update --- tests/app/main/test_formatters.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/app/main/test_formatters.py b/tests/app/main/test_formatters.py index f50bd71ff..377429418 100644 --- a/tests/app/main/test_formatters.py +++ b/tests/app/main/test_formatters.py @@ -183,6 +183,7 @@ def test_markdown_format(fake_markdown_file): with app.app_context(): assert convert_markdown_template(fake_markdown_file, test=True) == "

Test

" + @pytest.mark.usefixtures("fake_soup_template") def test_soup_format(fake_soup_template): assert apply_html_class([['h1', 'testClass']], fake_soup_template) == '

Test

' From d1b71838e184dbfde0206ebed7cab11da612afb7 Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Wed, 3 Jan 2024 22:13:04 -0700 Subject: [PATCH 29/53] style update --- app/formatters.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/formatters.py b/app/formatters.py index ed4198395..ec3075e6c 100644 --- a/app/formatters.py +++ b/app/formatters.py @@ -60,7 +60,6 @@ def convert_markdown_template(mdf, test=False): jn_render = render_template_string(content_text) md_render = markdown.markdown(jn_render) - return md_render From 545fbbe43cdae72e8b888fbee51b8fa0392bb217 Mon Sep 17 00:00:00 2001 From: Anastasia Gradova Date: Wed, 3 Jan 2024 22:17:43 -0700 Subject: [PATCH 30/53] isort update --- tests/app/main/test_formatters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/main/test_formatters.py b/tests/app/main/test_formatters.py index 377429418..81e78ed0c 100644 --- a/tests/app/main/test_formatters.py +++ b/tests/app/main/test_formatters.py @@ -6,8 +6,8 @@ from flask import Flask, url_for from freezegun import freeze_time from app.formatters import ( - convert_markdown_template, apply_html_class, + convert_markdown_template, email_safe, format_datetime_relative, format_delta, From 7d6a07efd7cb8d2fbbc1b73b048c4a5e03e90add Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Thu, 4 Jan 2024 10:02:31 -0500 Subject: [PATCH 31/53] Test update --- tests/app/main/test_permissions.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/app/main/test_permissions.py b/tests/app/main/test_permissions.py index 2843407ba..3ad521ae2 100644 --- a/tests/app/main/test_permissions.py +++ b/tests/app/main/test_permissions.py @@ -125,7 +125,6 @@ def test_service_navigation_for_org_user( ( "Send messages", "Sent messages", - "Team members", ), 403, ), @@ -134,7 +133,7 @@ def test_service_navigation_for_org_user( ( "Send messages", "Sent messages", - "Team members", + "Usage", ), 200, ), From f1e678760b9c5a6f19ed996c64681ba03f5abb28 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Thu, 4 Jan 2024 15:23:01 -0500 Subject: [PATCH 32/53] Updating tests, but need to add a new one to test the new secondary navivation --- app/templates/admin_template.html | 33 ++++++++++++++++---------- app/templates/settings_nav.html | 4 ++-- tests/app/main/views/test_dashboard.py | 14 +++++------ 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/app/templates/admin_template.html b/app/templates/admin_template.html index c858fb59e..03e229236 100644 --- a/app/templates/admin_template.html +++ b/app/templates/admin_template.html @@ -117,18 +117,27 @@ "active": header_navigation.is_selected('user-profile') } ] %} - {% set secondaryNavigation = [ - { - "href": url_for('.service_settings', service_id=current_service.id), - "text": "Settings", - "active": secondary_navigation.is_selected('settings') - }, - { - "href": url_for('main.sign_out'), - "text": "Sign out" - } - ] %} - {% endif %} + {% if current_service %} + {% set secondaryNavigation = [ + { + "href": url_for('main.service_settings', service_id=current_service.id), + "text": "Settings", + "active": secondary_navigation.is_selected('settings') + }, + { + "href": url_for('main.sign_out'), + "text": "Sign out" + } + ] %} + {% else %} + {% set secondaryNavigation = [ + { + "href": url_for('main.sign_out'), + "text": "Sign out" + } + ] %} + {% endif %} + {% endif %} {% else %} {# {% set navigation = [ diff --git a/app/templates/settings_nav.html b/app/templates/settings_nav.html index e6fbbe437..d94c417e7 100644 --- a/app/templates/settings_nav.html +++ b/app/templates/settings_nav.html @@ -5,11 +5,11 @@
    {# {% if current_user.has_permissions() %} #}
  • General
  • + href="{{ url_for('main.service_settings', service_id=current_service.id) }}">General
  • User profile
  • Team members
  • + href="{{ url_for('main.manage_users', service_id=current_service.id) }}">Team members {# {% endif %} #}
diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 010b53d5d..95b67d3ad 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -1052,9 +1052,9 @@ def test_menu_send_messages( in page ) # assert url_for('main.uploads', service_id=service_one['id']) in page - assert url_for("main.manage_users", service_id=service_one["id"]) in page + assert url_for("main.manage_users", service_id=service_one["id"]) not in page - assert url_for("main.service_settings", service_id=service_one["id"]) not in page + assert url_for("main.service_settings", service_id=service_one["id"]) in page # assert url_for('main.api_keys', service_id=service_one['id']) not in page @@ -1086,7 +1086,7 @@ def test_menu_manage_service( ) in page ) - assert url_for("main.manage_users", service_id=service_one["id"]) in page + # assert url_for("main.manage_users", service_id=service_one["id"]) in page assert url_for("main.service_settings", service_id=service_one["id"]) in page # assert url_for('main.api_keys', service_id=service_one['id']) not in page @@ -1122,8 +1122,8 @@ def test_menu_manage_api_keys( ) in page ) - assert url_for("main.manage_users", service_id=service_one["id"]) in page - assert url_for("main.service_settings", service_id=service_one["id"]) in page + # assert url_for("main.manage_users", service_id=service_one["id"]) not in page + # assert url_for("main.service_settings", service_id=service_one["id"]) not in page assert url_for("main.api_integration", service_id=service_one["id"]) in page @@ -1145,8 +1145,8 @@ def test_menu_all_services_for_platform_admin_user( ) page = str(page) assert url_for("main.choose_template", service_id=service_one["id"]) in page - assert url_for("main.manage_users", service_id=service_one["id"]) in page - assert url_for("main.service_settings", service_id=service_one["id"]) in page + # assert url_for("main.manage_users", service_id=service_one["id"]) in page + # assert url_for("main.service_settings", service_id=service_one["id"]) in page # assert url_for('main.view_notifications', service_id=service_one['id'], message_type='email') in page assert ( url_for( From 3a1d624d8fe41600aa58e8ec76bef276c864ca5c Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Thu, 4 Jan 2024 15:43:43 -0500 Subject: [PATCH 33/53] Missed a test --- tests/app/main/views/accounts/test_choose_accounts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app/main/views/accounts/test_choose_accounts.py b/tests/app/main/views/accounts/test_choose_accounts.py index 8b94ebe64..dae5c712a 100644 --- a/tests/app/main/views/accounts/test_choose_accounts.py +++ b/tests/app/main/views/accounts/test_choose_accounts.py @@ -363,7 +363,7 @@ def test_should_show_back_to_service_if_user_belongs_to_service( ): mock_get_service.return_value = service_one expected_page_text = ( - "Test Service Switch service " "Send messages " "Dashboard " "Team members" + "Test Service Switch service " "Send messages " "Dashboard " "Usage" ) # TODO: set sidebar variables in common test module page = client_request.get( From 5a243904b6d0f5feb25e96d4e5cabf6592057e69 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Fri, 5 Jan 2024 12:07:20 -0500 Subject: [PATCH 34/53] Updated the tests to include the Settings page --- app/templates/admin_template.html | 2 +- tests/app/main/views/test_dashboard.py | 52 +++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/app/templates/admin_template.html b/app/templates/admin_template.html index 03e229236..c48f768ce 100644 --- a/app/templates/admin_template.html +++ b/app/templates/admin_template.html @@ -72,7 +72,7 @@ {% if current_service %} {% set secondaryNavigation = [ { - "href": url_for('.service_settings', service_id=current_service.id), + "href": url_for('main.service_settings', service_id=current_service.id), "text": "Settings", "active": secondary_navigation.is_selected('settings') }, diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 95b67d3ad..1acd1f2de 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -1020,6 +1020,20 @@ def _test_dashboard_menu(client_request, mocker, usr, service, permissions): return client_request.get("main.service_dashboard", service_id=service["id"]) +def _test_settings_menu(client_request, mocker, usr, service, permissions): + usr["permissions"][str(service["id"])] = permissions + usr["services"] = [service["id"]] + mocker.patch("app.user_api_client.check_verify_code", return_value=(True, "")) + mocker.patch( + "app.service_api_client.get_services", return_value={"data": [service]} + ) + mocker.patch("app.user_api_client.get_user", return_value=usr) + mocker.patch("app.user_api_client.get_user_by_email", return_value=usr) + mocker.patch("app.service_api_client.get_service", return_value={"data": service}) + client_request.login(usr) + return client_request.get("main.service_dashboard", service_id=service["id"]) + + def test_menu_send_messages( client_request, mocker, @@ -1051,11 +1065,8 @@ def test_menu_send_messages( ) in page ) - # assert url_for('main.uploads', service_id=service_one['id']) in page assert url_for("main.manage_users", service_id=service_one["id"]) not in page - assert url_for("main.service_settings", service_id=service_one["id"]) in page - # assert url_for('main.api_keys', service_id=service_one['id']) not in page def test_menu_manage_service( @@ -1086,10 +1097,39 @@ def test_menu_manage_service( ) in page ) - # assert url_for("main.manage_users", service_id=service_one["id"]) in page - assert url_for("main.service_settings", service_id=service_one["id"]) in page + assert url_for(".service_dashboard", service_id=service_one["id"]) in page + assert url_for(".choose_template", service_id=service_one["id"]) in page - # assert url_for('main.api_keys', service_id=service_one['id']) not in page + +def test_menu_main_settings( + client_request, + mocker, + api_user_active, + service_one, + mock_get_service_templates, + mock_has_no_jobs, + mock_get_template_statistics, + mock_get_service_statistics, + mock_get_annual_usage_for_service, + mock_get_inbound_sms_summary, + mock_get_free_sms_fragment_limit, +): + page = _test_settings_menu( + client_request, + mocker, + api_user_active, + service_one, + ["view_activity", "user_profile", "manage_users", "manage_settings"], + ) + page = str(page) + assert ( + url_for( + "main.service_settings", + service_id=service_one["id"], + ) + in page + ) + assert url_for("main.service_settings", service_id=service_one["id"]) in page def test_menu_manage_api_keys( From 07de703491679313133f615a38314eca8f19dff0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 8 Jan 2024 08:25:11 -0800 Subject: [PATCH 35/53] notify-admin-1049 --- app/main/forms.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/main/forms.py b/app/main/forms.py index 2520474fc..4036af416 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1239,11 +1239,15 @@ class ChangePreferredTimezoneForm(StripWhitespaceForm): def __init__(self, *args, **kwargs): super(ChangePreferredTimezoneForm, self).__init__(*args, **kwargs) self.new_preferred_timezone.choices = [ + ("US/Atlantic", "US/Atlantic") ("US/Eastern", "US/Eastern"), ("US/Central", "US/Central"), ("US/Mountain", "US/Mountain"), ("US/Pacific", "US/Pacific"), - ("US/Hawaii", "US/Hawaii"), + ("US/Alaska", "US/Alaska") + ("US/Hawaii-Aleutian", "US/Hawaii-Aleutian"), + ("US/American Samoa", "US/American Samoa"), + ("US/Chamorro", "US/Chamorro") ] new_preferred_timezone = GovukRadiosField( From 38f590907924fc21201d91a6dd7a30e58e8b7bcc Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 8 Jan 2024 08:27:37 -0800 Subject: [PATCH 36/53] fix format --- deploy-config/egress_proxy/notify-admin-staging.allow.acl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/deploy-config/egress_proxy/notify-admin-staging.allow.acl b/deploy-config/egress_proxy/notify-admin-staging.allow.acl index d329f111d..65c7931d2 100644 --- a/deploy-config/egress_proxy/notify-admin-staging.allow.acl +++ b/deploy-config/egress_proxy/notify-admin-staging.allow.acl @@ -1,2 +1,4 @@ gov-collector.newrelic.com egress-proxy-notify-admin-staging.apps.internal +idp.int.identitysandbox.gov +secure.login.gov From f43fd3e21f24d70bbf1fecc206bb15fb38472f08 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 8 Jan 2024 10:13:26 -0800 Subject: [PATCH 37/53] add missing timezones --- app/main/forms.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index 4036af416..d9a35b72a 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1235,19 +1235,20 @@ class ChangeNameForm(StripWhitespaceForm): new_name = GovukTextInputField("Your name") +# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones class ChangePreferredTimezoneForm(StripWhitespaceForm): def __init__(self, *args, **kwargs): super(ChangePreferredTimezoneForm, self).__init__(*args, **kwargs) self.new_preferred_timezone.choices = [ - ("US/Atlantic", "US/Atlantic") + ("America/Puerto_Rico", "America/Puerto_Rico"), ("US/Eastern", "US/Eastern"), ("US/Central", "US/Central"), ("US/Mountain", "US/Mountain"), ("US/Pacific", "US/Pacific"), - ("US/Alaska", "US/Alaska") - ("US/Hawaii-Aleutian", "US/Hawaii-Aleutian"), - ("US/American Samoa", "US/American Samoa"), - ("US/Chamorro", "US/Chamorro") + ("US/Alaska", "US/Alaska"), + ("US/Hawaii", "US/Hawaii"), + ("US/Aleutian", "US/Aleutian"), + ("US/Samoa", "US/Samoa"), ] new_preferred_timezone = GovukRadiosField( From c5c7dd5321f58f89eff48a3933e0e34203ac62b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 23:12:02 +0000 Subject: [PATCH 38/53] Bump moto from 4.2.12 to 4.2.13 Bumps [moto](https://github.com/getmoto/moto) from 4.2.12 to 4.2.13. - [Release notes](https://github.com/getmoto/moto/releases) - [Changelog](https://github.com/getmoto/moto/blob/master/CHANGELOG.md) - [Commits](https://github.com/getmoto/moto/compare/4.2.12...4.2.13) --- updated-dependencies: - dependency-name: moto dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 952fa7c07..444043892 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1510,13 +1510,13 @@ files = [ [[package]] name = "moto" -version = "4.2.12" +version = "4.2.13" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "moto-4.2.12-py2.py3-none-any.whl", hash = "sha256:bdcad46e066a55b7d308a786e5dca863b3cba04c6239c6974135a48d1198b3ab"}, - {file = "moto-4.2.12.tar.gz", hash = "sha256:7c4d37f47becb4a0526b64df54484e988c10fde26861fc3b5c065bc78800cb59"}, + {file = "moto-4.2.13-py2.py3-none-any.whl", hash = "sha256:93e0fd13b624bd79115494f833308c3641b2be0fc9f4f18aa9264aa01f6168e0"}, + {file = "moto-4.2.13.tar.gz", hash = "sha256:01aef6a489a725c8d725bd3dc6f70ff1bedaee3e2641752e4b471ff0ede4b4d7"}, ] [package.dependencies] From 872afba186ff31ab7d22af06979753c9d0ae4bc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 14:51:51 +0000 Subject: [PATCH 39/53] Bump pip-audit from 2.6.2 to 2.6.3 Bumps [pip-audit](https://github.com/pypa/pip-audit) from 2.6.2 to 2.6.3. - [Release notes](https://github.com/pypa/pip-audit/releases) - [Changelog](https://github.com/pypa/pip-audit/blob/main/CHANGELOG.md) - [Commits](https://github.com/pypa/pip-audit/compare/v2.6.2...v2.6.3) --- updated-dependencies: - dependency-name: pip-audit dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/poetry.lock b/poetry.lock index 444043892..b0a32d595 100644 --- a/poetry.lock +++ b/poetry.lock @@ -571,21 +571,26 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "cyclonedx-python-lib" -version = "4.2.3" -description = "A library for producing CycloneDX SBOM (Software Bill of Materials) files." +version = "6.3.0" +description = "Python library for CycloneDX" optional = false -python-versions = ">=3.7,<4.0" +python-versions = ">=3.8,<4.0" files = [ - {file = "cyclonedx_python_lib-4.2.3-py3-none-any.whl", hash = "sha256:e9b923af525b6acf7bab917a35360b4b562b85dc15fde9eaa500828949adf73a"}, - {file = "cyclonedx_python_lib-4.2.3.tar.gz", hash = "sha256:904068b55d1665f0ea96f38307603cc14f95c3b421f1687fc2411326aefde3a6"}, + {file = "cyclonedx_python_lib-6.3.0-py3-none-any.whl", hash = "sha256:0e73c1036c2f7fc67adc28aef807e6b44340ea70202aab197fb06b20ea165de8"}, + {file = "cyclonedx_python_lib-6.3.0.tar.gz", hash = "sha256:82f2489de3c0cadad5af1ad7fa6b6a185f985746370245d38769699c734533c6"}, ] [package.dependencies] license-expression = ">=30,<31" packageurl-python = ">=0.11" -py-serializable = ">=0.11.1,<0.12.0" +py-serializable = ">=0.16,<0.18" sortedcontainers = ">=2.4.0,<3.0.0" +[package.extras] +json-validation = ["jsonschema[format] (>=4.18,<5.0)"] +validation = ["jsonschema[format] (>=4.18,<5.0)", "lxml (>=4,<6)"] +xml-validation = ["lxml (>=4,<6)"] + [[package]] name = "defusedxml" version = "0.7.1" @@ -1902,18 +1907,18 @@ pip = "*" [[package]] name = "pip-audit" -version = "2.6.2" +version = "2.6.3" description = "A tool for scanning Python environments for known vulnerabilities" optional = false python-versions = ">=3.8" files = [ - {file = "pip_audit-2.6.2-py3-none-any.whl", hash = "sha256:ac3a4b6e977ef2c574aa8d19a5d71d12201bdb65bba2d67d9df49f53f0be5e7d"}, - {file = "pip_audit-2.6.2.tar.gz", hash = "sha256:0bbd023a199a104b29f949f063a872d41113b5a9048285666820fa35a76a7794"}, + {file = "pip_audit-2.6.3-py3-none-any.whl", hash = "sha256:216983210db4a15393f9e80e4d24a805f5767e4c8e0c31fc70c336acc629613b"}, + {file = "pip_audit-2.6.3.tar.gz", hash = "sha256:bd796066f69684b2f4fc2c2b6d222589e23190db0bbde069cea5c2b0be2cc57d"}, ] [package.dependencies] CacheControl = {version = ">=0.13.0", extras = ["filecache"]} -cyclonedx-python-lib = ">=4,<6" +cyclonedx-python-lib = ">=5,<7" html5lib = ">=1.1" packaging = ">=23.0.0" pip-api = ">=0.0.28" @@ -1925,7 +1930,7 @@ toml = ">=0.10" [package.extras] dev = ["build", "bump (>=1.3.2)", "pip-audit[doc,lint,test]"] doc = ["pdoc"] -lint = ["interrogate", "mypy", "ruff (<0.1.9)", "types-html5lib", "types-requests", "types-toml"] +lint = ["interrogate", "mypy", "ruff (<0.1.12)", "types-html5lib", "types-requests", "types-toml"] test = ["coverage[toml] (>=7.0,!=7.3.3,<8.0)", "pretend", "pytest", "pytest-cov"] [[package]] @@ -2017,13 +2022,13 @@ virtualenv = ">=20.10.0" [[package]] name = "py-serializable" -version = "0.11.1" +version = "0.17.1" description = "Library for serializing and deserializing Python Objects to and from JSON and XML." optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "py-serializable-0.11.1.tar.gz", hash = "sha256:ba0e1287b9e4f645a5334f1913abd8e647e7250209f84f55dce3909498a6f586"}, - {file = "py_serializable-0.11.1-py3-none-any.whl", hash = "sha256:79e21f0672822e6200b15f45ce9f636e8126466f62dbd7d488c67313c72b5c3e"}, + {file = "py-serializable-0.17.1.tar.gz", hash = "sha256:875bb9c01df77f563dfcd1e75bb4244b5596083d3aad4ccd3fb63e1f5a9d3e5f"}, + {file = "py_serializable-0.17.1-py3-none-any.whl", hash = "sha256:389c2254d912bec3a44acdac667c947d73c59325050d5ae66386e1ed7108a45a"}, ] [package.dependencies] From 8b9a892e768612c83eb13fe7a18f66d39ba5d9d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:08:35 +0000 Subject: [PATCH 40/53] Bump newrelic from 9.3.0 to 9.4.0 Bumps [newrelic](https://github.com/newrelic/newrelic-python-agent) from 9.3.0 to 9.4.0. - [Release notes](https://github.com/newrelic/newrelic-python-agent/releases) - [Commits](https://github.com/newrelic/newrelic-python-agent/compare/v9.3.0...v9.4.0) --- updated-dependencies: - dependency-name: newrelic dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/poetry.lock b/poetry.lock index b0a32d595..23a245ebc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1640,26 +1640,40 @@ files = [ [[package]] name = "newrelic" -version = "9.3.0" +version = "9.4.0" description = "New Relic Python Agent" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ - {file = "newrelic-9.3.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:f25980a8c86bda75344b5b22edd5d6ad41777776e1ed8a495eb6e38e9813b02c"}, - {file = "newrelic-9.3.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:adefb6620c5a5d75b4bf3ec565cc4d91abcb5cc4e5569f5f82ab29fa3d5aa2d9"}, - {file = "newrelic-9.3.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:27056ab8a3cf39787fc1f93f55243749dd25786f65b15032b6fbb3e8534f4c2a"}, - {file = "newrelic-9.3.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:663fa1c074661f93abf681c8f6028de64744c67f004b722835de1372b6bc4d19"}, - {file = "newrelic-9.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83346c8f0bcb8f07f74c88f6073e4d44a2e2b3eeec5b2ebe8c450ae695d02b88"}, - {file = "newrelic-9.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2187078d7b0054b30f39dbf891cb2caa71a7046f6d0258fb8c0fcfce70777774"}, - {file = "newrelic-9.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe0f5edd4eba3d62742b3b0730bb4f826be015dd7fbb9c455b01c410421661a2"}, - {file = "newrelic-9.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8577a0f733174bee70a147f71aa061fb44a593a1be841feffe12dff480c6e02e"}, - {file = "newrelic-9.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:234594655ac0fbe938d34ce5d5d38549d0f5cc11d0552170903ad09574bb4499"}, - {file = "newrelic-9.3.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce38949404e974b566b21487394f5ea36a1fb80ba36cc4a6e8fb968d2e150ab"}, - {file = "newrelic-9.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a750ffed8aedacdafcb548b3d3f45630a96862db630c9f72520ebbfe91e4e9e0"}, - {file = "newrelic-9.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d01d0f0c22b1290dbd2756ef120cfbe154179aae35e1dfc579f8bfd574066105"}, - {file = "newrelic-9.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53e860c6eacfdef879f23fbbf7d76d8bbb90b725a1c422f62439c6edfceebc21"}, - {file = "newrelic-9.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4caad3017cc978f3130fe2f3933f233c214a4850a595458b733282b3b7f7e886"}, - {file = "newrelic-9.3.0.tar.gz", hash = "sha256:c2dd685527433f6b6fbffe58f83852b46c24b9713ebb8ee7af647e04c2de3ee4"}, + {file = "newrelic-9.4.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:ed7a8ab3fb4425d7d55c44517f24f5259eab2045d4b24a21cf9439d9a6f53ffd"}, + {file = "newrelic-9.4.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3d1253c67bc371f8eca386a8d96e0ae29861359ca5b62e7e5c4f87083b8a8930"}, + {file = "newrelic-9.4.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:04e055c3a4a9b2b2719bc83e5e2935f700f3943025d169873b8952b9576d3962"}, + {file = "newrelic-9.4.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1f28ef38aed097600e149755b4b102edcb18e9b4e270d415154699cec2cb1a05"}, + {file = "newrelic-9.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f177f27cfbcd3673359ce0d80f8e418fc706b019ba936bbba9aa08585dff5f0"}, + {file = "newrelic-9.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d3d4902431de420baf1c9801c17adb8d6accb01704a6206dcdbb3ab6cc83ca8"}, + {file = "newrelic-9.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66df7709bc8da0a79aea34eaf3f38410eeed2b84abb53fcac78130a0f4fb7eb4"}, + {file = "newrelic-9.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:89329509f6c37f444eedd4a6abc8e569c0faa74e42538e31288e75610ae5fb4e"}, + {file = "newrelic-9.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ec7da405d968b4f31103d6db407e409ad1cda1403efb22862bdefdd44a9742a"}, + {file = "newrelic-9.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3183168cc1a7d79b2b0be147ea657105a83c631e33edef5a17c469052f9ae944"}, + {file = "newrelic-9.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dcd592bb0115694ca4c8e4b9264ffc05af10c365dfd95c0b8bc10b89c03bb282"}, + {file = "newrelic-9.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0f74d88c1b279ffadae325ecebe35a3dab662ae074f868a03cfdc5be5214b3d3"}, + {file = "newrelic-9.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d61eb8972323d57919cefef8ba1faad325a7818939d00ee2bc9698f96a880ca8"}, + {file = "newrelic-9.4.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72267bf3c2ab493813d7f5fb084a722c52da1493b376c56ff1d6a637dc451bed"}, + {file = "newrelic-9.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:78567ccedf2bdb75dc567bec318e221dcfab4681bd05babc398ce1b78d60f67b"}, + {file = "newrelic-9.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7a0fcbe0a581bea77346e291a0329fe7fce5226252c69d41fd4d91ba4d7c5493"}, + {file = "newrelic-9.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9162bf466d8ed7c973a597115434855f4e37888c2350d56b25f9b11875d20f2"}, + {file = "newrelic-9.4.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5d9e8f0f9ef0920dfad046e70dd91fcecab225d1ea5c09369a701c24e622c69"}, + {file = "newrelic-9.4.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6b63ad134842b92521845864cbc47a7559d189cf8a706220a90974ad2a9510da"}, + {file = "newrelic-9.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:895bfa0e1497dc061139b83dd4a5ff7b40b3eafa62a2e54c5bce2e616c72c762"}, + {file = "newrelic-9.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b40049de63700f518a9ee4e2b97881c5796e8a72fe9684bd0ae8e11d1ec17755"}, + {file = "newrelic-9.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eb1a8571d0434d62eac401797e835feed1b39a918434ab1e72e486b39bc0e87"}, + {file = "newrelic-9.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:195bc995b227ed0cdbe2c95dc27ae057002432a7c84532e72ba57a430265054a"}, + {file = "newrelic-9.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:895d0e78da2b3d5abbde7e8856692944ada2b744b26cdb339d5cbfa4461e9acb"}, + {file = "newrelic-9.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d11de77ba0e9e7921b21385f8300172248e865cd38c16165ee48adc9af35c746"}, + {file = "newrelic-9.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3f71b218febb7a48a8df048a7248025e1bd86c76a3144602e56d2a9f7d1740d"}, + {file = "newrelic-9.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f5cecccf3e85dccfa6b5ad7be21ae8940c46c579e2979890d84969546322d715"}, + {file = "newrelic-9.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f9fa697c355790b52e3180044349bbc2822230ca6f98d6292df4142080cd20de"}, + {file = "newrelic-9.4.0.tar.gz", hash = "sha256:84437107e0d47be070a17b31f48b54abea7d4951b5ca89f5c2416a2fa6ab42b8"}, ] [package.extras] From 493654652c47c65082e84557b868df5c0385f540 Mon Sep 17 00:00:00 2001 From: Carlo Costino Date: Tue, 9 Jan 2024 12:03:04 -0500 Subject: [PATCH 41/53] This changeset shifts the BeautifulSoup dependency from a dev-only dependency to a proper project dependency. Signed-off-by: Carlo Costino --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9bb152279..4f06f14c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,6 +8,7 @@ readme = "README.md" [tool.poetry.dependencies] python = ">=3.9,<3.12" ago = "~=0.0.95" +beautifulsoup4 = "^4.12.2" blinker = "~=1.7" exceptiongroup = "==1.2.0" flask = "~=2.3" @@ -41,7 +42,6 @@ markdown = "^3.5.1" [tool.poetry.group.dev.dependencies] bandit = "*" -beautifulsoup4 = "^4.12.2" black = "^23.12.1" coverage = "*" freezegun = "^1.4.0" From 80744cd7c997095fcfa247621012154e1db2ef0a Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Tue, 9 Jan 2024 16:19:17 -0500 Subject: [PATCH 42/53] 1077 - fix failure threshold so it always shows with any failure % --- app/templates/views/platform-admin/_global_stats.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/views/platform-admin/_global_stats.html b/app/templates/views/platform-admin/_global_stats.html index aaf9b41ef..70ba725a7 100644 --- a/app/templates/views/platform-admin/_global_stats.html +++ b/app/templates/views/platform-admin/_global_stats.html @@ -13,7 +13,7 @@ {% if link %} {% endif %} - + {% if global_stats.email.failed %} {% if failure_link %} @@ -44,7 +44,7 @@ {% if link %} {% endif %} - + {% if global_stats.sms.failed %} {% if failure_link %} From 4d06c9d389067e099375ba3ef35d2d21694a1965 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 23:11:19 +0000 Subject: [PATCH 43/53] Bump wtforms from 3.1.1 to 3.1.2 Bumps [wtforms](https://github.com/wtforms/wtforms) from 3.1.1 to 3.1.2. - [Release notes](https://github.com/wtforms/wtforms/releases) - [Changelog](https://github.com/wtforms/wtforms/blob/master/CHANGES.rst) - [Commits](https://github.com/wtforms/wtforms/compare/3.1.1...3.1.2) --- updated-dependencies: - dependency-name: wtforms dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8571215ff..022d9c5ec 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3055,13 +3055,13 @@ watchdog = ["watchdog (>=2.3)"] [[package]] name = "wtforms" -version = "3.1.1" +version = "3.1.2" description = "Form validation and rendering for Python web development." optional = false python-versions = ">=3.8" files = [ - {file = "wtforms-3.1.1-py3-none-any.whl", hash = "sha256:ae7c54b29806c70f7bce8eb9f24afceb10ca5c32af3d9f04f74d2f66ccc5c7e0"}, - {file = "wtforms-3.1.1.tar.gz", hash = "sha256:5e51df8af9a60f6beead75efa10975e97768825a82146a65c7cbf5b915990620"}, + {file = "wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07"}, + {file = "wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9"}, ] [package.dependencies] @@ -3126,4 +3126,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "b4223b62fe62c0dca55cafab817f7527081865b6f1e1c0a8c306c3eb0332b1e9" +content-hash = "8676ac8b4734f4b786f02abb6eb9740426fbb6ef74530d5c76b08271a6f9a4c1" From 12b8b1ce9c7be62b847609494348e7ab2a835208 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:14:29 +0000 Subject: [PATCH 44/53] Bump gitpython from 3.1.40 to 3.1.41 Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.40 to 3.1.41. - [Release notes](https://github.com/gitpython-developers/GitPython/releases) - [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) - [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.40...3.1.41) --- updated-dependencies: - dependency-name: gitpython dependency-type: indirect ... Signed-off-by: dependabot[bot] --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 022d9c5ec..9b1b3528c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -928,20 +928,20 @@ smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.40" +version = "3.1.41" description = "GitPython is a Python library used to interact with Git repositories" optional = false python-versions = ">=3.7" files = [ - {file = "GitPython-3.1.40-py3-none-any.whl", hash = "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a"}, - {file = "GitPython-3.1.40.tar.gz", hash = "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4"}, + {file = "GitPython-3.1.41-py3-none-any.whl", hash = "sha256:c36b6634d069b3f719610175020a9aed919421c87552185b085e04fbbdb10b7c"}, + {file = "GitPython-3.1.41.tar.gz", hash = "sha256:ed66e624884f76df22c8e16066d567aaa5a37d5b5fa19db2c6df6f7156db9048"}, ] [package.dependencies] gitdb = ">=4.0.1,<5" [package.extras] -test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-sugar"] +test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "sumtypes"] [[package]] name = "govuk-bank-holidays" From 8d6e455d18ff52ae5778f95262aa4845f167c695 Mon Sep 17 00:00:00 2001 From: Carlo Costino Date: Wed, 10 Jan 2024 13:23:19 -0500 Subject: [PATCH 45/53] Update utils to 0.2.5 This changeset updates the notification-utils library to 0.2.5. Signed-off-by: Carlo Costino --- poetry.lock | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9b1b3528c..883b4de67 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1456,16 +1456,6 @@ files = [ {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-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-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"}, @@ -1728,7 +1718,7 @@ requests = ">=2.0.0" [[package]] name = "notifications-utils" -version = "0.2.4" +version = "0.2.5" description = "" optional = false python-versions = ">=3.9,<3.12" @@ -1780,7 +1770,7 @@ werkzeug = "^3.0.1" type = "git" url = "https://github.com/GSA/notifications-utils.git" reference = "HEAD" -resolved_reference = "bd604dc32ea80b5d8a1157b09653e4bd4a755a6e" +resolved_reference = "4d18d2c333811fa8c2f8440feca050c21c85f7ff" [[package]] name = "numpy" From f0e667b3b5c7ff6d9631a569772def6dcccb319f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 00:06:38 +0000 Subject: [PATCH 46/53] Bump markdown from 3.5.1 to 3.5.2 Bumps [markdown](https://github.com/Python-Markdown/markdown) from 3.5.1 to 3.5.2. - [Release notes](https://github.com/Python-Markdown/markdown/releases) - [Changelog](https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md) - [Commits](https://github.com/Python-Markdown/markdown/compare/3.5.1...3.5.2) --- updated-dependencies: - dependency-name: markdown dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 18 ++++++++++++++---- pyproject.toml | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 883b4de67..1cc8d3c16 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1389,13 +1389,13 @@ restructuredtext = ["rst2ansi"] [[package]] name = "markdown" -version = "3.5.1" +version = "3.5.2" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.8" files = [ - {file = "Markdown-3.5.1-py3-none-any.whl", hash = "sha256:5874b47d4ee3f0b14d764324d2c94c03ea66bee56f2d929da9f2508d65e722dc"}, - {file = "Markdown-3.5.1.tar.gz", hash = "sha256:b65d7beb248dc22f2e8a31fb706d93798093c308dc1aba295aedeb9d41a813bd"}, + {file = "Markdown-3.5.2-py3-none-any.whl", hash = "sha256:d43323865d89fc0cb9b20c75fc8ad313af307cc087e84b657d9eec768eddeadd"}, + {file = "Markdown-3.5.2.tar.gz", hash = "sha256:e1ac7b3dc550ee80e602e71c1d168002f062e49f1b11e26a36264dafd4df2ef8"}, ] [package.dependencies] @@ -1456,6 +1456,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-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {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-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"}, @@ -3116,4 +3126,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.12" -content-hash = "8676ac8b4734f4b786f02abb6eb9740426fbb6ef74530d5c76b08271a6f9a4c1" +content-hash = "6f9697c8f58f1d17b4bc28f0ed908c4c1a327a2f4eeafbdf7374692408e9d682" diff --git a/pyproject.toml b/pyproject.toml index 4f06f14c7..881eb9163 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ pytz = "==2023.3.post1" rtreelib = "==0.2.0" werkzeug = "^3.0.1" wtforms = "~=3.1" -markdown = "^3.5.1" +markdown = "^3.5.2" [tool.poetry.group.dev.dependencies] From fa0d1e20d1913b6f8bac85d870a282fc2b9968a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 14:21:14 +0000 Subject: [PATCH 47/53] Bump jinja2 from 3.1.2 to 3.1.3 Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3) --- updated-dependencies: - dependency-name: jinja2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1cc8d3c16..278d9404d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1187,13 +1187,13 @@ files = [ [[package]] name = "jinja2" -version = "3.1.2" +version = "3.1.3" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, ] [package.dependencies] From c57e4b935599a866470b8cfa764748cb4c38193a Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Thu, 11 Jan 2024 12:43:49 -0500 Subject: [PATCH 48/53] Adding a template to create a User Story issue --- .github/ISSUE_TEMPLATE/issue_template.yaml | 78 ++++++++++++++++++++++ app/__init__.py | 2 +- app/formatters.py | 11 ++- app/main/views/index.py | 16 +++-- tests/app/main/test_formatters.py | 13 +++- 5 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/issue_template.yaml diff --git a/.github/ISSUE_TEMPLATE/issue_template.yaml b/.github/ISSUE_TEMPLATE/issue_template.yaml new file mode 100644 index 000000000..b4e324e6b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue_template.yaml @@ -0,0 +1,78 @@ +name: "User Story Template" + +about: "Use this template for creating user stories." + +title: "User Story: [Brief description of the user story]" + +labels: + - "Type: User Story" + +body: + - type: markdown + attributes: + value: '**User Story:**' + - type: textarea + id: userType + attributes: + label: "As a [type of user]," + description: "Describe the type of user involved in this story." + validations: + required: true + - type: textarea + id: actionFeature + attributes: + label: "I want [an action or feature]," + description: "Describe the desired action or feature from the user's perspective." + validations: + required: true + - type: textarea + id: benefitValue + attributes: + label: "So that [benefit or value]." + description: "Describe the benefit or value the user expects from the action or feature." + validations: + required: true + + - type: markdown + attributes: + value: '**Acceptance Criteria:**' + - type: textarea + id: acceptanceCriteria + attributes: + label: "Detailed condition or criteria that must be met for the user story to be considered complete." + description: "List the acceptance criteria for the user story." + validations: + required: true + + - type: markdown + attributes: + value: '**Tasks:**' + - type: textarea + id: tasks + attributes: + label: "List of specific tasks or sub-tasks that need to be done to implement the user story." + description: "Outline the tasks necessary to implement the user story." + validations: + required: true + + - type: markdown + attributes: + value: '**Dependencies:**' + - type: textarea + id: dependencies + attributes: + label: "List any dependencies that need to be resolved before starting or completing this user story." + description: "Specify any dependencies related to the user story." + validations: + required: false + + - type: markdown + attributes: + value: '**Notes:**' + - type: textarea + id: notes + attributes: + label: "Any additional information or context that might be useful for the team." + description: "Provide any extra notes or context for the user story." + validations: + required: false diff --git a/app/__init__.py b/app/__init__.py index 322a12210..9ec056c2b 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -585,7 +585,7 @@ def add_template_filters(application): format_mobile_network, format_yes_no, square_metres_to_square_miles, - convert_markdown_template + convert_markdown_template, ]: application.add_template_filter(fn) diff --git a/app/formatters.py b/app/formatters.py index ec3075e6c..86c187f55 100644 --- a/app/formatters.py +++ b/app/formatters.py @@ -26,18 +26,16 @@ from app.utils.time import parse_naive_dt def apply_html_class(tags, html_file): - new_html = html_file for tag in tags: - element = tag[0] class_name = tag[1] - soup = BeautifulSoup(new_html, 'html.parser') + soup = BeautifulSoup(new_html, "html.parser") for xtag in soup.find_all(element): - xtag['class'] = class_name + xtag["class"] = class_name new_html = str(soup) @@ -45,12 +43,11 @@ def apply_html_class(tags, html_file): def convert_markdown_template(mdf, test=False): - content_text = "" if not test: - APP_ROOT = get_root_path('notifications-admin') - file = 'app/content/' + mdf + '.md' + APP_ROOT = get_root_path("notifications-admin") + file = "app/content/" + mdf + ".md" md_file = os.path.join(APP_ROOT, file) with open(md_file) as f: content_text = f.read() diff --git a/app/main/views/index.py b/app/main/views/index.py index ef5c1a5da..f4e3a67db 100644 --- a/app/main/views/index.py +++ b/app/main/views/index.py @@ -138,16 +138,20 @@ def get_started_old(): @main.route("/using-notify/get-started") @user_is_logged_in def get_started(): - markdown = convert_markdown_template('get-started') - html_style = apply_html_class([['ol', 'usa-process-list'], - ['li', 'usa-process-list__item padding-bottom-4 margin-top-2'], - ['h2', 'usa-process-list__heading line-height-sans-3']], - markdown) + markdown = convert_markdown_template("get-started") + html_style = apply_html_class( + [ + ["ol", "usa-process-list"], + ["li", "usa-process-list__item padding-bottom-4 margin-top-2"], + ["h2", "usa-process-list__heading line-height-sans-3"], + ], + markdown, + ) return render_template( "views/get-started.html", navigation_links=using_notify_nav(), - content=html_style + content=html_style, ) diff --git a/tests/app/main/test_formatters.py b/tests/app/main/test_formatters.py index 81e78ed0c..b9fd7f975 100644 --- a/tests/app/main/test_formatters.py +++ b/tests/app/main/test_formatters.py @@ -174,16 +174,23 @@ def test_format_delta(): def test_jinja_format(fake_jinja_template): app = Flask("app") with app.app_context(): - assert convert_markdown_template(fake_jinja_template, test=True) == "

True

" + assert ( + convert_markdown_template(fake_jinja_template, test=True) == "

True

" + ) @pytest.mark.usefixtures("fake_markdown_file") def test_markdown_format(fake_markdown_file): app = Flask("app") with app.app_context(): - assert convert_markdown_template(fake_markdown_file, test=True) == "

Test

" + assert ( + convert_markdown_template(fake_markdown_file, test=True) == "

Test

" + ) @pytest.mark.usefixtures("fake_soup_template") def test_soup_format(fake_soup_template): - assert apply_html_class([['h1', 'testClass']], fake_soup_template) == '

Test

' + assert ( + apply_html_class([["h1", "testClass"]], fake_soup_template) + == '

Test

' + ) From a2ca10a6c51d5c2fc7361676154fa8c03c759c34 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Thu, 11 Jan 2024 12:52:35 -0500 Subject: [PATCH 49/53] About wasn't a permitted key --- .github/ISSUE_TEMPLATE/issue_template.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/issue_template.yaml b/.github/ISSUE_TEMPLATE/issue_template.yaml index b4e324e6b..bbd6bab28 100644 --- a/.github/ISSUE_TEMPLATE/issue_template.yaml +++ b/.github/ISSUE_TEMPLATE/issue_template.yaml @@ -1,6 +1,6 @@ name: "User Story Template" -about: "Use this template for creating user stories." +description: "Use this template for creating user stories." title: "User Story: [Brief description of the user story]" From 6034c7e54e73f7b7eeca4525be92767e72f6d79d Mon Sep 17 00:00:00 2001 From: Emily Herrick <91496588+em-herrick@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:31:37 -0500 Subject: [PATCH 50/53] Add files via upload --- docs/FCC RND Best Practices.pdf | Bin 0 -> 79017 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/FCC RND Best Practices.pdf diff --git a/docs/FCC RND Best Practices.pdf b/docs/FCC RND Best Practices.pdf new file mode 100644 index 0000000000000000000000000000000000000000..07cecf4b86699fec103090f59e24aa12dfd4126d GIT binary patch literal 79017 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 Date: Thu, 11 Jan 2024 13:51:06 -0500 Subject: [PATCH 51/53] Adding a config --- .github/ISSUE_TEMPLATE/config.yml | 1 + .../{issue_template.yaml => issue_template.yml} | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/config.yml rename .github/ISSUE_TEMPLATE/{issue_template.yaml => issue_template.yml} (97%) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..0086358db --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: true diff --git a/.github/ISSUE_TEMPLATE/issue_template.yaml b/.github/ISSUE_TEMPLATE/issue_template.yml similarity index 97% rename from .github/ISSUE_TEMPLATE/issue_template.yaml rename to .github/ISSUE_TEMPLATE/issue_template.yml index bbd6bab28..576af0095 100644 --- a/.github/ISSUE_TEMPLATE/issue_template.yaml +++ b/.github/ISSUE_TEMPLATE/issue_template.yml @@ -1,7 +1,5 @@ name: "User Story Template" - -description: "Use this template for creating user stories." - +description: "Use this template for creating user stories" title: "User Story: [Brief description of the user story]" labels: From e5c2bd9ef239943681f753334ad57c81d479dee8 Mon Sep 17 00:00:00 2001 From: Carlo Costino Date: Fri, 12 Jan 2024 12:24:54 -0500 Subject: [PATCH 52/53] Update notification-utils to 0.2.6 This changeset updates notification-utils to 0.2.6 for dependency updates. Signed-off-by: Carlo Costino --- poetry.lock | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/poetry.lock b/poetry.lock index 278d9404d..d45a29a21 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1456,16 +1456,6 @@ files = [ {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-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-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"}, @@ -1728,7 +1718,7 @@ requests = ">=2.0.0" [[package]] name = "notifications-utils" -version = "0.2.5" +version = "0.2.6" description = "" optional = false python-versions = ">=3.9,<3.12" @@ -1753,7 +1743,7 @@ geojson = "^3.0.1" govuk-bank-holidays = "^0.13" idna = "^3.4" itsdangerous = "^2.1.2" -jinja2 = "^3.1.2" +jinja2 = "^3.1.3" jmespath = "^1.0.1" markupsafe = "^2.1.2" mistune = "==0.8.4" @@ -1780,7 +1770,7 @@ werkzeug = "^3.0.1" type = "git" url = "https://github.com/GSA/notifications-utils.git" reference = "HEAD" -resolved_reference = "4d18d2c333811fa8c2f8440feca050c21c85f7ff" +resolved_reference = "f183d120a8b86e655405694adde1f0d95e4e5a51" [[package]] name = "numpy" From e500ec567e6640a2e9fb6be98291346e85b2d491 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 17:38:22 +0000 Subject: [PATCH 53/53] Bump pip-audit from 2.6.3 to 2.7.0 Bumps [pip-audit](https://github.com/pypa/pip-audit) from 2.6.3 to 2.7.0. - [Release notes](https://github.com/pypa/pip-audit/releases) - [Changelog](https://github.com/pypa/pip-audit/blob/main/CHANGELOG.md) - [Commits](https://github.com/pypa/pip-audit/compare/v2.6.3...v2.7.0) --- updated-dependencies: - dependency-name: pip-audit dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index d45a29a21..2efe9f375 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1456,6 +1456,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-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {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-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"}, @@ -1929,13 +1939,13 @@ pip = "*" [[package]] name = "pip-audit" -version = "2.6.3" +version = "2.7.0" description = "A tool for scanning Python environments for known vulnerabilities" optional = false python-versions = ">=3.8" files = [ - {file = "pip_audit-2.6.3-py3-none-any.whl", hash = "sha256:216983210db4a15393f9e80e4d24a805f5767e4c8e0c31fc70c336acc629613b"}, - {file = "pip_audit-2.6.3.tar.gz", hash = "sha256:bd796066f69684b2f4fc2c2b6d222589e23190db0bbde069cea5c2b0be2cc57d"}, + {file = "pip_audit-2.7.0-py3-none-any.whl", hash = "sha256:83e039740653eb9ef1a78b1540ed441600cd88a560588ba2c0a169180685a522"}, + {file = "pip_audit-2.7.0.tar.gz", hash = "sha256:67740c5b1d5d967a258c3dfefc46f9713a2819c48062505ddf4b29de101c2b75"}, ] [package.dependencies]