Compare commits

..

8 Commits

Author SHA1 Message Date
Kenneth Kehl
050ce753a2 ugh 2025-01-17 10:45:16 -08:00
Kenneth Kehl
038f9aead6 try again 2025-01-16 14:10:56 -08:00
Kenneth Kehl
50e8e4bdb0 try again 2025-01-16 14:05:10 -08:00
Kenneth Kehl
c05b0076fa try again 2025-01-16 13:59:44 -08:00
Kenneth Kehl
2d8d2945b7 try again 2025-01-16 13:45:40 -08:00
Kenneth Kehl
7c9fbe8417 try again 2025-01-16 13:38:06 -08:00
Kenneth Kehl
4519a5a333 try again 2025-01-16 13:31:40 -08:00
Kenneth Kehl
e600087266 initial 2025-01-16 12:00:15 -08:00
17 changed files with 184 additions and 169 deletions

View File

@@ -133,7 +133,7 @@
"filename": ".github/workflows/checks.yml",
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
"is_verified": false,
"line_number": 68,
"line_number": 71,
"is_secret": false
}
],
@@ -684,5 +684,5 @@
}
]
},
"generated_at": "2025-01-16T16:38:48Z"
"generated_at": "2025-01-16T21:38:03Z"
}

View File

@@ -37,7 +37,7 @@ body:
- type: textarea
id: acceptanceCriteria
attributes:
label: "Detailed condition or criteria that must be met for the user story to be considered complete. This includes basic a11y checks around screen readers and keyboard testing."
label: "Detailed condition or criteria that must be met for the user story to be considered complete."
description: "List the acceptance criteria for the user story."
validations:
required: true
@@ -48,7 +48,7 @@ body:
- type: textarea
id: tasks
attributes:
label: "List of specific tasks or sub-tasks that need to be done to implement the user story. This includes a11y standards."
label: "List of specific tasks or sub-tasks that need to be done to implement the user story."
description: "Outline the tasks necessary to implement the user story."
validations:
required: true
@@ -59,7 +59,7 @@ body:
- type: textarea
id: dependencies
attributes:
label: "List any dependencies that need to be resolved before starting or completing this user story. This includes screenreaders and keyboard testing passing."
label: "List any dependencies that need to be resolved before starting or completing this user story."
description: "Specify any dependencies related to the user story."
validations:
required: false

View File

@@ -20,8 +20,3 @@ Please enter a detailed description here.
* Consideration 1
* Consideration 2
* Consideration ...
## A11y Checks (if applicable)
* Conduct automated tests through [AxeDevTools](https://www.deque.com/axe/devtools/) and [WAVE](https://wave.webaim.org/)
* Review the [Manual Checklist](https://docs.google.com/document/d/192bBXStebdXWtYhZQ73qaWMJhGcuSB1W6c9YBXhWZvc/edit?usp=sharing)

View File

@@ -38,10 +38,13 @@ jobs:
output: report-markdown
annotations: failed-tests
prnumber: ${{ steps.findPr.outputs.number }}
- name: Check imports alphabetized
run: poetry run isort ./app ./tests
- name: Check pep8
run: poetry run black ./app ./tests
- name: Run style checks
run: poetry run flake8 .
- name: Check imports alphabetized
run: poetry run isort --check-only ./app ./tests
- name: Check dead code
run: make dead-code
- name: Run js tests

View File

@@ -8,7 +8,7 @@
width: 100%;
max-width: 464px;
box-sizing: border-box;
padding: units(2);
padding: units(1);
background: color('gray-cool-10');
border: 1px solid color('gray-cool-10');
border-radius: 5px;

View File

@@ -1,3 +1,5 @@
import csv
from io import StringIO
import re
from abc import ABC, abstractmethod
@@ -28,6 +30,16 @@ class CsvFileValidator:
self.message = message
def __call__(self, form, field):
data = Spreadsheet.from_file_form(form).as_dict
data = data["data"]
if data is not None and data != "":
csv_file = StringIO(data)
reader = csv.reader(csv_file)
first_line = next(reader, None)
if first_line is None or all(cell.strip() == "" for cell in first_line):
raise ValidationError(f"No headers on row 1 in {field.data.filename}")
if not Spreadsheet.can_handle(field.data.filename):
raise ValidationError(
"{} is not a spreadsheet that Notify can read".format(

View File

@@ -132,6 +132,7 @@ def send_messages(service_id, template_id):
form = CsvUploadForm()
if form.validate_on_submit():
try:
upload_id = s3upload(
service_id,
Spreadsheet.from_file_form(form).as_dict,

View File

@@ -42,7 +42,8 @@ class Spreadsheet:
@staticmethod
def normalise_newlines(file_content):
return "\r\n".join(file_content.read().decode("utf-8").splitlines())
rows = file_content.read().decode("utf-8").splitlines()
return "\r\n".join(rows)
@classmethod
def from_rows(cls, rows, filename=""):

View File

@@ -1,6 +1,3 @@
import json
from app.extensions import redis_client
from app.notify_client import NotifyAdminAPIClient
@@ -18,19 +15,10 @@ class BillingAPIClient(NotifyAdminAPIClient):
)
def get_free_sms_fragment_limit_for_year(self, service_id, year=None):
frag_limit = redis_client.get(f"free-sms-fragment-limit-{service_id}-{year}")
if frag_limit is not None:
return json.loads(frag_limit.decode("utf-8"))
result = self.get(
"/service/{0}/billing/free-sms-fragment-limit".format(service_id),
params=dict(financial_year_start=year),
)
redis_client.set(
f"free-sms-fragment-limit-{service_id}-{year}",
json.dumps(result["free_sms_fragment_limit"]),
ex=30,
)
return result["free_sms_fragment_limit"]
def create_or_update_free_sms_fragment_limit(

View File

@@ -1,4 +1,3 @@
import json
from datetime import datetime, timezone
from app.extensions import redis_client
@@ -518,18 +517,7 @@ class ServiceAPIClient(NotifyAdminAPIClient):
return int(count)
def get_global_notification_count(self, service_id):
notification_count = redis_client.get(f"notification-count-{service_id}")
if notification_count is not None:
return json.loads(notification_count.decode("utf-8"))
notification_count = self.get(
"/service/{}/notification-count".format(service_id)
)
redis_client.set(
f"notification-count-{service_id}", json.dumps(notification_count), ex=30
)
return notification_count
return self.get("/service/{}/notification-count".format(service_id))
def get_service_invite_data(self, redis_key):
"""

View File

@@ -1,6 +1,7 @@
{% extends "base.html" %}
{% set page_title = "About Notify" %}
{% block per_page_title %}
{{page_title}}
{% endblock %}
@@ -26,7 +27,7 @@
{% set product_highlights = [
{
"svg_src": "#send",
"card_heading": "Send customized one-way messages",
"card_heading": "Send customized one-way customized messages",
"p_text": "Upload a file with recipient phone numbers and Notify.gov sends customized messages",
},
{

View File

@@ -51,37 +51,35 @@
{
"image_src": asset_url('images/calendar.svg'),
"card_heading": "Reminders",
"p_text": "Your Quality Control food phone interview is on ((date)) at ((time)). Failure to
"p_text": "In a text bubble // Your Quality Control food phone interview is on ((date)) at ((time)). Failure to
attend may lead to closure of your benefits. Call 1-800-222-3333 with questions.",
"alt_text": "reminder text example"
},
{
"image_src": asset_url('images/alert.svg'),
"card_heading": "Alerts to take action",
"p_text": "Your household's Medicaid coverage is expiring. To keep getting Medicaid, you must
"p_text": "In a text bubble // Your household's Medicaid coverage is expiring. To keep getting Medicaid, you must
complete your renewal by ((date)). You can renew online at dhs.state.gov…",
"alt_text": "alerts text example"
},
{
"image_src": asset_url('images/alarm.svg'),
"card_heading": "Important status updates",
"p_text": "Your passport has been issued at the Los Angeles Passport Agency. Please come to the
"p_text": "In a text bubble // Your passport has been issued at the Los Angeles Passport Agency. Please come to the
desk between 1:30pm and 2:30pm today to pick up your passport…",
"alt_text": "status update text example"
},
] %}
{% for item in card_contents %}
<div class="grid-container-tablet padding-3 radius-lg border-2px margin-left-0 ">
<h3 class="usa-card__heading padding-y-2">{{item.card_heading}}</h3>
<div class="grid-row grid-gap-3 flex-align-center">
<div class="grid-col-auto ">
<p class="sms-message-wrapper">{{item.p_text}}</p>
</div>
<div class="grid-col-fill">
{% if item.image_src %}
<img src="{{ item.image_src }}" alt="{{ item.alt_text }}" class="height-15" />
{% endif %}
<div class="radius-lg border-2px maxw-tablet">
<div class="grid-row grid-gap-4 padding-2 padding-x-3 flex-align-center">
<div class="grid-col flex-3">
<p><b>{{item.card_heading}}</b></p>
<p>{{item.p_text}}</p>
</div>
{% if item.image_src %}
<img src="{{item.image_src}}" alt="{{ item.alt_text }}" class="height-15" />
{% endif %}
</div>
</div>
{% endfor %}

View File

@@ -34,7 +34,7 @@
{% set product_highlights = [
{
"svg_src": "#chat",
"card_heading": "Up to 100,000 messages to use over your first year*",
"card_heading": "Up to 250,000 messages to use over your first year*",
},
{
"svg_src": "#phone",

180
package-lock.json generated
View File

@@ -50,7 +50,7 @@
"jest-environment-jsdom": "^29.2.2",
"jshint": "2.13.6",
"jshint-stylish": "2.2.1",
"rollup": "^4.31.0",
"rollup": "^4.30.1",
"rollup-plugin-commonjs": "10.1.0",
"rollup-plugin-node-resolve": "5.2.0"
},
@@ -2621,247 +2621,228 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.31.0.tgz",
"integrity": "sha512-9NrR4033uCbUBRgvLcBrJofa2KY9DzxL2UKZ1/4xA/mnTNyhZCWBuD8X3tPm1n4KxcgaraOYgrFKSgwjASfmlA==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz",
"integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.31.0.tgz",
"integrity": "sha512-iBbODqT86YBFHajxxF8ebj2hwKm1k8PTBQSojSt3d1FFt1gN+xf4CowE47iN0vOSdnd+5ierMHBbu/rHc7nq5g==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz",
"integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.31.0.tgz",
"integrity": "sha512-WHIZfXgVBX30SWuTMhlHPXTyN20AXrLH4TEeH/D0Bolvx9PjgZnn4H677PlSGvU6MKNsjCQJYczkpvBbrBnG6g==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz",
"integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.31.0.tgz",
"integrity": "sha512-hrWL7uQacTEF8gdrQAqcDy9xllQ0w0zuL1wk1HV8wKGSGbKPVjVUv/DEwT2+Asabf8Dh/As+IvfdU+H8hhzrQQ==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz",
"integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.31.0.tgz",
"integrity": "sha512-S2oCsZ4hJviG1QjPY1h6sVJLBI6ekBeAEssYKad1soRFv3SocsQCzX6cwnk6fID6UQQACTjeIMB+hyYrFacRew==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz",
"integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.31.0.tgz",
"integrity": "sha512-pCANqpynRS4Jirn4IKZH4tnm2+2CqCNLKD7gAdEjzdLGbH1iO0zouHz4mxqg0uEMpO030ejJ0aA6e1PJo2xrPA==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz",
"integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.31.0.tgz",
"integrity": "sha512-0O8ViX+QcBd3ZmGlcFTnYXZKGbFu09EhgD27tgTdGnkcYXLat4KIsBBQeKLR2xZDCXdIBAlWLkiXE1+rJpCxFw==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz",
"integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.31.0.tgz",
"integrity": "sha512-w5IzG0wTVv7B0/SwDnMYmbr2uERQp999q8FMkKG1I+j8hpPX2BYFjWe69xbhbP6J9h2gId/7ogesl9hwblFwwg==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz",
"integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.31.0.tgz",
"integrity": "sha512-JyFFshbN5xwy6fulZ8B/8qOqENRmDdEkcIMF0Zz+RsfamEW+Zabl5jAb0IozP/8UKnJ7g2FtZZPEUIAlUSX8cA==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz",
"integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.31.0.tgz",
"integrity": "sha512-kpQXQ0UPFeMPmPYksiBL9WS/BDiQEjRGMfklVIsA0Sng347H8W2iexch+IEwaR7OVSKtr2ZFxggt11zVIlZ25g==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz",
"integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.31.0.tgz",
"integrity": "sha512-pMlxLjt60iQTzt9iBb3jZphFIl55a70wexvo8p+vVFK+7ifTRookdoXX3bOsRdmfD+OKnMozKO6XM4zR0sHRrQ==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz",
"integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==",
"cpu": [
"loong64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.31.0.tgz",
"integrity": "sha512-D7TXT7I/uKEuWiRkEFbed1UUYZwcJDU4vZQdPTcepK7ecPhzKOYk4Er2YR4uHKme4qDeIh6N3XrLfpuM7vzRWQ==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz",
"integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==",
"cpu": [
"ppc64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.31.0.tgz",
"integrity": "sha512-wal2Tc8O5lMBtoePLBYRKj2CImUCJ4UNGJlLwspx7QApYny7K1cUYlzQ/4IGQBLmm+y0RS7dwc3TDO/pmcneTw==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz",
"integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==",
"cpu": [
"riscv64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.31.0.tgz",
"integrity": "sha512-O1o5EUI0+RRMkK9wiTVpk2tyzXdXefHtRTIjBbmFREmNMy7pFeYXCFGbhKFwISA3UOExlo5GGUuuj3oMKdK6JQ==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz",
"integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==",
"cpu": [
"s390x"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.31.0.tgz",
"integrity": "sha512-zSoHl356vKnNxwOWnLd60ixHNPRBglxpv2g7q0Cd3Pmr561gf0HiAcUBRL3S1vPqRC17Zo2CX/9cPkqTIiai1g==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz",
"integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.31.0.tgz",
"integrity": "sha512-ypB/HMtcSGhKUQNiFwqgdclWNRrAYDH8iMYH4etw/ZlGwiTVxBz2tDrGRrPlfZu6QjXwtd+C3Zib5pFqID97ZA==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz",
"integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.31.0.tgz",
"integrity": "sha512-JuhN2xdI/m8Hr+aVO3vspO7OQfUFO6bKLIRTAy0U15vmWjnZDLrEgCZ2s6+scAYaQVpYSh9tZtRijApw9IXyMw==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz",
"integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.31.0.tgz",
"integrity": "sha512-U1xZZXYkvdf5MIWmftU8wrM5PPXzyaY1nGCI4KI4BFfoZxHamsIe+BtnPLIvvPykvQWlVbqUXdLa4aJUuilwLQ==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz",
"integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==",
"cpu": [
"ia32"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.31.0.tgz",
"integrity": "sha512-ul8rnCsUumNln5YWwz0ted2ZHFhzhRRnkpBZ+YRuHoRAlUji9KChpOUOndY7uykrPEPXVbHLlsdo6v5yXo/TXw==",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz",
"integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
@@ -12742,10 +12723,9 @@
"license": "Unlicense"
},
"node_modules/rollup": {
"version": "4.31.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.31.0.tgz",
"integrity": "sha512-9cCE8P4rZLx9+PjoyqHLs31V9a9Vpvfo4qNcs6JCiGWYhw2gijSetFbH6SSy1whnkgcefnUwr8sad7tgqsGvnw==",
"license": "MIT",
"version": "4.30.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz",
"integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==",
"dependencies": {
"@types/estree": "1.0.6"
},
@@ -12757,25 +12737,25 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.31.0",
"@rollup/rollup-android-arm64": "4.31.0",
"@rollup/rollup-darwin-arm64": "4.31.0",
"@rollup/rollup-darwin-x64": "4.31.0",
"@rollup/rollup-freebsd-arm64": "4.31.0",
"@rollup/rollup-freebsd-x64": "4.31.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.31.0",
"@rollup/rollup-linux-arm-musleabihf": "4.31.0",
"@rollup/rollup-linux-arm64-gnu": "4.31.0",
"@rollup/rollup-linux-arm64-musl": "4.31.0",
"@rollup/rollup-linux-loongarch64-gnu": "4.31.0",
"@rollup/rollup-linux-powerpc64le-gnu": "4.31.0",
"@rollup/rollup-linux-riscv64-gnu": "4.31.0",
"@rollup/rollup-linux-s390x-gnu": "4.31.0",
"@rollup/rollup-linux-x64-gnu": "4.31.0",
"@rollup/rollup-linux-x64-musl": "4.31.0",
"@rollup/rollup-win32-arm64-msvc": "4.31.0",
"@rollup/rollup-win32-ia32-msvc": "4.31.0",
"@rollup/rollup-win32-x64-msvc": "4.31.0",
"@rollup/rollup-android-arm-eabi": "4.30.1",
"@rollup/rollup-android-arm64": "4.30.1",
"@rollup/rollup-darwin-arm64": "4.30.1",
"@rollup/rollup-darwin-x64": "4.30.1",
"@rollup/rollup-freebsd-arm64": "4.30.1",
"@rollup/rollup-freebsd-x64": "4.30.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.30.1",
"@rollup/rollup-linux-arm-musleabihf": "4.30.1",
"@rollup/rollup-linux-arm64-gnu": "4.30.1",
"@rollup/rollup-linux-arm64-musl": "4.30.1",
"@rollup/rollup-linux-loongarch64-gnu": "4.30.1",
"@rollup/rollup-linux-powerpc64le-gnu": "4.30.1",
"@rollup/rollup-linux-riscv64-gnu": "4.30.1",
"@rollup/rollup-linux-s390x-gnu": "4.30.1",
"@rollup/rollup-linux-x64-gnu": "4.30.1",
"@rollup/rollup-linux-x64-musl": "4.30.1",
"@rollup/rollup-win32-arm64-msvc": "4.30.1",
"@rollup/rollup-win32-ia32-msvc": "4.30.1",
"@rollup/rollup-win32-x64-msvc": "4.30.1",
"fsevents": "~2.3.2"
}
},

View File

@@ -66,7 +66,7 @@
"jest-environment-jsdom": "^29.2.2",
"jshint": "2.13.6",
"jshint-stylish": "2.2.1",
"rollup": "^4.31.0",
"rollup": "^4.30.1",
"rollup-plugin-commonjs": "10.1.0",
"rollup-plugin-node-resolve": "5.2.0"
}

View File

@@ -898,6 +898,67 @@ def test_upload_csv_invalid_extension(
assert "invalid.txt is not a spreadsheet that Notify can read" in page.text
@pytest.mark.parametrize(
("file_contents", "expected_error"),
[
(
"""
phone number, name
+12028675109, example
+12028675109,
+12028675109, example
""",
(
"Theres a problem with example.csv "
"You need to put the column headers in row 1."
),
),
],
)
def test_upload_csv_file_with_extra_blank_lines_is_flagged(
client_request,
mocker,
mock_get_service_template_with_placeholders,
mock_get_users_by_service,
mock_get_service_statistics,
mock_get_job_doesnt_exist,
mock_get_jobs,
service_one,
fake_uuid,
file_contents,
expected_error,
):
mocker.patch("app.main.views.send.set_metadata_on_csv_upload")
mocker.patch(
"app.main.views.send.get_csv_metadata",
return_value={"original_file_name": "example.csv"},
)
mocker.patch("app.main.views.send.s3upload", return_value=sample_uuid())
mocker.patch("app.main.views.send.s3download", return_value=file_contents)
page = client_request.post(
"main.send_messages",
service_id=service_one["id"],
template_id=fake_uuid,
_data={"file": (BytesIO("".encode("utf-8")), "example.csv")},
_follow_redirects=True,
)
with client_request.session_transaction() as session:
assert "file_uploads" not in session
assert page.select_one("input[type=file]").has_attr("accept")
assert (
page.select_one("input[type=file]")["accept"]
== ".csv,.xlsx,.xls,.ods,.xlsm,.tsv"
)
assert normalize_spaces(page.select(".banner-dangerous")[0].text) == expected_error
def test_upload_csv_size_too_big(
client_request,
mock_login,

View File

@@ -10,15 +10,7 @@ def test_get_free_sms_fragment_limit_for_year_correct_endpoint(mocker, api_user_
expected_url = "/service/{}/billing/free-sms-fragment-limit".format(service_id)
client = BillingAPIClient()
mock_get = mocker.patch(
"app.notify_client.billing_api_client.BillingAPIClient.get",
return_value={"free_sms_fragment_limit": 0},
)
mocker.patch(
"app.notify_client.billing_api_client.redis_client.get", return_value=None
)
mocker.patch("app.notify_client.billing_api_client.redis_client.set")
mock_get = mocker.patch("app.notify_client.billing_api_client.BillingAPIClient.get")
client.get_free_sms_fragment_limit_for_year(service_id, year=1999)
mock_get.assert_called_once_with(
@@ -36,11 +28,6 @@ def test_post_free_sms_fragment_limit_for_current_year_endpoint(
)
client = BillingAPIClient()
mocker.patch(
"app.notify_client.billing_api_client.redis_client.get", return_value=None
)
mocker.patch("app.notify_client.billing_api_client.redis_client.set")
client.create_or_update_free_sms_fragment_limit(
service_id=service_id, free_sms_fragment_limit=1111
)