diff --git a/.gitignore b/.gitignore index 62f46925c..7e07fc102 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,10 @@ *.XLSX ## Non user files allowed to be commited +!app/assets/pdf/best-practices-for-texting-the-public.pdf +!app/assets/pdf/investing-in-notifications-tts-public-benefits-studio-decision-memo.pdf +!app/assets/pdf/best-practices-section-outline.pdf +!app/assets/pdf/standing-up-your-own-notify.pdf !app/assets/pdf/tcpa_overview.pdf !app/assets/pdf/investing-notifications-tts-public-benefits-memo.pdf !app/assets/pdf/out-of-pilot-announcement.pdf diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cb3c48cae..579650135 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,6 +8,7 @@ repos: - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files + exclude: ^app/assets/pdf/.*\.pdf$ - id: debug-statements - id: check-merge-conflict - id: check-toml diff --git a/app/assets/pdf/best-practices-for-texting-the-public.pdf b/app/assets/pdf/best-practices-for-texting-the-public.pdf new file mode 100644 index 000000000..04e9cc99c Binary files /dev/null and b/app/assets/pdf/best-practices-for-texting-the-public.pdf differ diff --git a/app/assets/pdf/best-practices-section-outline.pdf b/app/assets/pdf/best-practices-section-outline.pdf new file mode 100644 index 000000000..4c19613b0 Binary files /dev/null and b/app/assets/pdf/best-practices-section-outline.pdf differ diff --git a/app/assets/pdf/investing-in-notifications-tts-public-benefits-studio-decision-memo.pdf b/app/assets/pdf/investing-in-notifications-tts-public-benefits-studio-decision-memo.pdf new file mode 100644 index 000000000..727d6a122 Binary files /dev/null and b/app/assets/pdf/investing-in-notifications-tts-public-benefits-studio-decision-memo.pdf differ diff --git a/app/assets/pdf/standing-up-your-own-notify.pdf b/app/assets/pdf/standing-up-your-own-notify.pdf new file mode 100644 index 000000000..f76c9d094 Binary files /dev/null and b/app/assets/pdf/standing-up-your-own-notify.pdf differ diff --git a/app/s3_client/s3_csv_client.py b/app/s3_client/s3_csv_client.py index 195ea3032..4d8f33a07 100644 --- a/app/s3_client/s3_csv_client.py +++ b/app/s3_client/s3_csv_client.py @@ -28,8 +28,17 @@ def get_csv_upload(service_id, upload_id): return get_s3_object(*get_csv_location(service_id, upload_id)) +def remove_blank_lines(filedata): + # sometimes people upload files with hundreds of blank lines at the end + data = filedata["data"] + cleaned_data = "\n".join(line for line in data.splitlines() if line.strip()) + filedata["data"] = cleaned_data + return filedata + + def s3upload(service_id, filedata): + filedata = remove_blank_lines(filedata) upload_id = str(uuid.uuid4()) bucket_name, file_location, access_key, secret_key, region = get_csv_location( service_id, upload_id diff --git a/app/templates/views/about/about.html b/app/templates/views/about/about.html index 5b034d34f..51272b5e4 100644 --- a/app/templates/views/about/about.html +++ b/app/templates/views/about/about.html @@ -16,7 +16,10 @@
  • More effectively deliver program outcomes
  • Save administrative costs
  • Implement 21st Century + href="https://digital.gov/resources/delivering-digital-first-public-experience/" + rel="noopener noreferrer" + target="_blank" + aria-label="21st Century IDEA (opens in a new tab)">21st Century IDEA and other directives
  • Notify.gov is an easy-to-use, web-based platform. It requires no technical expertise or system integration — users diff --git a/app/templates/views/about/security.html b/app/templates/views/about/security.html index 0a916035e..8a32e3fc7 100644 --- a/app/templates/views/about/security.html +++ b/app/templates/views/about/security.html @@ -22,16 +22,26 @@

    Notify.gov operates under a full three-year Authority-to-Operate (ATO). This + href="https://digital.gov/resources/an-introduction-to-ato/" + target="_blank" + rel="noopener noreferrer" + aria-label="Authority-to-Operate (ATO) (opens in a new tab)">Authority-to-Operate (ATO). This federal security authorization process leverages security controls provided by National Institute of Standards and Technology (NIST).

    - Our infrastructure runs on cloud.gov and utilizes several + Our infrastructure runs on cloud.gov and utilizes several services through Amazon Web - Services (AWS), including + Services (AWS), including AWS SNS for sending SMS messages.

    @@ -53,15 +63,22 @@

    Multi-Factor Authentication

    - Notify.gov uses Login.gov for enhanced security. + Notify.gov uses Login.gov for enhanced security. Login.gov is an extra layer of security created by the government that uses multi-factor authentication and stronger passwords to protect your account.

    To access Notify.gov, users will use a Login.gov account associated with their agency (.gov) email with one of the - multi-factor authentication + multi-factor authentication methods offered through Login.gov.

    diff --git a/app/templates/views/about/why-text-messaging.html b/app/templates/views/about/why-text-messaging.html index d9ec2635a..b59acf3ca 100644 --- a/app/templates/views/about/why-text-messaging.html +++ b/app/templates/views/about/why-text-messaging.html @@ -16,7 +16,9 @@

    Confusing or unreceived notifications are one of the largest barriers to people getting and keeping + target="_blank" + rel="noopener noreferrer" + aria-label="unreceived notifications (opens in a new tab)">unreceived notifications are one of the largest barriers to people getting and keeping benefits. The typical ways the government communicates with people often fall short. Low income households are more likely to experience housing instability, which means paper mail, already slow, can easily be missed.

    @@ -24,7 +26,9 @@

    Pew Research shows that nearly all adults in the US have a cell phone. Reliance on smartphones + target="_blank" + rel="noopener noreferrer" + aria-label="Pew Research shows that nearly all adults in the US have a cell phone (opens in a new tab)">Pew Research shows that nearly all adults in the US have a cell phone. Reliance on smartphones for online access is especially common among Americans with lower household incomes and those with lower levels of formal education. Of those earning less than $30,000 a year, 28% say their mobile phone is the sole method to digitally connect. diff --git a/app/templates/views/guides/benchmark-performance.html b/app/templates/views/guides/benchmark-performance.html index c302fc5b8..39ca69700 100644 --- a/app/templates/views/guides/benchmark-performance.html +++ b/app/templates/views/guides/benchmark-performance.html @@ -23,7 +23,9 @@

    When the Center on Budget and Policy Priorities studied WIC, they found key learnings about the + target="_blank" + rel="noopener noreferrer" + aria-label="Center on Budget and Policy Priorities (opens in a new tab)">Center on Budget and Policy Priorities studied WIC, they found key learnings about the quantity of messages delivered, how people engage with messages, and how they take action.

    @@ -68,8 +70,11 @@

    - The Code for America’s Texting + The Code for America’s Texting Playbook reported specific learnings around appointment reminders, completing document submission, and maintenance reminders. diff --git a/app/templates/views/guides/clear-goals.html b/app/templates/views/guides/clear-goals.html index a6e3a742b..f3a188766 100644 --- a/app/templates/views/guides/clear-goals.html +++ b/app/templates/views/guides/clear-goals.html @@ -142,7 +142,9 @@

    The Department of Veterans Affairs provides a helpful flow-chart that can help you decide if a text message is needed + target="_blank" + rel="noopener noreferrer" + aria-label="helpful flow-chart (opens in a new tab)">helpful flow-chart that can help you decide if a text message is needed for the communication problem you are trying to solve.

    Use a hypothesis framework to plan your campaign

    diff --git a/app/templates/views/guides/establish-trust.html b/app/templates/views/guides/establish-trust.html index 026e9da81..5d72f66b4 100644 --- a/app/templates/views/guides/establish-trust.html +++ b/app/templates/views/guides/establish-trust.html @@ -101,8 +101,11 @@

    {{circle_number(7) }}Dept. of Social Services: Hi {{circle_number(8) }}Julie, Your Medicaid renewal is closing December 31, 2023. You can renew online at {{circle_number(9) }}https://www.application.yourstate.gov or {{circle_number(10) }} + class="use-link usa-link--external" + href="https://www.application.yourstate.gov" + target="_blank" + rel="application.yourstate.gov" + aria-label="Yourstate dot gov (opens in a new tab)">https://www.application.yourstate.gov or {{circle_number(10) }} call the number on the back of your Medicaid card.

    diff --git a/app/templates/views/guides/rules-and-regulations.html b/app/templates/views/guides/rules-and-regulations.html index 8ad6d000b..7f86248ea 100644 --- a/app/templates/views/guides/rules-and-regulations.html +++ b/app/templates/views/guides/rules-and-regulations.html @@ -29,7 +29,10 @@ {% set links = [ { "p_text": 'The Telephone Consumer + target="_blank" + rel="noopener noreferrer" + aria-label="Telephone Consumer Protection Act (TCPA) (opens in a new tab)" + >Telephone Consumer Protection Act (TCPA) (47 USC § 227) is the federal law that impacts how organizations are allowed to communicate in bulk with the public via telephone (including text message or SMS).' @@ -37,7 +40,9 @@ { "p_text": 'The FCC has ruled that Federal and State programs are exempt from the TCPA and can + target="_blank" + rel="noopener noreferrer" + aria-label="FCC has ruled (opens in a new tab)">FCC has ruled that Federal and State programs are exempt from the TCPA and can send text messages to the public without consent if conducting official business. Without explicit mention in the ruling, local governments, phone carriers, or any texting intermediaries might require it.' @@ -52,7 +57,10 @@ case. For additional questions about the enforcement of the TCPA, you can watch a recorded training on public + target="_blank" + rel="noopener noreferrer" + aria-label="a recorded training on public + benefits texting (opens in a new tab)">a recorded training on public benefits texting provided by the FCC.' }, ] %} @@ -65,7 +73,9 @@

    + target="_blank" + rel="noopener noreferrer" + aria-label="{{ item.url_text }} (opens in a new tab)"> {{ item.url_text }}

    @@ -119,6 +129,7 @@ process to keep your phone number list up-to-date. The FCC offers a Reassigned Numbers Database to identify phone numbers that may have been reassigned since your agency obtained them.

    diff --git a/app/templates/views/guides/write-for-action.html b/app/templates/views/guides/write-for-action.html index 31ac2aa84..f7574def5 100644 --- a/app/templates/views/guides/write-for-action.html +++ b/app/templates/views/guides/write-for-action.html @@ -81,7 +81,10 @@

    What provoking action looks like

    Evidence + href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC10002044/" + target="_blank" + rel="noopener noreferrer" + aria-label="Evidence shows (opens in a new tab)">Evidence shows that employing behavioral science is an effective way to increase the likelihood of a recipient diff --git a/app/templates/views/platform-admin/reports.html b/app/templates/views/platform-admin/reports.html index 23dccc41c..02157c2a2 100644 --- a/app/templates/views/platform-admin/reports.html +++ b/app/templates/views/platform-admin/reports.html @@ -11,7 +11,7 @@

    - Download live services csv report + Download live services csv report

    Monthly notification statuses for live services diff --git a/tests/app/s3_client/test_s3_csv_client.py b/tests/app/s3_client/test_s3_csv_client.py index dbf26ea47..2ea3c43db 100644 --- a/tests/app/s3_client/test_s3_csv_client.py +++ b/tests/app/s3_client/test_s3_csv_client.py @@ -1,6 +1,6 @@ from unittest.mock import Mock -from app.s3_client.s3_csv_client import set_metadata_on_csv_upload +from app.s3_client.s3_csv_client import remove_blank_lines, set_metadata_on_csv_upload def test_sets_metadata(client_request, mocker): @@ -21,3 +21,11 @@ def test_sets_metadata(client_request, mocker): MetadataDirective="REPLACE", ServerSideEncryption="AES256", ) + + +def test_removes_blank_lines(): + filedata = { + "data": "phone number\r\n15555555555\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n" + } + file_data = remove_blank_lines(filedata) + assert file_data == {"data": "phone number\n15555555555"}