Merge and push back up

This commit is contained in:
Jonathan Bobel
2023-11-02 14:40:08 -04:00
33 changed files with 600 additions and 383 deletions
+10 -2
View File
@@ -15,7 +15,7 @@ NVMSH := $(shell [ -f "$(HOME)/.nvm/nvm.sh" ] && echo "$(HOME)/.nvm/nvm.sh" || e
.PHONY: bootstrap .PHONY: bootstrap
bootstrap: generate-version-file ## Set up everything to run the app bootstrap: generate-version-file ## Set up everything to run the app
poetry install poetry install --sync
poetry run playwright install --with-deps poetry run playwright install --with-deps
source $(NVMSH) --no-use && nvm install && npm ci --no-audit source $(NVMSH) --no-use && nvm install && npm ci --no-audit
source $(NVMSH) && npm run build source $(NVMSH) && npm run build
@@ -95,6 +95,14 @@ fix-imports: ## Fix imports using isort
.PHONY: py-lock .PHONY: py-lock
py-lock: ## Syncs dependencies and updates lock file without performing recursive internal updates py-lock: ## Syncs dependencies and updates lock file without performing recursive internal updates
poetry lock --no-update poetry lock --no-update
poetry install --sync
.PHONY: update-utils
update-utils: ## Forces Poetry to pull the latest changes from the notifications-utils repo; requires that you commit the changes to poetry.lock!
poetry update notifications-utils
@echo
@echo !!! PLEASE MAKE SURE TO COMMIT AND PUSH THE UPDATED poetry.lock FILE !!!
@echo
.PHONY: freeze-requirements .PHONY: freeze-requirements
freeze-requirements: ## create static requirements.txt freeze-requirements: ## create static requirements.txt
@@ -105,7 +113,7 @@ pip-audit:
poetry requirements > requirements.txt poetry requirements > requirements.txt
poetry requirements --dev > requirements_for_test.txt poetry requirements --dev > requirements_for_test.txt
poetry run pip-audit -r requirements.txt poetry run pip-audit -r requirements.txt
-poetry run pip-audit -r requirements_for_test.txt poetry run pip-audit -r requirements_for_test.txt
.PHONY: audit .PHONY: audit
audit: npm-audit pip-audit audit: npm-audit pip-audit
+17
View File
@@ -102,6 +102,23 @@ In either situation, once you are finished and have verified the dependency
changes are working, please be sure to commit both the `pyproject.toml` and changes are working, please be sure to commit both the `pyproject.toml` and
`poetry.lock` files. `poetry.lock` files.
### Keeping the notification-utils dependency up-to-date
The `notifications-utils` dependency references the other repository we have at
https://github.com/GSA/notifications-utils - this dependency requires a bit of
extra legwork to ensure it stays up-to-date.
Whenever a PR is merged in the `notifications-utils` repository, we need to make
sure the changes are pulled in here and committed to this repository as well.
You can do this by going through these steps:
- Make sure your local `main` branch is up-to-date
- Create a new branch to work in
- Run `make update-utils`
- Commit the updated `poetry.lock` file and push the changes
- Make a new PR with the change
- Have the PR get reviewed and merged
## To test the application ## To test the application
From a terminal within the running devcontainer: From a terminal within the running devcontainer:
+1 -1
View File
@@ -227,7 +227,7 @@ def terms():
) )
@main.route("/features/using-notify") @main.route("/features/using_notify")
@user_is_logged_in @user_is_logged_in
def using_notify(): def using_notify():
return ( return (
+76
View File
@@ -61,6 +61,82 @@ class HeaderNavigation(Navigation):
"message_status", "message_status",
"guidance_index", "guidance_index",
}, },
"accounts-or-dashboard": {
"conversation",
"inbox",
"monthly",
"service_dashboard",
"template_usage",
"view_notification",
"view_notifications",
"action_blocked",
"add_service_template",
"check_messages",
"check_notification",
"choose_template",
"choose_template_to_copy",
"confirm_redact_template",
"conversation_reply",
"copy_template",
"delete_service_template",
"edit_service_template",
"manage_template_folder",
"send_messages",
"send_one_off",
"send_one_off_step",
"send_one_off_to_myself",
"set_sender",
"set_template_sender",
"view_template",
"view_template_version",
"view_template_versions",
"uploads",
"view_job",
"view_jobs",
"confirm_edit_user_email",
"confirm_edit_user_mobile_number",
"edit_user_email",
"edit_user_mobile_number",
"edit_user_permissions",
"invite_user",
"manage_users",
"remove_user_from_service",
"usage",
"email_branding_govuk",
"email_branding_govuk_and_org",
"email_branding_organization",
"email_branding_request",
"email_branding_something_else",
"estimate_usage",
"link_service_to_organization",
"request_to_go_live",
"service_add_email_reply_to",
"service_add_sms_sender",
"service_confirm_delete_email_reply_to",
"service_confirm_delete_sms_sender",
"service_edit_email_reply_to",
"service_edit_sms_sender",
"service_email_reply_to",
"service_name_change",
"service_preview_email_branding",
"service_set_auth_type",
"service_set_channel",
"send_files_by_email_contact_details",
"service_set_email_branding",
"service_set_inbound_number",
"service_set_inbound_sms",
"service_set_international_sms",
"service_set_reply_to_email",
"service_set_sms_prefix",
"service_verify_reply_to_address",
"service_verify_reply_to_address_updates",
"service_settings",
"service_sms_senders",
"set_free_sms_allowance",
"set_message_limit",
"set_rate_limit",
"submit_request_to_go_live",
},
"pricing": { "pricing": {
"how_to_pay", "how_to_pay",
"billing_details", "billing_details",
+11 -1
View File
@@ -43,6 +43,11 @@
{% if current_user.is_authenticated %} {% if current_user.is_authenticated %}
{% if current_user.platform_admin %} {% if current_user.platform_admin %}
{% set navigation = [ {% set navigation = [
{
"href": url_for("main.show_accounts_or_dashboard"),
"text": "Current service",
"active": header_navigation.is_selected('accounts-or-dashboard')
},
{ {
"href": url_for('main.get_started'), "href": url_for('main.get_started'),
"text": "Using Notify", "text": "Using Notify",
@@ -75,6 +80,11 @@
] %} ] %}
{% else %} {% else %}
{% set navigation = [ {% set navigation = [
{
"href": url_for("main.show_accounts_or_dashboard"),
"text": "Current service",
"active": header_navigation.is_selected('accounts-or-dashboard')
},
{ {
"href": url_for('main.get_started'), "href": url_for('main.get_started'),
"text": "Using Notify", "text": "Using Notify",
@@ -92,7 +102,7 @@
}, },
{ {
"href": url_for('main.user_profile'), "href": url_for('main.user_profile'),
"text": current_user.name, "text": "User profile",
"active": header_navigation.is_selected('user-profile') "active": header_navigation.is_selected('user-profile')
}, },
{ {
+2 -8
View File
@@ -4,16 +4,10 @@
<div class="grid-row"> <div class="grid-row">
<div class="grid-col-8"> <div class="grid-col-8">
<h1 class="heading-large"> <h1 class="heading-large">
Sorry, theres a problem with Notify.gov Sorry, we can't deliver what you asked for right now.
</h1> </h1>
<p class="usa-body"> <p class="usa-body">
Try again later. Please try again later or <a class="usa-link" href="mailto:notify-support@gsa.gov"></a>email us</a> for more information.</p>
</p>
<!-- <p class="usa-body">
You can check our <a class="usa-link" href="https://status.notifications.service.gov.uk">system status</a> page to see if there are any known issues.
</p> -->
<p class="usa-body">
To report a problem, please email <a class="usa-link" href="mailto:notify-support@gsa.gov">notify-support@gsa.gov</a>.
</p> </p>
</div> </div>
</div> </div>
+4 -2
View File
@@ -1,13 +1,15 @@
{% if help %} {% if help %}
{% include 'partials/tour.html' %} {% include 'partials/tour.html' %}
{% else %} {% else %}
<nav class="nav margin-bottom-5"> <nav class="nav">
<a class="usa-button margin-top-1 margin-bottom-5 width-full"
href="{{ url_for('.choose_template', service_id=current_service.id) }}">Send messages</a>
<ul class="usa-sidenav"> <ul class="usa-sidenav">
{% if current_user.has_permissions() %} {% if current_user.has_permissions() %}
{% if current_user.has_permissions('view_activity') %} {% if current_user.has_permissions('view_activity') %}
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('dashboard') }}" href="{{ url_for('.service_dashboard', service_id=current_service.id) }}">Dashboard</a></li> <li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('dashboard') }}" href="{{ url_for('.service_dashboard', service_id=current_service.id) }}">Dashboard</a></li>
{% endif %} {% endif %}
<li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('templates') }}" href="{{ url_for('.choose_template', service_id=current_service.id) }}">Send messages</a></li> {# <li class="usa-sidenav__item"><a class="{{ main_navigation.is_selected('templates') }}" href="{{ url_for('.choose_template', service_id=current_service.id) }}">Send messages</a></li> #}
{% if not current_user.has_permissions('view_activity') %} {% if not current_user.has_permissions('view_activity') %}
<li class="usa-sidenav__item"><a class="{{ casework_navigation.is_selected('sent-messages') }}" href="{{ url_for('.view_notifications', service_id=current_service.id, status='sending,delivered,failed') }}">Sent messages</a></li> <li class="usa-sidenav__item"><a class="{{ casework_navigation.is_selected('sent-messages') }}" href="{{ url_for('.view_notifications', service_id=current_service.id, status='sending,delivered,failed') }}">Sent messages</a></li>
{% endif %} {% endif %}
+1 -1
View File
@@ -7,7 +7,7 @@
</div> </div>
{% endmacro %} {% endmacro %}
<div class="navigation-service margin-top-2 display-flex flex-align-end flex-justify border-bottom padding-bottom-1"> <div class="navigation-service margin-top-5 display-flex flex-align-end flex-justify border-bottom padding-bottom-1">
{% if current_service.organization_id %} {% if current_service.organization_id %}
{% if current_user.platform_admin or {% if current_user.platform_admin or
(current_user.belongs_to_organization(current_service.organization_id) and current_service.live) %} (current_user.belongs_to_organization(current_service.organization_id) and current_service.live) %}
@@ -1,4 +1,4 @@
<h2 class="font-body-lg">Get started</h2> <h2 class="font-body-lg margin-top-0 margin-bottom-1">Get started</h2>
<a class="usa-button" href="{{ url_for('.choose_template', service_id=current_service.id) }}"> <a class="usa-button margin-bottom-5" href="{{ url_for('.choose_template', service_id=current_service.id) }}">
Create your first template Create your first template
</a> </a>
+3 -3
View File
@@ -3,16 +3,16 @@
{% from "components/table.html" import mapping_table, row, text_field, optional_text_field, edit_field, field, boolean_field with context %} {% from "components/table.html" import mapping_table, row, text_field, optional_text_field, edit_field, field, boolean_field with context %}
{% block per_page_title %} {% block per_page_title %}
Your profile User profile
{% endblock %} {% endblock %}
{% block maincolumn_content %} {% block maincolumn_content %}
<h1 class="font-body-2xl margin-bottom-3">Your profile</h1> <h1 class="font-body-2xl margin-bottom-3">User profile</h1>
<div class="body-copy-table"> <div class="body-copy-table">
{% call mapping_table( {% call mapping_table(
caption='Your profile', caption='User profile',
field_headings_visible=False, field_headings_visible=False,
caption_visible=False caption_visible=False
) %} ) %}
+2 -2
View File
@@ -4,9 +4,9 @@
{% block beforeContent %} {% block beforeContent %}
{% if current_service and current_service.active and current_user.is_authenticated and current_user.belongs_to_service(current_service.id) %} {% if current_service and current_service.active and current_user.is_authenticated and current_user.belongs_to_service(current_service.id) %}
<div class="navigation-service usa-breadcrumb"> <!-- <div class="navigation-service usa-breadcrumb">
<a href="{{ url_for('main.show_accounts_or_dashboard') }}" class="usa-link usa-breadcrumb__link usa-breadcrumb-back-to">Back to {{ current_service.name }}</a> <a href="{{ url_for('main.show_accounts_or_dashboard') }}" class="usa-link usa-breadcrumb__link usa-breadcrumb-back-to">Back to {{ current_service.name }}</a>
</div> </div> -->
{% endif %} {% endif %}
{% block backLink %}{% endblock %} {% block backLink %}{% endblock %}
{% endblock %} {% endblock %}
+23 -1
View File
@@ -1,6 +1,28 @@
# Notify Sprint Goals Log # Notify Sprint Goals Log
## Sprint: T (9/28/23) ## Sprint: V (10/30/23)
| | Goals | Impact |
|-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| Engineering | Continue login.gov [sandbox implementation](https://github.com/GSA/notifications-admin/issues/338), catch up deploys that lag from last week's dependency audit failures, change timezones displays to [Eastern time](https://github.com/GSA/notifications-admin/issues/861), Persist [individal send reports](https://github.com/GSA/notifications-admin/issues/855) somwehere in the app| Stronger auth security, streamlined UX, better timezone familiarity |
| UX | Continue making common-sense [UI/UX changes](https://github.com/GSA/notifications-admin/issues/828), review and finalize proposal for [Notify logo](https://github.com/GSA/notifications-admin/issues/859) & begin approvals chain | Improve ease of use, begin process of brand creation |
| Security | Complete pre-requisite documentation, start project planning timelines and control group deadlines | Aim to have package completed with enough time to allow for long assessment|
| Content | Finalize cloud.gov pages IAA mod for content site | Enable an easy static website for future content |
| Ops | Onboard Beverly, get access to tools for them once possible | Add valuable dev resources to increase our capacity
## Sprint: Upupa Marginata (10/12/23)
| | Goals | Impact |
|-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| Engineering | Shift the quota count from `service` to `org`, complete [notify.gov redirect](https://github.com/GSA/notifications-api/issues/515), continue login.gov [sandbox implementation](https://github.com/GSA/notifications-admin/issues/338), meet with AWS to gain answers on opt-out capabilities| Stronger auth security, streamlined UX, operational efficiency |
| UX | Make common-sense [UI/UX changes](https://github.com/GSA/notifications-admin/issues/828), Complete proposal for [Notify logo](https://github.com/GSA/notifications-admin/issues/859), switch application to Eastern timezone displays | Improve ease of use, begin process of brand creation |
| Security | Complete pre-requisite documentation, start project planning timelines and control group deadlines | Aim to have package completed with enough time to allow for long assessment|
| Content | Work on cloud.gov pages IAA mod for content site | Enable an easy static website for future content |
| Ops | Onboard new back-end dev, get access to tools for them once possible | Add valuable dev resources to increase our capacity
## Sprint: Toucan (9/28/23)
| | Goals | Impact | | | Goals | Impact |
|-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------| |-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
Generated
+277 -158
View File
@@ -124,13 +124,13 @@ uvloop = ["uvloop (>=0.15.2)"]
[[package]] [[package]]
name = "bleach" name = "bleach"
version = "6.0.0" version = "6.1.0"
description = "An easy safelist-based HTML-sanitizing tool." description = "An easy safelist-based HTML-sanitizing tool."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.8"
files = [ files = [
{file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"},
{file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"},
] ]
[package.dependencies] [package.dependencies]
@@ -138,17 +138,17 @@ six = ">=1.9.0"
webencodings = "*" webencodings = "*"
[package.extras] [package.extras]
css = ["tinycss2 (>=1.1.0,<1.2)"] css = ["tinycss2 (>=1.1.0,<1.3)"]
[[package]] [[package]]
name = "blinker" name = "blinker"
version = "1.6.3" version = "1.7.0"
description = "Fast, simple object-to-object and broadcast signaling" description = "Fast, simple object-to-object and broadcast signaling"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.8"
files = [ files = [
{file = "blinker-1.6.3-py3-none-any.whl", hash = "sha256:296320d6c28b006eb5e32d4712202dbcdcbf5dc482da298c2f44881c43884aaa"}, {file = "blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9"},
{file = "blinker-1.6.3.tar.gz", hash = "sha256:152090d27c1c5c722ee7e48504b02d76502811ce02e1523553b4cf8c8b3d3a8d"}, {file = "blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182"},
] ]
[[package]] [[package]]
@@ -164,38 +164,41 @@ files = [
[[package]] [[package]]
name = "boto3" name = "boto3"
version = "1.28.52" version = "1.28.75"
description = "The AWS SDK for Python" description = "The AWS SDK for Python"
optional = false optional = false
python-versions = ">= 3.7" python-versions = ">= 3.7"
files = [ files = [
{file = "boto3-1.28.52-py3-none-any.whl", hash = "sha256:1d36db102517d62c6968b3b0636303241f56859d12dd071def4882fc6e030b20"}, {file = "boto3-1.28.75-py3-none-any.whl", hash = "sha256:b959decd588982bc919bfcbebc7916926b05003a0093e7f2845362da4f5dd9fc"},
{file = "boto3-1.28.52.tar.gz", hash = "sha256:a34fc153cb2f6fb2f79a764286c967392e8aae9412381d943bddc576c4f7631a"}, {file = "boto3-1.28.75.tar.gz", hash = "sha256:63d772a784e8e35ee51974eb1c20dff5faa51b007d22c5647783f18966bf4042"},
] ]
[package.dependencies] [package.dependencies]
botocore = ">=1.31.52,<1.32.0" botocore = ">=1.31.75,<1.32.0"
jmespath = ">=0.7.1,<2.0.0" jmespath = ">=0.7.1,<2.0.0"
s3transfer = ">=0.6.0,<0.7.0" s3transfer = ">=0.7.0,<0.8.0"
[package.extras] [package.extras]
crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
[[package]] [[package]]
name = "botocore" name = "botocore"
version = "1.31.52" version = "1.31.75"
description = "Low-level, data-driven core of boto 3." description = "Low-level, data-driven core of boto 3."
optional = false optional = false
python-versions = ">= 3.7" python-versions = ">= 3.7"
files = [ files = [
{file = "botocore-1.31.52-py3-none-any.whl", hash = "sha256:46b0a75a38521aa6a75fddccb1542e002930e609d4e13516f40fef170d32e515"}, {file = "botocore-1.31.75-py3-none-any.whl", hash = "sha256:fa078c4aa9a5777b3ede756540e62fec551e13d39cf7abf9a37bb81981496d68"},
{file = "botocore-1.31.52.tar.gz", hash = "sha256:6d09881c5a8be34b497872ca3936f8757d886a6f42f2a8703411928189cfedc0"}, {file = "botocore-1.31.75.tar.gz", hash = "sha256:d704ea9867b2227de0350bc2a5ca2543349e164ecb5d15edbfacbb05f2056482"},
] ]
[package.dependencies] [package.dependencies]
jmespath = ">=0.7.1,<2.0.0" jmespath = ">=0.7.1,<2.0.0"
python-dateutil = ">=2.1,<3.0.0" python-dateutil = ">=2.1,<3.0.0"
urllib3 = ">=1.25.4,<1.27" urllib3 = [
{version = ">=1.25.4,<1.27", markers = "python_version < \"3.10\""},
{version = ">=1.25.4,<2.1", markers = "python_version >= \"3.10\""},
]
[package.extras] [package.extras]
crt = ["awscrt (==0.16.26)"] crt = ["awscrt (==0.16.26)"]
@@ -245,75 +248,63 @@ files = [
[[package]] [[package]]
name = "cffi" name = "cffi"
version = "1.15.1" version = "1.16.0"
description = "Foreign Function Interface for Python calling C code." description = "Foreign Function Interface for Python calling C code."
optional = false optional = false
python-versions = "*" python-versions = ">=3.8"
files = [ files = [
{file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"},
{file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"},
{file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"},
{file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"},
{file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"},
{file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"},
{file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"},
{file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"},
{file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"},
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"},
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"},
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"},
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"},
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"},
{file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"},
{file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"},
{file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"},
{file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"},
{file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"},
{file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"},
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"},
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"},
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"},
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"},
{file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"},
{file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"},
{file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"},
{file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"},
{file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"},
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"},
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"},
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"},
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"},
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"},
{file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"},
{file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"},
{file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"},
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"},
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"},
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"},
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"},
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"},
{file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"},
{file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"},
{file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"},
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"},
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"},
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"},
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"},
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"},
{file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"},
{file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"},
{file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"},
{file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"},
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"},
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"},
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"},
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"},
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"},
{file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"},
{file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"},
{file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"},
{file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"},
{file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"},
] ]
[package.dependencies] [package.dependencies]
@@ -866,13 +857,13 @@ python-dateutil = ">=2.7"
[[package]] [[package]]
name = "geojson" name = "geojson"
version = "2.5.0" version = "3.0.1"
description = "Python bindings and utilities for GeoJSON" description = "Python bindings and utilities for GeoJSON"
optional = false optional = false
python-versions = "*" python-versions = ">=3.7, <3.12"
files = [ files = [
{file = "geojson-2.5.0-py2.py3-none-any.whl", hash = "sha256:ccbd13368dd728f4e4f13ffe6aaf725b6e802c692ba0dde628be475040c534ba"}, {file = "geojson-3.0.1-py3-none-any.whl", hash = "sha256:e49df982b204ed481e4c1236c57f587adf71537301cf8faf7120ab27d73c7568"},
{file = "geojson-2.5.0.tar.gz", hash = "sha256:6e4bb7ace4226a45d9c8c8b1348b3fc43540658359f93c3f7e03efa9f15f658a"}, {file = "geojson-3.0.1.tar.gz", hash = "sha256:ff3d75acab60b1e66504a11f7ea12c104bad32ff3c410a807788663b966dee4a"},
] ]
[[package]] [[package]]
@@ -1397,6 +1388,16 @@ files = [
{file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
{file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
{file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
{file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
{file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
{file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
{file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
{file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
{file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
{file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
{file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
@@ -1589,26 +1590,26 @@ files = [
[[package]] [[package]]
name = "newrelic" name = "newrelic"
version = "9.1.0" version = "9.1.1"
description = "New Relic Python Agent" description = "New Relic Python Agent"
optional = false optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
files = [ files = [
{file = "newrelic-9.1.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:1e9ede0fd193b0fec7b0a1b55b8bd81bc51151f80046309a999b3939c32e5820"}, {file = "newrelic-9.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:639abcaa1baee5a1a137036e328617e3a6bbb33a63814ef6227a8059d9062f0d"},
{file = "newrelic-9.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:08d4b93d3c60518bacd8e69e76dfe488980ab71a74fab24c9a23f429b067c2d5"}, {file = "newrelic-9.1.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:1bd46363c71c3fc5dbcc0e96e1698757f4e7ff82c73a0ccb28f18c2b9f9c5de5"},
{file = "newrelic-9.1.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:434c2a876223daaeb8c1db46cb399319b5f4d554002f17f51572888b35a4a577"}, {file = "newrelic-9.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:fbebaf8d9801eef85827ca2906a7bdbc2a458a226455da49c71857e2ce2b264a"},
{file = "newrelic-9.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4505991bc0e0554482ed4b7cd94486ade521cc7408870f1c89d7b4d65c7ff532"}, {file = "newrelic-9.1.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:c1a91322fdb301a7a17aab8df2e70925c1e2a01a61136d86a0e433f6ff167c5c"},
{file = "newrelic-9.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c92458b80c9a0841acdd50db7a5ba3b6b8d35b2859b0f3c907d2f01a90b6b0e5"}, {file = "newrelic-9.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d677f8f11bd69d92a4b359c53a04e02094e5198ed1aa49c9b1ca235522d5efd5"},
{file = "newrelic-9.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b475ec4b1ac7e7026d7e23d63e6fff2db0c8b5d720f6603faddf78f833459966"}, {file = "newrelic-9.1.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:289cebbb86eb92b6c133e18cd5640115a918db41ae791d11c1ded5b592dd7c23"},
{file = "newrelic-9.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bdcf45a4074b49daabb0e89378f83577dee1aa645ae9b34b86234d8755f3454"}, {file = "newrelic-9.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1b93effe99be14a1747a70e9368274091abbed2ef3c593b08a29732d72d83e4"},
{file = "newrelic-9.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f0add508afc0195631a2d91fd267fe8f63e153b633ec4503edef5019868a762"}, {file = "newrelic-9.1.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45966c5f083d1f1abb76828c4864d20296f6929053fbe4d122e164d84c78e388"},
{file = "newrelic-9.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7aefddec021b1259317e03ddaa6945e0562e96742b79be4f04a6ab845b88121"}, {file = "newrelic-9.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18e8e6af37cc084007913b991bced2ea2b8b31ed5318a397f210a9625c214459"},
{file = "newrelic-9.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf178086cf1a5d1fcfeedff871968c7c0a70f677c84afc6cc2f6ccb6430f3f83"}, {file = "newrelic-9.1.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:437dfae553012dbe6e0f288b1f600ef27b0ebc2c367641723529b1a71fa541ae"},
{file = "newrelic-9.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52c690d9529d208446c0861f28be0b8056e1e5004246b312fb7af59c9f45f694"}, {file = "newrelic-9.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5489becb7cff1ba992405c9d891fd1743e8042910c97f89ac072fd562501cdb1"},
{file = "newrelic-9.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a4b602b131aa7e0795f08a8ec0d1adc5361542222927c156f9a1e8b1eecd09f"}, {file = "newrelic-9.1.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8403b48807eae524ee1b2da254f4222834f3aef8326dd4475f0b22f924774bde"},
{file = "newrelic-9.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:427f8266a450f295b6d28127070a07937946392d433a05ab81528cbe5aae9f51"}, {file = "newrelic-9.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:603158cb23ed6604845e4fc8ee2a052e60003ccbb7da0f4b00667cd0c7c77c11"},
{file = "newrelic-9.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:098717a64be932c70a6145f15a4b73416613bf00b14452b73ef7bae89888475b"}, {file = "newrelic-9.1.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96dedf6c1a385bf7b4b1336b3e4b5a0d6e983b5305022176c7c43d327e768bf3"},
{file = "newrelic-9.1.0.tar.gz", hash = "sha256:29032d57a41b03ff028c5dd7173491f7e21743ed9444f693e0b662007eee3d6a"}, {file = "newrelic-9.1.1.tar.gz", hash = "sha256:968a3662ccfb881498789105a52eec866b57c22b8cbdef43889ad76881c62a95"},
] ]
[package.extras] [package.extras]
@@ -1616,12 +1617,12 @@ infinite-tracing = ["grpcio", "protobuf"]
[[package]] [[package]]
name = "notifications-python-client" name = "notifications-python-client"
version = "8.0.1" version = "8.1.0"
description = "Python API client for GOV.UK Notify." description = "Python API client for GOV.UK Notify."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "notifications_python_client-8.0.1-py3-none-any.whl", hash = "sha256:e89f5ad7caf17065ede88a1c2270c32cc24de75843856e524a2336f952260b4c"}, {file = "notifications_python_client-8.1.0-py3-none-any.whl", hash = "sha256:8aec1f7a4ba592fd699eae899df8ccca9ccafb614f47826c07b318ca903c9c13"},
] ]
[package.dependencies] [package.dependencies]
@@ -1631,39 +1632,59 @@ requests = ">=2.0.0"
[[package]] [[package]]
name = "notifications-utils" name = "notifications-utils"
version = "56.0.3" version = "0.2.0"
description = "Shared python code for Notify applications" description = ""
optional = false optional = false
python-versions = "*" python-versions = ">=3.9,<3.12"
files = [] files = []
develop = true develop = false
[package.dependencies] [package.dependencies]
bleach = ">=4.1.0" async-timeout = "^4.0.2"
boto3 = ">=1.19.4" bleach = "^6.1.0"
cachetools = ">=4.1.1" blinker = "^1.6.2"
cryptography = ">=39.0.1" boto3 = "^1.28.66"
Flask = ">=2.2.2" botocore = "^1.31.66"
Flask-Redis = ">=0.4.0" cachetools = "^5.3.0"
geojson = ">=2.5.0" certifi = "^2023.7.22"
govuk-bank-holidays = ">=0.10" cffi = "^1.16.0"
itsdangerous = ">=1.1.0" charset-normalizer = "^3.1.0"
Jinja2 = ">=2.11.3" click = "^8.1.3"
mistune = "<2.0.0" cryptography = "^41.0.4"
orderedset = ">=2.0.3" flask = "^2.3.2"
phonenumbers = ">=8.13.3" flask-redis = "^0.4.0"
python-json-logger = ">=2.0.1" geojson = "^3.0.1"
pytz = ">=2020.4" govuk-bank-holidays = "^0.13"
pyyaml = ">=5.3.1" idna = "^3.4"
requests = ">=2.25.0" itsdangerous = "^2.1.2"
Shapely = ">=1.8.0" jinja2 = "^3.1.2"
smartypants = ">=2.0.1" jmespath = "^1.0.1"
markupsafe = "^2.1.2"
mistune = "==0.8.4"
numpy = "^1.24.2"
orderedset = "^2.0.3"
phonenumbers = "^8.13.8"
pycparser = "^2.21"
python-dateutil = "^2.8.2"
python-json-logger = "^2.0.7"
pytz = "^2023.3"
pyyaml = "^6.0"
redis = "^5.0.1"
regex = "^2023.10.3"
requests = "^2.31.0"
s3transfer = "^0.7.0"
shapely = "^2.0.1"
six = "^1.16.0"
smartypants = "^2.0.1"
urllib3 = "^1.26.18"
webencodings = "^0.5.1"
werkzeug = "^3.0.1"
[package.source] [package.source]
type = "git" type = "git"
url = "https://github.com/GSA/notifications-utils.git" url = "https://github.com/GSA/notifications-utils.git"
reference = "main" reference = "HEAD"
resolved_reference = "5eadd38702fd187fd2954a5c763314b9b2446bea" resolved_reference = "e8154e0981166b7085638e17503ec169b4c5cf62"
[[package]] [[package]]
name = "numpy" name = "numpy"
@@ -2155,13 +2176,13 @@ certifi = "*"
[[package]] [[package]]
name = "pytest" name = "pytest"
version = "7.4.2" version = "7.4.3"
description = "pytest: simple powerful testing with Python" description = "pytest: simple powerful testing with Python"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"},
{file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"},
] ]
[package.dependencies] [package.dependencies]
@@ -2192,30 +2213,31 @@ requests = ">=2.9"
[[package]] [[package]]
name = "pytest-env" name = "pytest-env"
version = "1.0.1" version = "1.1.1"
description = "py.test plugin that allows you to add environment variables." description = "pytest plugin that allows you to add environment variables."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.8"
files = [ files = [
{file = "pytest_env-1.0.1-py3-none-any.whl", hash = "sha256:e8faf927c6fcdbbc8fe3317506acc116713c9708d01652a0fd945f9ae27b71aa"}, {file = "pytest_env-1.1.1-py3-none-any.whl", hash = "sha256:2b71b37c6810f28bec790a7b373c777af87352b3a359b3de0edb9d24df5cf8b3"},
{file = "pytest_env-1.0.1.tar.gz", hash = "sha256:603fe216e8e03a5d134989cb41317c59aabef013d2250c71b864ab0798fbe6f6"}, {file = "pytest_env-1.1.1.tar.gz", hash = "sha256:1efb8acce1f6431196150f3b30673443ff05a6fabff64539a9495cd2248adf9e"},
] ]
[package.dependencies] [package.dependencies]
pytest = ">=7.3.1" pytest = ">=7.4.3"
tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
[package.extras] [package.extras]
test = ["coverage (>=7.2.7)", "pytest-mock (>=3.10)"] test = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "pytest-mock (>=3.12)"]
[[package]] [[package]]
name = "pytest-mock" name = "pytest-mock"
version = "3.11.1" version = "3.12.0"
description = "Thin-wrapper around the mock package for easier use with pytest" description = "Thin-wrapper around the mock package for easier use with pytest"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.8"
files = [ files = [
{file = "pytest-mock-3.11.1.tar.gz", hash = "sha256:7f6b125602ac6d743e523ae0bfa71e1a697a2f5534064528c6ff84c2f7c2fc7f"}, {file = "pytest-mock-3.12.0.tar.gz", hash = "sha256:31a40f038c22cad32287bb43932054451ff5583ff094bca6f675df2f8bc1a6e9"},
{file = "pytest_mock-3.11.1-py3-none-any.whl", hash = "sha256:21c279fff83d70763b05f8874cc9cfb3fcacd6d354247a976f9529d19f9acf39"}, {file = "pytest_mock-3.12.0-py3-none-any.whl", hash = "sha256:0972719a7263072da3a21c7f4773069bcc7486027d7e8e1f81d98a47e701bc4f"},
] ]
[package.dependencies] [package.dependencies]
@@ -2407,13 +2429,13 @@ toml = ["tomli (>=2.0.1)"]
[[package]] [[package]]
name = "redis" name = "redis"
version = "5.0.0" version = "5.0.1"
description = "Python client for Redis database and key-value store" description = "Python client for Redis database and key-value store"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "redis-5.0.0-py3-none-any.whl", hash = "sha256:06570d0b2d84d46c21defc550afbaada381af82f5b83e5b3777600e05d8e2ed0"}, {file = "redis-5.0.1-py3-none-any.whl", hash = "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f"},
{file = "redis-5.0.0.tar.gz", hash = "sha256:5cea6c0d335c9a7332a460ed8729ceabb4d0c489c7285b0a86dbbf8a017bd120"}, {file = "redis-5.0.1.tar.gz", hash = "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f"},
] ]
[package.dependencies] [package.dependencies]
@@ -2423,6 +2445,103 @@ async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2
hiredis = ["hiredis (>=1.0.0)"] hiredis = ["hiredis (>=1.0.0)"]
ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"]
[[package]]
name = "regex"
version = "2023.10.3"
description = "Alternative regular expression module, to replace re."
optional = false
python-versions = ">=3.7"
files = [
{file = "regex-2023.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc"},
{file = "regex-2023.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915"},
{file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29"},
{file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8"},
{file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b"},
{file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee"},
{file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55"},
{file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be"},
{file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5"},
{file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767"},
{file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff"},
{file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a"},
{file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a"},
{file = "regex-2023.10.3-cp310-cp310-win32.whl", hash = "sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec"},
{file = "regex-2023.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353"},
{file = "regex-2023.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e"},
{file = "regex-2023.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051"},
{file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964"},
{file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc"},
{file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b"},
{file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac"},
{file = "regex-2023.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58"},
{file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a"},
{file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e"},
{file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0"},
{file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6"},
{file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54"},
{file = "regex-2023.10.3-cp311-cp311-win32.whl", hash = "sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2"},
{file = "regex-2023.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c"},
{file = "regex-2023.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037"},
{file = "regex-2023.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f"},
{file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41"},
{file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e"},
{file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c"},
{file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841"},
{file = "regex-2023.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9"},
{file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420"},
{file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9"},
{file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f"},
{file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292"},
{file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a"},
{file = "regex-2023.10.3-cp312-cp312-win32.whl", hash = "sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a"},
{file = "regex-2023.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b"},
{file = "regex-2023.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a3ee019a9befe84fa3e917a2dd378807e423d013377a884c1970a3c2792d293"},
{file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76066d7ff61ba6bf3cb5efe2428fc82aac91802844c022d849a1f0f53820502d"},
{file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe50b61bab1b1ec260fa7cd91106fa9fece57e6beba05630afe27c71259c59b"},
{file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fd88f373cb71e6b59b7fa597e47e518282455c2734fd4306a05ca219a1991b0"},
{file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ab05a182c7937fb374f7e946f04fb23a0c0699c0450e9fb02ef567412d2fa3"},
{file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dac37cf08fcf2094159922edc7a2784cfcc5c70f8354469f79ed085f0328ebdf"},
{file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e54ddd0bb8fb626aa1f9ba7b36629564544954fff9669b15da3610c22b9a0991"},
{file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3367007ad1951fde612bf65b0dffc8fd681a4ab98ac86957d16491400d661302"},
{file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:16f8740eb6dbacc7113e3097b0a36065a02e37b47c936b551805d40340fb9971"},
{file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:f4f2ca6df64cbdd27f27b34f35adb640b5d2d77264228554e68deda54456eb11"},
{file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:39807cbcbe406efca2a233884e169d056c35aa7e9f343d4e78665246a332f597"},
{file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7eece6fbd3eae4a92d7c748ae825cbc1ee41a89bb1c3db05b5578ed3cfcfd7cb"},
{file = "regex-2023.10.3-cp37-cp37m-win32.whl", hash = "sha256:ce615c92d90df8373d9e13acddd154152645c0dc060871abf6bd43809673d20a"},
{file = "regex-2023.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f649fa32fe734c4abdfd4edbb8381c74abf5f34bc0b3271ce687b23729299ed"},
{file = "regex-2023.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b98b7681a9437262947f41c7fac567c7e1f6eddd94b0483596d320092004533"},
{file = "regex-2023.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:91dc1d531f80c862441d7b66c4505cd6ea9d312f01fb2f4654f40c6fdf5cc37a"},
{file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82fcc1f1cc3ff1ab8a57ba619b149b907072e750815c5ba63e7aa2e1163384a4"},
{file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7979b834ec7a33aafae34a90aad9f914c41fd6eaa8474e66953f3f6f7cbd4368"},
{file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef71561f82a89af6cfcbee47f0fabfdb6e63788a9258e913955d89fdd96902ab"},
{file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd829712de97753367153ed84f2de752b86cd1f7a88b55a3a775eb52eafe8a94"},
{file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00e871d83a45eee2f8688d7e6849609c2ca2a04a6d48fba3dff4deef35d14f07"},
{file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:706e7b739fdd17cb89e1fbf712d9dc21311fc2333f6d435eac2d4ee81985098c"},
{file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cc3f1c053b73f20c7ad88b0d1d23be7e7b3901229ce89f5000a8399746a6e039"},
{file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f85739e80d13644b981a88f529d79c5bdf646b460ba190bffcaf6d57b2a9863"},
{file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:741ba2f511cc9626b7561a440f87d658aabb3d6b744a86a3c025f866b4d19e7f"},
{file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e77c90ab5997e85901da85131fd36acd0ed2221368199b65f0d11bca44549711"},
{file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:979c24cbefaf2420c4e377ecd1f165ea08cc3d1fbb44bdc51bccbbf7c66a2cb4"},
{file = "regex-2023.10.3-cp38-cp38-win32.whl", hash = "sha256:58837f9d221744d4c92d2cf7201c6acd19623b50c643b56992cbd2b745485d3d"},
{file = "regex-2023.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:c55853684fe08d4897c37dfc5faeff70607a5f1806c8be148f1695be4a63414b"},
{file = "regex-2023.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af"},
{file = "regex-2023.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930"},
{file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e"},
{file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14"},
{file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d"},
{file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52"},
{file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b"},
{file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588"},
{file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa"},
{file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af"},
{file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528"},
{file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca"},
{file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48"},
{file = "regex-2023.10.3-cp39-cp39-win32.whl", hash = "sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd"},
{file = "regex-2023.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988"},
{file = "regex-2023.10.3.tar.gz", hash = "sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f"},
]
[[package]] [[package]]
name = "requests" name = "requests"
version = "2.31.0" version = "2.31.0"
@@ -2517,13 +2636,13 @@ diagram = ["matplotlib (>=3.0.0)", "pydot (>=1.3.0)", "tqdm (>=v4.31.0)"]
[[package]] [[package]]
name = "s3transfer" name = "s3transfer"
version = "0.6.2" version = "0.7.0"
description = "An Amazon S3 Transfer Manager" description = "An Amazon S3 Transfer Manager"
optional = false optional = false
python-versions = ">= 3.7" python-versions = ">= 3.7"
files = [ files = [
{file = "s3transfer-0.6.2-py3-none-any.whl", hash = "sha256:b014be3a8a2aab98cfe1abc7229cc5a9a0cf05eb9c1f2b86b230fd8df3f78084"}, {file = "s3transfer-0.7.0-py3-none-any.whl", hash = "sha256:10d6923c6359175f264811ef4bf6161a3156ce8e350e705396a7557d6293c33a"},
{file = "s3transfer-0.6.2.tar.gz", hash = "sha256:cab66d3380cca3e70939ef2255d01cd8aece6a4907a9528740f668c4b0611861"}, {file = "s3transfer-0.7.0.tar.gz", hash = "sha256:fd3889a66f5fe17299fe75b82eae6cf722554edca744ca5d5fe308b104883d2e"},
] ]
[package.dependencies] [package.dependencies]
@@ -2780,17 +2899,17 @@ watchdog = ["watchdog (>=2.3)"]
[[package]] [[package]]
name = "wtforms" name = "wtforms"
version = "3.0.1" version = "3.1.1"
description = "Form validation and rendering for Python web development." description = "Form validation and rendering for Python web development."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.8"
files = [ files = [
{file = "WTForms-3.0.1-py3-none-any.whl", hash = "sha256:837f2f0e0ca79481b92884962b914eba4e72b7a2daaf1f939c890ed0124b834b"}, {file = "wtforms-3.1.1-py3-none-any.whl", hash = "sha256:ae7c54b29806c70f7bce8eb9f24afceb10ca5c32af3d9f04f74d2f66ccc5c7e0"},
{file = "WTForms-3.0.1.tar.gz", hash = "sha256:6b351bbb12dd58af57ffef05bc78425d08d1914e0fd68ee14143b7ade023c5bc"}, {file = "wtforms-3.1.1.tar.gz", hash = "sha256:5e51df8af9a60f6beead75efa10975e97768825a82146a65c7cbf5b915990620"},
] ]
[package.dependencies] [package.dependencies]
MarkupSafe = "*" markupsafe = "*"
[package.extras] [package.extras]
email = ["email-validator"] email = ["email-validator"]
@@ -2850,5 +2969,5 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.9" python-versions = ">=3.9,<3.12"
content-hash = "1fa4c6660c944c683b91a0c4eda1044cb1040e53b2f6d922bacb4ab5cab25e3b" content-hash = "dc52fb7e5db480267e4f6102edee0ce19669cfd853b8b32e6758366b5e048021"
+8 -8
View File
@@ -6,9 +6,9 @@ authors = ["Your Name <you@example.com>"]
readme = "README.md" readme = "README.md"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.9" python = ">=3.9,<3.12"
ago = "~=0.0.95" ago = "~=0.0.95"
blinker = "~=1.6" blinker = "~=1.7"
exceptiongroup = "==1.1.3" exceptiongroup = "==1.1.3"
flask = "~=2.3" flask = "~=2.3"
flask-basicauth = "~=0.2" flask-basicauth = "~=0.2"
@@ -22,8 +22,8 @@ humanize = "~=4.8"
itsdangerous = "~=2.1" itsdangerous = "~=2.1"
jinja2 = "~=3.1" jinja2 = "~=3.1"
newrelic = "*" newrelic = "*"
notifications-python-client = "==8.0.1" notifications-python-client = "==8.1.0"
notifications-utils = {git = "https://github.com/GSA/notifications-utils.git", develop = true, branch = "main"} notifications-utils = {git = "https://github.com/GSA/notifications-utils.git"}
pyexcel = "==0.7.0" pyexcel = "==0.7.0"
pyexcel-io = "==0.6.6" pyexcel-io = "==0.6.6"
pyexcel-ods3 = "==0.6.1" pyexcel-ods3 = "==0.6.1"
@@ -35,7 +35,7 @@ python-dotenv = "==1.0.0"
pytz = "==2023.3.post1" pytz = "==2023.3.post1"
rtreelib = "==0.2.0" rtreelib = "==0.2.0"
werkzeug = "^3.0.1" werkzeug = "^3.0.1"
wtforms = "~=3.0" wtforms = "~=3.1"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
@@ -52,9 +52,9 @@ isort = "^5.12.0"
jinja2-cli = {version = "==0.8.2", extras = ["yaml"]} jinja2-cli = {version = "==0.8.2", extras = ["yaml"]}
moto = "^4.2" moto = "^4.2"
pip-audit = "*" pip-audit = "*"
pytest = "^7.4.2" pytest = "^7.4.3"
pytest-env = "^1.0.1" pytest-env = "^1.1.1"
pytest-mock = "^3.11.1" pytest-mock = "^3.12.0"
pytest-playwright = "^0.4.3" pytest-playwright = "^0.4.3"
pytest-xdist = "^3.3.1" pytest-xdist = "^3.3.1"
radon = "^6.0.1" radon = "^6.0.1"
+2 -2
View File
@@ -18,11 +18,11 @@ class TestAssetFingerprint(object):
asset_fingerprinter = AssetFingerprinter(asset_root="/suppliers/static/") asset_fingerprinter = AssetFingerprinter(asset_root="/suppliers/static/")
assert ( assert (
asset_fingerprinter.get_url("application.css") asset_fingerprinter.get_url("application.css")
== "/suppliers/static/application.css?418e6f4a6cdf1142e45c072ed3e1c90a" # noqa == "/suppliers/static/application.css?418e6f4a6cdf1142e45c072ed3e1c90a"
) )
assert ( assert (
asset_fingerprinter.get_url("application-ie6.css") asset_fingerprinter.get_url("application-ie6.css")
== "/suppliers/static/application-ie6.css?418e6f4a6cdf1142e45c072ed3e1c90a" # noqa == "/suppliers/static/application-ie6.css?418e6f4a6cdf1142e45c072ed3e1c90a"
) )
def test_building_file_path(self, mocker): def test_building_file_path(self, mocker):
+8 -2
View File
@@ -54,7 +54,10 @@ def test_csrf_returns_400(client_request, mocker):
_test_page_title=False, _test_page_title=False,
) )
assert page.h1.string.strip() == "Sorry, theres a problem with Notify.gov" assert (
page.h1.string.strip()
== "Sorry, we can't deliver what you asked for right now."
)
assert ( assert (
page.title.string.strip() page.title.string.strip()
== "Sorry, theres a problem with the service Notify.gov" == "Sorry, theres a problem with the service Notify.gov"
@@ -75,7 +78,10 @@ def test_csrf_redirects_to_sign_in_page_if_not_signed_in(client_request, mocker)
def test_405_returns_something_went_wrong_page(client_request, mocker): def test_405_returns_something_went_wrong_page(client_request, mocker):
page = client_request.post_url("/", _expected_status=405) page = client_request.post_url("/", _expected_status=405)
assert page.h1.string.strip() == "Sorry, theres a problem with Notify.gov" assert (
page.h1.string.strip()
== "Sorry, we can't deliver what you asked for right now."
)
assert ( assert (
page.title.string.strip() page.title.string.strip()
== "Sorry, theres a problem with the service Notify.gov" == "Sorry, theres a problem with the service Notify.gov"
+1
View File
@@ -111,6 +111,7 @@ def test_service_navigation_for_org_user(
service_id=SERVICE_ONE_ID, service_id=SERVICE_ONE_ID,
) )
assert [item.text.strip() for item in page.select("nav.nav a")] == [ assert [item.text.strip() for item in page.select("nav.nav a")] == [
"Send messages",
"Usage", "Usage",
"Team members", "Team members",
] ]
@@ -256,21 +256,23 @@ def test_choose_account_should_should_organizations_link_for_platform_admin(
] == expected_headings ] == expected_headings
def test_choose_account_should_show_back_to_service_link( # Moving the back to service link into the top navigation
client_request,
mock_get_orgs_and_services,
mock_get_organization,
mock_get_organization_services,
):
resp = client_request.get("main.choose_account")
service_navigation = resp.find( # def test_choose_account_should_show_back_to_service_link(
"div", {"class": "navigation-service usa-breadcrumb"} # client_request,
) # mock_get_orgs_and_services,
back_to_service_link = service_navigation.a # mock_get_organization,
# mock_get_organization_services,
# ):
# resp = client_request.get("main.choose_account")
assert back_to_service_link["href"] == url_for("main.show_accounts_or_dashboard") # service_navigation = resp.find(
assert back_to_service_link.text == "Back to service one" # "div", {"class": "navigation-service usa-breadcrumb"}
# )
# back_to_service_link = service_navigation.a
# assert back_to_service_link["href"] == url_for("main.show_accounts_or_dashboard")
# assert back_to_service_link.text == "Back to service one"
def test_choose_account_should_not_show_back_to_service_link_if_no_service_in_session( def test_choose_account_should_not_show_back_to_service_link_if_no_service_in_session(
@@ -322,7 +324,7 @@ def test_choose_account_should_not_show_back_to_service_link_if_service_archived
assert normalize_spaces(page.select_one("h1").text) == "Choose service" assert normalize_spaces(page.select_one("h1").text) == "Choose service"
if active: if active:
assert page.select_one(".navigation-service a") is not None assert page.select_one(".navigation-service a") is None
else: else:
assert page.select_one(".navigation-service a") is None assert page.select_one(".navigation-service a") is None
@@ -361,7 +363,7 @@ def test_should_show_back_to_service_if_user_belongs_to_service(
): ):
mock_get_service.return_value = service_one mock_get_service.return_value = service_one
expected_page_text = ( expected_page_text = (
"Test Service Switch service " "" "Dashboard " "Send messages " "Team members" "Test Service Switch service " "Send messages " "Dashboard " "Team members"
) # TODO: set sidebar variables in common test module ) # TODO: set sidebar variables in common test module
page = client_request.get( page = client_request.get(
@@ -190,12 +190,10 @@ def test_service_setting_link_toggles_index_error(
index, index,
text, text,
): ):
with pytest.raises( # noqa: PT012 # Requires more research to refactor. url_for(endpoint, service_id=service_one["id"])
expected_exception=IndexError service_one.update(service_fields)
): page = get_service_settings_page()
url_for(endpoint, service_id=service_one["id"]) with pytest.raises(expected_exception=IndexError):
service_one.update(service_fields)
page = get_service_settings_page()
page.select(".page-footer-link a")[index] page.select(".page-footer-link a")[index]
@@ -744,13 +744,11 @@ def test_should_check_for_reply_to_on_go_live_index_error(
return_value=volume, return_value=volume,
) )
with pytest.raises( # noqa: PT012 # This will require more research for refactoring. page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
expected_exception=IndexError assert page.h1.text == "Before you request to go live"
): checklist_items = page.select(".task-list .task-list-item")
page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
assert page.h1.text == "Before you request to go live"
checklist_items = page.select(".task-list .task-list-item") with pytest.raises(expected_exception=IndexError):
assert ( assert (
normalize_spaces(checklist_items[3].text) normalize_spaces(checklist_items[3].text)
== expected_reply_to_checklist_item == expected_reply_to_checklist_item
@@ -1030,19 +1028,24 @@ def test_should_check_for_sms_sender_on_go_live(
return_value=volume, return_value=volume,
) )
with pytest.raises( # noqa: PT012 # Requires more research for how to refactor. with pytest.raises(expected_exception=IndexError):
expected_exception=IndexError simple_statement_for_test_should_check_for_sms_sender_on_go_live(
): client_request, expected_sms_sender_checklist_item, mock_get_sms_senders
page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
assert page.h1.text == "Before you request to go live"
checklist_items = page.select(".task-list .task-list-item")
assert (
normalize_spaces(checklist_items[3].text)
== expected_sms_sender_checklist_item
) )
mock_get_sms_senders.assert_called_once_with(SERVICE_ONE_ID)
def simple_statement_for_test_should_check_for_sms_sender_on_go_live(
client_request, expected_sms_sender_checklist_item, mock_get_sms_senders
):
page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
assert page.h1.text == "Before you request to go live"
checklist_items = page.select(".task-list .task-list-item")
assert (
normalize_spaces(checklist_items[3].text) == expected_sms_sender_checklist_item
)
mock_get_sms_senders.assert_called_once_with(SERVICE_ONE_ID)
def test_non_gov_user_is_told_they_cant_go_live( def test_non_gov_user_is_told_they_cant_go_live(
@@ -3145,10 +3148,8 @@ def test_should_set_sms_allowance_fails(
mock_get_free_sms_fragment_limit, mock_get_free_sms_fragment_limit,
mock_create_or_update_free_sms_fragment_limit, mock_create_or_update_free_sms_fragment_limit,
): ):
with pytest.raises( # noqa: PT012 # Needs more research for refactoring. client_request.login(platform_admin_user)
expected_exception=AssertionError with pytest.raises(expected_exception=AssertionError):
):
client_request.login(platform_admin_user)
client_request.post( client_request.post(
"main.set_free_sms_allowance", "main.set_free_sms_allowance",
service_id=SERVICE_ONE_ID, service_id=SERVICE_ONE_ID,
@@ -3460,10 +3461,8 @@ def test_archive_service_after_confirm_error(
mocker.patch("app.notify_client.service_api_client.redis_client.delete") mocker.patch("app.notify_client.service_api_client.redis_client.delete")
mocker.patch("app.notify_client.service_api_client.redis_client.delete_by_pattern") mocker.patch("app.notify_client.service_api_client.redis_client.delete_by_pattern")
with pytest.raises( # noqa: PT012 # Needs more research for refactoring. client_request.login(user)
expected_exception=AssertionError with pytest.raises(expected_exception=AssertionError):
):
client_request.login(user)
client_request.post( client_request.post(
"main.archive_service", "main.archive_service",
service_id=SERVICE_ONE_ID, service_id=SERVICE_ONE_ID,
@@ -3596,10 +3595,8 @@ def test_suspend_service_after_confirm_error(
): ):
mocker.patch("app.service_api_client.post") mocker.patch("app.service_api_client.post")
mocker.patch("app.main.views.service_settings.create_suspend_service_event") mocker.patch("app.main.views.service_settings.create_suspend_service_event")
with pytest.raises( # noqa: PT012 # Needs more research for refactoring. client_request.login(user)
expected_exception=AssertionError with pytest.raises(expected_exception=AssertionError):
):
client_request.login(user)
client_request.post( client_request.post(
"main.suspend_service", "main.suspend_service",
service_id=SERVICE_ONE_ID, service_id=SERVICE_ONE_ID,
+2 -1
View File
@@ -16,7 +16,8 @@ def test_owasp_useful_headers_set(
assert search(r"frame-ancestors 'none';", csp) assert search(r"frame-ancestors 'none';", csp)
assert search(r"form-action 'self';", csp) assert search(r"form-action 'self';", csp)
assert search( assert search(
r"script-src 'self' static\.example\.com 'unsafe-eval' https:\/\/js-agent\.newrelic\.com https:\/\/gov-bam\.nr-data\.net 'nonce-.*';", # noqa e501 r"script-src 'self' static\.example\.com 'unsafe-eval' https:\/\/js-agent\.new"
r"relic\.com https:\/\/gov-bam\.nr-data\.net 'nonce-.*';",
csp, csp,
) )
assert search(r"connect-src 'self' https:\/\/gov-bam.nr-data\.net;", csp) assert search(r"connect-src 'self' https:\/\/gov-bam.nr-data\.net;", csp)
+2 -1
View File
@@ -238,7 +238,8 @@ def test_should_show_job_with_sending_limit_exceeded_status(
) )
assert normalize_spaces(page.select("main p")[1].text) == ( assert normalize_spaces(page.select("main p")[1].text) == (
"Notify cannot send these messages because you have reached a limit. You can only send 1,000 messages per day and 250,000 messages in total." # noqa "Notify cannot send these messages because you have reached a limit. "
"You can only send 1,000 messages per day and 250,000 messages in total."
) )
assert normalize_spaces(page.select("main p")[2].text) == ( assert normalize_spaces(page.select("main p")[2].text) == (
"Upload this spreadsheet again tomorrow or contact the Notify.gov team to raise the limit." "Upload this spreadsheet again tomorrow or contact the Notify.gov team to raise the limit."
+20 -65
View File
@@ -20,8 +20,8 @@ from tests.conftest import (
) )
@pytest.mark.parametrize( # noqa: PT014 # Duplicate parameters have different permissions. @pytest.mark.parametrize(
("user", "expected_self_text", "expected_coworker_text"), ("user", "expected_self_text", "add_details"),
[ [
( (
create_active_user_with_permissions(), create_active_user_with_permissions(),
@@ -34,16 +34,7 @@ from tests.conftest import (
"Can Manage settings, team and usage " "Can Manage settings, team and usage "
"Can Manage API integration" "Can Manage API integration"
), ),
( True,
"ZZZZZZZZ zzzzzzz@example.gsa.gov "
"Permissions "
"Can See dashboard "
"Cannot Send messages "
"Cannot Add and edit templates "
"Cannot Manage settings, team and usage "
"Cannot Manage API integration "
"Change details for ZZZZZZZZ zzzzzzz@example.gsa.gov"
),
), ),
( (
create_active_user_empty_permissions(), create_active_user_empty_permissions(),
@@ -56,15 +47,7 @@ from tests.conftest import (
"Cannot Manage settings, team and usage " "Cannot Manage settings, team and usage "
"Cannot Manage API integration" "Cannot Manage API integration"
), ),
( False,
"ZZZZZZZZ zzzzzzz@example.gsa.gov "
"Permissions "
"Can See dashboard "
"Cannot Send messages "
"Cannot Add and edit templates "
"Cannot Manage settings, team and usage "
"Cannot Manage API integration"
),
), ),
( (
create_active_user_view_permissions(), create_active_user_view_permissions(),
@@ -77,15 +60,7 @@ from tests.conftest import (
"Cannot Manage settings, team and usage " "Cannot Manage settings, team and usage "
"Cannot Manage API integration" "Cannot Manage API integration"
), ),
( False,
"ZZZZZZZZ zzzzzzz@example.gsa.gov "
"Permissions "
"Can See dashboard "
"Cannot Send messages "
"Cannot Add and edit templates "
"Cannot Manage settings, team and usage "
"Cannot Manage API integration"
),
), ),
( (
create_active_user_manage_template_permissions(), create_active_user_manage_template_permissions(),
@@ -98,36 +73,7 @@ from tests.conftest import (
"Cannot Manage settings, team and usage " "Cannot Manage settings, team and usage "
"Cannot Manage API integration" "Cannot Manage API integration"
), ),
( False,
"ZZZZZZZZ zzzzzzz@example.gsa.gov "
"Permissions "
"Can See dashboard "
"Cannot Send messages "
"Cannot Add and edit templates "
"Cannot Manage settings, team and usage "
"Cannot Manage API integration"
),
),
(
create_active_user_manage_template_permissions(),
(
"Test User With Permissions (you) "
"Permissions "
"Can See dashboard "
"Cannot Send messages "
"Can Add and edit templates "
"Cannot Manage settings, team and usage "
"Cannot Manage API integration"
),
(
"ZZZZZZZZ zzzzzzz@example.gsa.gov "
"Permissions "
"Can See dashboard "
"Cannot Send messages "
"Cannot Add and edit templates "
"Cannot Manage settings, team and usage "
"Cannot Manage API integration"
),
), ),
], ],
) )
@@ -140,8 +86,8 @@ def test_should_show_overview_page(
service_one, service_one,
user, user,
expected_self_text, expected_self_text,
expected_coworker_text,
active_user_view_permissions, active_user_view_permissions,
add_details,
): ):
current_user = user current_user = user
other_user = copy.deepcopy(active_user_view_permissions) other_user = copy.deepcopy(active_user_view_permissions)
@@ -164,11 +110,20 @@ def test_should_show_overview_page(
assert ( assert (
normalize_spaces(page.select(".user-list-item")[0].text) == expected_self_text normalize_spaces(page.select(".user-list-item")[0].text) == expected_self_text
) )
# [1:5] are invited users
assert ( expected = (
normalize_spaces(page.select(".user-list-item")[6].text) "ZZZZZZZZ zzzzzzz@example.gsa.gov "
== expected_coworker_text "Permissions "
"Can See dashboard "
"Cannot Send messages "
"Cannot Add and edit templates "
"Cannot Manage settings, team and usage "
"Cannot Manage API integration"
) )
if add_details is True:
expected = f"{expected} Change details for ZZZZZZZZ zzzzzzz@example.gsa.gov"
assert normalize_spaces(page.select(".user-list-item")[6].text) == expected
mock_get_users.assert_called_once_with(SERVICE_ONE_ID) mock_get_users.assert_called_once_with(SERVICE_ONE_ID)
+4 -2
View File
@@ -770,10 +770,12 @@ def test_clear_cache_shows_form(
[ [
call("service-????????-????-????-????-????????????-templates"), call("service-????????-????-????-????-????????????-templates"),
call( call(
"service-????????-????-????-????-????????????-template-????????-????-????-????-????????????-version-*" # noqa "service-????????-????-????-????-????????????-template"
"-????????-????-????-????-????????????-version-*"
), ),
call( call(
"service-????????-????-????-????-????????????-template-????????-????-????-????-????????????-versions" # noqa "service-????????-????-????-????-????????????-template"
"-????????-????-????-????-????????????-versions"
), ),
], ],
"Removed 6 objects across 3 key formats for template", "Removed 6 objects across 3 key formats for template",
+21 -15
View File
@@ -2319,25 +2319,31 @@ def test_warns_if_file_sent_already_errors(
"app.main.views.send.get_csv_metadata", "app.main.views.send.get_csv_metadata",
return_value={"original_file_name": uploaded_file_name}, return_value={"original_file_name": uploaded_file_name},
) )
# Should be botocore.errorfactory.NoSuchKey but for some reason can't use that
with pytest.raises( # noqa: PT011,PT012 # Requires more research on how to refactor. with pytest.raises(
expected_exception=Exception expected_exception=Exception, match="Unable to locate credentials"
): ):
page = client_request.get( stmt_for_test_warns_if_file_sent_already_errors(
"main.check_messages", client_request, uploaded_file_name, fake_uuid, mock_get_jobs
service_id=SERVICE_ONE_ID,
template_id="5d729fbd-239c-44ab-b498-75a985f3198f",
upload_id=fake_uuid,
original_file_name=uploaded_file_name,
_test_page_title=False,
) )
assert normalize_spaces(page.select_one(".banner-dangerous").text) == (
"These messages have already been sent today "
"If you need to resend them, rename the file and upload it again."
)
mock_get_jobs.assert_called_once_with(SERVICE_ONE_ID, limit_days=0) def stmt_for_test_warns_if_file_sent_already_errors(
client_request, uploaded_file_name, fake_uuid, mock_get_jobs
):
page = client_request.get(
"main.check_messages",
service_id=SERVICE_ONE_ID,
template_id="5d729fbd-239c-44ab-b498-75a985f3198f",
upload_id=fake_uuid,
original_file_name=uploaded_file_name,
_test_page_title=False,
)
assert normalize_spaces(page.select_one(".banner-dangerous").text) == (
"These messages have already been sent today "
"If you need to resend them, rename the file and upload it again."
)
mock_get_jobs.assert_called_once_with(SERVICE_ONE_ID, limit_days=0)
def test_check_messages_column_error_doesnt_show_optional_columns( def test_check_messages_column_error_doesnt_show_optional_columns(
+21 -15
View File
@@ -1117,25 +1117,31 @@ def test_should_show_checkboxes_for_selecting_templates_assertion_error(
mock_get_no_api_keys, mock_get_no_api_keys,
user, user,
): ):
with pytest.raises( # noqa: PT012 # This will require more research into refactoring. with pytest.raises(expected_exception=AssertionError):
expected_exception=AssertionError _stmt_for_test_should_show_checkboxes_for_selecting_templates_assertion_error(
): client_request, user
client_request.login(user)
page = client_request.get(
"main.choose_template",
service_id=SERVICE_ONE_ID,
) )
checkboxes = page.select("input[name=templates_and_folders]")
assert len(checkboxes) == 4
assert checkboxes[0]["value"] == TEMPLATE_ONE_ID def _stmt_for_test_should_show_checkboxes_for_selecting_templates_assertion_error(
assert checkboxes[0]["id"] == "templates-or-folder-{}".format(TEMPLATE_ONE_ID) client_request, user
):
client_request.login(user)
for index in (1, 2, 3): page = client_request.get(
assert checkboxes[index]["value"] != TEMPLATE_ONE_ID "main.choose_template",
assert TEMPLATE_ONE_ID not in checkboxes[index]["id"] service_id=SERVICE_ONE_ID,
)
checkboxes = page.select("input[name=templates_and_folders]")
assert len(checkboxes) == 4
assert checkboxes[0]["value"] == TEMPLATE_ONE_ID
assert checkboxes[0]["id"] == "templates-or-folder-{}".format(TEMPLATE_ONE_ID)
for index in (1, 2, 3):
assert checkboxes[index]["value"] != TEMPLATE_ONE_ID
assert TEMPLATE_ONE_ID not in checkboxes[index]["id"]
@pytest.mark.parametrize( @pytest.mark.parametrize(
+21 -18
View File
@@ -304,7 +304,7 @@ def test_should_show_live_search_if_service_has_lots_of_folders(
assert count_of_templates == 4 assert count_of_templates == 4
@pytest.mark.parametrize( # noqa: PT014 # Requires more research why there are duplicate params here. @pytest.mark.parametrize(
("service_permissions", "expected_values", "expected_labels"), ("service_permissions", "expected_values", "expected_labels"),
[ [
pytest.param( pytest.param(
@@ -320,19 +320,20 @@ def test_should_show_live_search_if_service_has_lots_of_folders(
"Copy an existing template", "Copy an existing template",
], ],
), ),
pytest.param( # TODO This is a duplicate of above. Why?
["email", "sms"], # pytest.param(
[ # ["email", "sms"],
# 'email', # [
"sms", # # 'email',
"copy-existing", # "sms",
], # "copy-existing",
[ # ],
# 'Email', # [
"Start with a blank template", # # 'Email',
"Copy an existing template", # "Start with a blank template",
], # "Copy an existing template",
), # ],
# ),
], ],
) )
def test_should_show_new_template_choices_if_service_has_folder_permission( def test_should_show_new_template_choices_if_service_has_folder_permission(
@@ -753,9 +754,9 @@ def test_choose_a_template_to_copy(
assert len(actual) == len(expected) assert len(actual) == len(expected)
for actual, expected in zip(actual, expected): # noqa: B020 zipobject = zip(actual, expected)
for actual, expected in zipobject:
assert normalize_spaces(actual.text) == expected assert normalize_spaces(actual.text) == expected
links = page.select("main nav a") links = page.select("main nav a")
assert links[0]["href"] == url_for( assert links[0]["href"] == url_for(
"main.choose_template_to_copy", "main.choose_template_to_copy",
@@ -799,7 +800,8 @@ def test_choose_a_template_to_copy_when_user_has_one_service(
assert len(actual) == len(expected) assert len(actual) == len(expected)
for actual, expected in zip(actual, expected): # noqa: B020 zipobject = zip(actual, expected)
for actual, expected in zipobject:
assert normalize_spaces(actual.text) == expected assert normalize_spaces(actual.text) == expected
assert page.select("main nav a")[0]["href"] == url_for( assert page.select("main nav a")[0]["href"] == url_for(
@@ -875,7 +877,8 @@ def test_choose_a_template_to_copy_from_folder_within_service(
assert len(actual) == len(expected) assert len(actual) == len(expected)
for actual, expected in zip(actual, expected): # noqa: B020 zipobject = zip(actual, expected)
for actual, expected in zipobject:
assert normalize_spaces(actual.text) == expected assert normalize_spaces(actual.text) == expected
links = page.select("main nav a") links = page.select("main nav a")
+3 -3
View File
@@ -17,7 +17,7 @@ def test_should_show_overview_page(
client_request, client_request,
): ):
page = client_request.get("main.user_profile") page = client_request.get("main.user_profile")
assert page.select_one("h1").text.strip() == "Your profile" assert page.select_one("h1").text.strip() == "User profile"
assert "Use platform admin view" not in page assert "Use platform admin view" not in page
assert "Security keys" not in page assert "Security keys" not in page
@@ -27,7 +27,7 @@ def test_overview_page_shows_disable_for_platform_admin(
): ):
client_request.login(platform_admin_user) client_request.login(platform_admin_user)
page = client_request.get("main.user_profile") page = client_request.get("main.user_profile")
assert page.select_one("h1").text.strip() == "Your profile" assert page.select_one("h1").text.strip() == "User profile"
disable_platform_admin_row = page.select_one("#disable-platform-admin") disable_platform_admin_row = page.select_one("#disable-platform-admin")
assert ( assert (
" ".join(disable_platform_admin_row.text.split()) " ".join(disable_platform_admin_row.text.split())
@@ -365,7 +365,7 @@ def test_non_gov_user_cannot_see_change_email_link(
client_request.login(api_nongov_user_active) client_request.login(api_nongov_user_active)
page = client_request.get("main.user_profile") page = client_request.get("main.user_profile")
assert not page.find("a", {"href": url_for("main.user_profile_email")}) assert not page.find("a", {"href": url_for("main.user_profile_email")})
assert page.select_one("h1").text.strip() == "Your profile" assert page.select_one("h1").text.strip() == "User profile"
def test_non_gov_user_cannot_access_change_email_page( def test_non_gov_user_cannot_access_change_email_page(
+1 -8
View File
@@ -192,18 +192,11 @@ def test_returns_value_from_cache(
assert mock_redis_set.call_args_list == expected_cache_set_calls assert mock_redis_set.call_args_list == expected_cache_set_calls
@pytest.mark.parametrize( # noqa: PT014 # Duplicate add_user_to_service has different params for each @pytest.mark.parametrize(
("client", "method", "extra_args", "extra_kwargs"), ("client", "method", "extra_args", "extra_kwargs"),
[ [
(
user_api_client,
"add_user_to_service",
[SERVICE_ONE_ID, sample_uuid(), [], []],
{},
),
(user_api_client, "update_user_attribute", [user_id], {}), (user_api_client, "update_user_attribute", [user_id], {}),
(user_api_client, "reset_failed_login_count", [user_id], {}), (user_api_client, "reset_failed_login_count", [user_id], {}),
(user_api_client, "update_user_attribute", [user_id], {}),
(user_api_client, "update_password", [user_id, "hunter2"], {}), (user_api_client, "update_password", [user_id, "hunter2"], {}),
(user_api_client, "verify_password", [user_id, "hunter2"], {}), (user_api_client, "verify_password", [user_id, "hunter2"], {}),
(user_api_client, "check_verify_code", [user_id, "", ""], {}), (user_api_client, "check_verify_code", [user_id, "", ""], {}),
+1 -2
View File
@@ -134,8 +134,7 @@ def test_does_not_delete_non_temp_email_file(client_request, mocker):
"app.s3_client.s3_logo_client.delete_s3_object" "app.s3_client.s3_logo_client.delete_s3_object"
) )
with pytest.raises(ValueError) as error: # noqa: PT011 # Requires more research. with pytest.raises(ValueError, match="Not a temp file: logo.png"):
delete_email_temp_file(filename) delete_email_temp_file(filename)
assert mocked_delete_s3_object.called is False assert mocked_delete_s3_object.called is False
assert str(error.value) == "Not a temp file: {}".format(filename)
+2 -3
View File
@@ -354,7 +354,6 @@ def test_raises_on_invalid_navigation_item(client_request, navigation_instance):
@pytest.mark.parametrize( @pytest.mark.parametrize(
("endpoint", "selected_nav_item"), ("endpoint", "selected_nav_item"),
[ [
("main.choose_template", "Send messages"),
("main.manage_users", "Team members"), ("main.manage_users", "Team members"),
], ],
) )
@@ -423,9 +422,9 @@ def test_navigation_urls(
mock_get_api_keys, mock_get_api_keys,
): ):
page = client_request.get("main.choose_template", service_id=SERVICE_ONE_ID) page = client_request.get("main.choose_template", service_id=SERVICE_ONE_ID)
assert [a["href"] for a in page.select(".nav.margin-bottom-5 a")] == [ assert [a["href"] for a in page.select(".nav a")] == [
"/services/{}".format(SERVICE_ONE_ID),
"/services/{}/templates".format(SERVICE_ONE_ID), "/services/{}/templates".format(SERVICE_ONE_ID),
"/services/{}".format(SERVICE_ONE_ID),
"/services/{}/users".format(SERVICE_ONE_ID), "/services/{}/users".format(SERVICE_ONE_ID),
"/services/{}/usage".format(SERVICE_ONE_ID), "/services/{}/usage".format(SERVICE_ONE_ID),
"/services/{}/service-settings".format(SERVICE_ONE_ID), "/services/{}/service-settings".format(SERVICE_ONE_ID),
+6 -6
View File
@@ -5,9 +5,9 @@ from werkzeug.exceptions import Forbidden
from app.utils.user import user_has_permissions from app.utils.user import user_has_permissions
@pytest.mark.parametrize( # noqa: PT007 # Ignoring wrong values type because of the list unpacking in the test. @pytest.mark.parametrize(
"permissions", "permissions",
( [
[ [
# Route has one of the permissions which the user has # Route has one of the permissions which the user has
"manage_service" "manage_service"
@@ -25,7 +25,7 @@ from app.utils.user import user_has_permissions
[ [
# Route has no specific permissions required # Route has no specific permissions required
], ],
), ],
) )
def test_permissions( def test_permissions(
client_request, client_request,
@@ -48,14 +48,14 @@ def test_permissions(
index() index()
@pytest.mark.parametrize( # noqa: PT007 # Ignoring wrong values type because of the list unpacking in the test. @pytest.mark.parametrize(
"permissions", "permissions",
( [
[ [
# Route has a permission which the user doesnt have # Route has a permission which the user doesnt have
"send_messages" "send_messages"
], ],
), ],
) )
def test_permissions_forbidden( def test_permissions_forbidden(
client_request, client_request,
+1 -1
View File
@@ -2423,7 +2423,7 @@ def _os_environ():
os.environ[k] = v os.environ[k] = v
@pytest.fixture # noqa (C901 too complex) @pytest.fixture()
def client_request(logged_in_client, mocker, service_one): # noqa (C901 too complex) def client_request(logged_in_client, mocker, service_one): # noqa (C901 too complex)
class ClientRequest: class ClientRequest:
@staticmethod @staticmethod