From 0021d6425332ab81cdcf1e8f73ae6669416c5504 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Tue, 30 Jan 2024 15:23:21 -0500 Subject: [PATCH 001/195] 1166 - Adjusting the card width and wrapping styles --- app/assets/javascripts/collapsibleCheckboxes.js | 2 +- .../sass/uswds/_uswds-theme-custom-styles.scss | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/collapsibleCheckboxes.js b/app/assets/javascripts/collapsibleCheckboxes.js index f67cad80a..93645f002 100644 --- a/app/assets/javascripts/collapsibleCheckboxes.js +++ b/app/assets/javascripts/collapsibleCheckboxes.js @@ -65,7 +65,7 @@ return $(`
- {% endif %} -
- + {% if current_user.is_authenticated %} + + {% endif %} + + + From 80135b2ff647567d41773ea1960815be48ac0a23 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 5 Feb 2024 12:27:40 -0800 Subject: [PATCH 009/195] notify-api-771 fix columns in reports --- app/utils/csv.py | 62 ++++++++++++++++++------------------- tests/app/utils/test_csv.py | 48 +++++++++++++--------------- 2 files changed, 51 insertions(+), 59 deletions(-) diff --git a/app/utils/csv.py b/app/utils/csv.py index 7cfcb8975..9531e0b5d 100644 --- a/app/utils/csv.py +++ b/app/utils/csv.py @@ -78,21 +78,21 @@ def generate_notifications_csv(**kwargs): template=get_sample_template(kwargs["template_type"]), ) original_column_headers = original_upload.column_headers - fieldnames = ( - ["Row number"] - + original_column_headers - + [ - "Template", - "Type", - "Sent by", - "Job", - "Carrier", - "Carrier Response", - "Status", - "Time", - ] - ) + fieldnames = [ + "Template", + "Type", + "Sent by", + "Job", + "Carrier", + "Carrier Response", + "Status", + "Time", + ] + for header in original_column_headers: + fieldnames.append(header) + else: + # TODO This is deprecated because everything should be a job now, is it ever invoked? fieldnames = [ "Recipient", "Template", @@ -104,6 +104,7 @@ def generate_notifications_csv(**kwargs): "Status", "Time", ] + current_app.logger.warning("Invoking deprecated report format") yield ",".join(fieldnames) + "\n" @@ -118,26 +119,23 @@ def generate_notifications_csv(**kwargs): current_app.logger.info(f"\n\n{notification}") if kwargs.get("job_id"): - values = ( - [ - notification["row_number"], - ] - + [ + values = [ + notification["template_name"], + notification["template_type"], + notification["created_by_name"], + notification["job_name"], + notification["carrier"], + notification["provider_response"], + notification["status"], + preferred_tz_created_at, + ] + for header in original_column_headers: + values.append( original_upload[notification["row_number"] - 1].get(header).data - for header in original_column_headers - ] - + [ - notification["template_name"], - notification["template_type"], - notification["created_by_name"], - notification["job_name"], - notification["carrier"], - notification["provider_response"], - notification["status"], - preferred_tz_created_at, - ] - ) + ) + else: + # TODO This is deprecated, should not be invoked. See above values = [ notification["recipient"], notification["template_name"], diff --git a/tests/app/utils/test_csv.py b/tests/app/utils/test_csv.py index b237d8ad5..c39414ae5 100644 --- a/tests/app/utils/test_csv.py +++ b/tests/app/utils/test_csv.py @@ -46,9 +46,6 @@ def _get_notifications_csv( "notifications": [ { "row_number": row_number + i, - "to": recipient, - "recipient": recipient, - "client_reference": "ref 1234", "template_name": template_name, "template_type": template_type, "template": {"name": template_name, "template_type": template_type}, @@ -60,6 +57,9 @@ def _get_notifications_csv( "updated_at": None, "created_by_name": created_by_name, "created_by_email_address": created_by_email_address, + "to": recipient, + "recipient": recipient, + "client_reference": "ref 1234", } for i in range(rows) ], @@ -130,8 +130,6 @@ def test_generate_notifications_csv_without_job( 2028675309 """, [ - "Row number", - "phone_number", "Template", "Type", "Sent by", @@ -140,10 +138,9 @@ def test_generate_notifications_csv_without_job( "Carrier Response", "Status", "Time", + "phone_number", ], [ - "1", - "2028675309", "foo", "sms", "Fake Person", @@ -152,6 +149,7 @@ def test_generate_notifications_csv_without_job( "Did not like it", "Delivered", "1943-04-19 08:00:00 AM US/Eastern", + "2028675309", ], ), ( @@ -160,11 +158,6 @@ def test_generate_notifications_csv_without_job( 2028675309, 🐜,🐝,🦀 """, [ - "Row number", - "phone_number", - "a", - "b", - "c", "Template", "Type", "Sent by", @@ -173,13 +166,12 @@ def test_generate_notifications_csv_without_job( "Carrier Response", "Status", "Time", + "phone_number", + "a", + "b", + "c", ], [ - "1", - "2028675309", - "🐜", - "🐝", - "🦀", "foo", "sms", "Fake Person", @@ -188,6 +180,10 @@ def test_generate_notifications_csv_without_job( "Did not like it", "Delivered", "1943-04-19 08:00:00 AM US/Eastern", + "2028675309", + "🐜", + "🐝", + "🦀", ], ), ( @@ -196,11 +192,6 @@ def test_generate_notifications_csv_without_job( "2028675309","🐜,🐜","🐝,🐝","🦀" """, [ - "Row number", - "phone_number", - "a", - "b", - "c", "Template", "Type", "Sent by", @@ -209,13 +200,12 @@ def test_generate_notifications_csv_without_job( "Carrier Response", "Status", "Time", + "phone_number", + "a", + "b", + "c", ], [ - "1", - "2028675309", - "🐜,🐜", - "🐝,🐝", - "🦀", "foo", "sms", "Fake Person", @@ -224,6 +214,10 @@ def test_generate_notifications_csv_without_job( "Did not like it", "Delivered", "1943-04-19 08:00:00 AM US/Eastern", + "2028675309", + "🐜,🐜", + "🐝,🐝", + "🦀", ], ), ], From d6f012ee9e0106df05286d0deeff6c0a12de4af7 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 6 Feb 2024 16:08:14 -0800 Subject: [PATCH 010/195] editing and creating new preview functions and backlinks --- app/assets/sass/uswds/_legacy-styles.scss | 4 +- app/main/views/send.py | 117 +++++++++++------- app/templates/views/check/ok.html | 41 +----- app/templates/views/check/preview.html | 38 ++---- app/templates/views/notifications/check.html | 11 +- .../views/notifications/preview.html | 65 ++++++++++ 6 files changed, 153 insertions(+), 123 deletions(-) create mode 100644 app/templates/views/notifications/preview.html diff --git a/app/assets/sass/uswds/_legacy-styles.scss b/app/assets/sass/uswds/_legacy-styles.scss index 3b09e2218..a4a6e3d2c 100644 --- a/app/assets/sass/uswds/_legacy-styles.scss +++ b/app/assets/sass/uswds/_legacy-styles.scss @@ -54,7 +54,7 @@ .sms-message-recipient { color: color('gray-cool-90'); - margin: 0 0 units(1); + margin: units(1) 0 units(1); } .sms-message-status { @@ -131,7 +131,7 @@ &-label, &-button-label { font-weight: bold; - font-size: 19px; + font-size: 19px; display: block; margin: 0 0 10px 0; } diff --git a/app/main/views/send.py b/app/main/views/send.py index 6c014b102..96389898b 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -527,11 +527,17 @@ def _check_messages(service_id, template_id, upload_id, preview_row): back_link = url_for( "main.send_one_off", service_id=service_id, template_id=template.id ) + back_link_from_preview = url_for( + "main.send_one_off", service_id=service_id, template_id=template.id + ) choose_time_form = None else: back_link = url_for( "main.send_messages", service_id=service_id, template_id=template.id ) + back_link_from_preview = url_for( + "main.check_messages", service_id=service_id, template_id=template.id, upload_id=upload_id + ) choose_time_form = ChooseTimeForm() if preview_row < 2: @@ -559,6 +565,7 @@ def _check_messages(service_id, template_id, upload_id, preview_row): remaining_messages=remaining_messages, choose_time_form=choose_time_form, back_link=back_link, + back_link_from_preview=back_link_from_preview, first_recipient_column=recipients.recipient_column_headers[0], preview_row=preview_row, sent_previously=job_api_client.has_sent_previously( @@ -612,6 +619,34 @@ def check_messages(service_id, template_id, upload_id, row_index=2): return render_template("views/check/ok.html", **data) +@main.route( + "/services///check//preview", + methods=["POST"], +) +@user_has_permissions("send_messages", restrict_admin_usage=True) +def preview_job(service_id, template_id, upload_id, row_index=2): + session['scheduled_for'] = request.form.get('scheduled_for', 'Not specified') + data = _check_messages(service_id, template_id, upload_id, row_index) + data["allowed_file_extensions"] = Spreadsheet.ALLOWED_FILE_EXTENSIONS + if ( + data["recipients"].too_many_rows + or not data["count_of_recipients"] + or not data["recipients"].has_recipient_columns + or data["recipients"].duplicate_recipient_column_headers + or data["recipients"].missing_column_headers + or data["sent_previously"] + ): + return render_template("views/check/column-errors.html", **data) + + if data["row_errors"]: + return render_template("views/check/row-errors.html", **data) + + if data["errors"]: + return render_template("views/check/column-errors.html", **data) + + return render_template('views/check/preview.html', scheduled_for=session['scheduled_for'], **data, +) + @main.route("/services//start-job/", methods=["POST"]) @user_has_permissions("send_messages", restrict_admin_usage=True) def start_job(service_id, upload_id): @@ -633,49 +668,6 @@ def start_job(service_id, upload_id): ) -@main.route( - "/services///check//preview", - methods=["POST"], -) -@user_has_permissions("send_messages", restrict_admin_usage=True) -def preview_job(service_id, template_id, upload_id, row_index=2): - # Store form data in session temporarily - session['scheduled_for'] = request.form.get('scheduled_for', 'Not specified') - # session.pop("sender_id", None) - data = _check_messages(service_id, template_id, upload_id, row_index) - data["allowed_file_extensions"] = Spreadsheet.ALLOWED_FILE_EXTENSIONS - - if ( - data["recipients"].too_many_rows - or not data["count_of_recipients"] - or not data["recipients"].has_recipient_columns - or data["recipients"].duplicate_recipient_column_headers - or data["recipients"].missing_column_headers - or data["sent_previously"] - ): - return render_template("views/check/column-errors.html", **data) - - if data["row_errors"]: - return render_template("views/check/row-errors.html", **data) - - if data["errors"]: - return render_template("views/check/column-errors.html", **data) - - metadata_kwargs = { - "notification_count": data["count_of_recipients"], - "template_id": template_id, - "valid": True, - "original_file_name": data.get("original_file_name", ""), - } - - if session.get("sender_id"): - metadata_kwargs["sender_id"] = session["sender_id"] - - set_metadata_on_csv_upload(service_id, upload_id, **metadata_kwargs) - - return render_template('views/check/preview.html', data=session['scheduled_for'], **data, metadata_kwargs=metadata_kwargs) - - def fields_to_fill_in(template, prefill_current_user=False): if not prefill_current_user: return first_column_headings[template.template_type] + list( @@ -721,7 +713,15 @@ def get_send_test_page_title(template_type, entering_recipient, name=None): return "Personalize this message" -def get_back_link(service_id, template, step_index, placeholders=None): +def get_back_link(service_id, template, step_index, placeholders=None, preview=False,): + if preview: + return url_for( + "main.check_notification", + service_id=service_id, + template_id=template.id, + ) + + if step_index == 0: if should_skip_template_page(template._template): return url_for( @@ -826,6 +826,8 @@ def _check_notification(service_id, template_id, exception=None): back_link = get_back_link(service_id, template, len(placeholders), placeholders) + back_link_from_preview = get_back_link(service_id, template, len(placeholders), placeholders, preview=True) + choose_time_form = ChooseTimeForm() if (not session.get("recipient")) or not all_placeholders_in_session( @@ -839,6 +841,7 @@ def _check_notification(service_id, template_id, exception=None): return dict( template=template, back_link=back_link, + back_link_from_preview=back_link_from_preview, choose_time_form=choose_time_form, **(get_template_error_dict(exception) if exception else {}), ) @@ -869,6 +872,29 @@ def get_template_error_dict(exception): "original_file_name": False, } +@main.route( + "/services//template//notification/check/preview", + methods=["POST"], +) +@user_has_permissions("send_messages", restrict_admin_usage=True) +def preview_notification(service_id, template_id): + recipient = get_recipient() + if not recipient: + return redirect( + url_for( + ".send_one_off", + service_id=service_id, + template_id=template_id, + ) + ) + + session['scheduled_for'] = request.form.get('scheduled_for', 'Not specified') + + return render_template( + "views/notifications/preview.html", + **_check_notification(service_id, template_id), data=session['scheduled_for'] + ) + @main.route( "/services//template//notification/check", @@ -876,6 +902,7 @@ def get_template_error_dict(exception): ) @user_has_permissions("send_messages", restrict_admin_usage=True) def send_notification(service_id, template_id): + scheduled_for = session.pop('scheduled_for', None) recipient = get_recipient() if not recipient: return redirect( @@ -910,7 +937,7 @@ def send_notification(service_id, template_id): job_api_client.create_job( upload_id, service_id, - scheduled_for=request.form.get("scheduled_for", ""), + scheduled_for=scheduled_for, template_id=template_id, original_file_name=filename, notification_count=1, diff --git a/app/templates/views/check/ok.html b/app/templates/views/check/ok.html index 6fc96f73b..f70b6232e 100644 --- a/app/templates/views/check/ok.html +++ b/app/templates/views/check/ok.html @@ -41,50 +41,11 @@

{{ original_file_name }}

{% endif %} {% set button_text %} - Preview send - + Preview {% endset %} {{ usaButton({ "text": button_text }) }} - - - {% endblock %} diff --git a/app/templates/views/check/preview.html b/app/templates/views/check/preview.html index 1c07bffc6..c7b303a8a 100644 --- a/app/templates/views/check/preview.html +++ b/app/templates/views/check/preview.html @@ -14,35 +14,23 @@ {% block backLink %} - {{ usaBackLink({ "href": back_link }) }} + {{ usaBackLink({ "href": back_link_from_preview }) }} {% endblock %} {% block maincolumn_content %} - {{ page_header('Send messages') }} + {{ page_header('Preview') }}

Message

- {% if data %} -

Time: {{data | format_datetime_short_america}}

+ {% if scheduled_for %} +

Time: {{scheduled_for}}

{% endif %} -

File: {{metadata_kwargs.original_file_name}}

+

File: {{original_file_name}}

{{ template|string }}
- - - - {% endblock %} diff --git a/app/templates/views/notifications/check.html b/app/templates/views/notifications/check.html index 5bc970f9b..fec77f779 100644 --- a/app/templates/views/notifications/check.html +++ b/app/templates/views/notifications/check.html @@ -40,17 +40,16 @@ {% endcall %} {% else %} - {{ page_header('Preview of ‘{}’'.format(template.name)) }} + {{ page_header('Select delivery time') }} {% endif %} {{ template|string }}
diff --git a/app/templates/views/notifications/preview.html b/app/templates/views/notifications/preview.html new file mode 100644 index 000000000..868caefd3 --- /dev/null +++ b/app/templates/views/notifications/preview.html @@ -0,0 +1,65 @@ +{% extends "withnav_template.html" %} +{% from "components/banner.html" import banner_wrapper %} +{% from "components/page-header.html" import page_header %} +{% from "components/components/back-link/macro.njk" import usaBackLink %} +{% from "components/components/button/macro.njk" import usaButton %} + +{% block service_page_title %} + {{ "Error" if error else "Preview of ‘{}’".format(template.name) }} +{% endblock %} + +{% block backLink %} + {{ usaBackLink({ "href": back_link_from_preview }) }} +{% endblock %} + +{% block maincolumn_content %} + {% if error == 'not-allowed-to-send-to' %} +
+ {% call banner_wrapper(type='dangerous') %} + {% with + count_of_recipients=1, + template_type_label=( + 'phone number' if template.template_type == 'sms' else 'email address' + ) + %} + {% include "partials/check/not-allowed-to-send-to.html" %} + {% endwith %} + {% endcall %} +
+ {% elif error == 'too-many-messages' %} +
+ {% call banner_wrapper(type='dangerous') %} + {% include "partials/check/too-many-messages.html" %} + {% endcall %} +
+ {% elif error == 'message-too-long' %} + {# the only row_errors we can get when sending one off messages is that the message is too long #} +
+ {% call banner_wrapper(type='dangerous') %} + {% include "partials/check/message-too-long.html" %} + {% endcall %} +
+ {% else %} + {{ page_header('Preview of ‘{}’'.format(template.name)) }} + {% endif %} + + {{ template|string }} + +
+ +
+ +{% endblock %} From 8eb329b444bc01c00171fb4af3829615d46f07c5 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 6 Feb 2024 16:42:11 -0800 Subject: [PATCH 011/195] removing comments --- app/main/views/send.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/main/views/send.py b/app/main/views/send.py index a07a9009e..59d3ff386 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -13,7 +13,6 @@ from notifications_utils.recipients import RecipientCSV, first_column_headings from notifications_utils.sanitise_text import SanitiseASCII from xlrd.biffh import XLRDError from xlrd.xldate import XLDateError -from pprint import pprint from app import ( current_service, From 15105bf5061ba46d490f6549e1700dd27be8091f Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 6 Feb 2024 17:06:18 -0800 Subject: [PATCH 012/195] fixed style checks --- app/main/views/send.py | 7 ++++--- app/templates/views/check/preview.html | 3 +-- app/templates/views/notifications/preview.html | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/main/views/send.py b/app/main/views/send.py index 59d3ff386..bc527ae10 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -614,7 +614,7 @@ def check_messages(service_id, template_id, upload_id, row_index=2): metadata_kwargs["sender_id"] = session["sender_id"] set_metadata_on_csv_upload(service_id, upload_id, **metadata_kwargs) - session['scheduled_for']=request.form.get("scheduled_for", "") + session['scheduled_for'] = request.form.get("scheduled_for", "") return render_template("views/check/ok.html", **data) @@ -644,7 +644,8 @@ def preview_job(service_id, template_id, upload_id, row_index=2): return render_template("views/check/column-errors.html", **data) return render_template('views/check/preview.html', scheduled_for=session['scheduled_for'], **data, -) + ) + @main.route("/services//start-job/", methods=["POST"]) @user_has_permissions("send_messages", restrict_admin_usage=True) @@ -720,7 +721,6 @@ def get_back_link(service_id, template, step_index, placeholders=None, preview=F template_id=template.id, ) - if step_index == 0: if should_skip_template_page(template._template): return url_for( @@ -871,6 +871,7 @@ def get_template_error_dict(exception): "original_file_name": False, } + @main.route( "/services//template//notification/check/preview", methods=["POST"], diff --git a/app/templates/views/check/preview.html b/app/templates/views/check/preview.html index c7b303a8a..caab43cad 100644 --- a/app/templates/views/check/preview.html +++ b/app/templates/views/check/preview.html @@ -63,8 +63,7 @@ {% endcall %}
{% endif %} - +

This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

Does everything look good?

{% set button_text %} Send diff --git a/app/templates/views/notifications/preview.html b/app/templates/views/notifications/preview.html index 868caefd3..dd009fdcb 100644 --- a/app/templates/views/notifications/preview.html +++ b/app/templates/views/notifications/preview.html @@ -53,6 +53,8 @@ help='3' if help else 0 )}}" class='page-footer'> +

This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

+

Does everything look good?

{% if not error %} {% set button_text %} Send From fbf902e1684c1b645249ff8fd34e4a52740bdbe6 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 6 Feb 2024 17:14:46 -0800 Subject: [PATCH 013/195] fixed style checks --- app/main/views/send.py | 3 +-- app/templates/views/check/preview.html | 2 +- app/templates/views/notifications/preview.html | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/main/views/send.py b/app/main/views/send.py index bc527ae10..d81eca83d 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -643,8 +643,7 @@ def preview_job(service_id, template_id, upload_id, row_index=2): if data["errors"]: return render_template("views/check/column-errors.html", **data) - return render_template('views/check/preview.html', scheduled_for=session['scheduled_for'], **data, - ) + return render_template('views/check/preview.html', scheduled_for=session['scheduled_for'], **data) @main.route("/services//start-job/", methods=["POST"]) diff --git a/app/templates/views/check/preview.html b/app/templates/views/check/preview.html index caab43cad..8dd40e612 100644 --- a/app/templates/views/check/preview.html +++ b/app/templates/views/check/preview.html @@ -63,7 +63,7 @@ {% endcall %} {% endif %} -

This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

+

Placeholder: This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

Does everything look good?

{% set button_text %} Send diff --git a/app/templates/views/notifications/preview.html b/app/templates/views/notifications/preview.html index dd009fdcb..468e91f3b 100644 --- a/app/templates/views/notifications/preview.html +++ b/app/templates/views/notifications/preview.html @@ -53,7 +53,7 @@ help='3' if help else 0 )}}" class='page-footer'> -

This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

+

Placeholder: This message will be delivered to 400 phone numbers and will use a total of 800 message parts, leaving Washington DSHS with 249,200 message parts remaining.

Does everything look good?

{% if not error %} {% set button_text %} From 456091996e33b51e53c52f2a322df7696490dfff Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Wed, 7 Feb 2024 13:57:21 -0500 Subject: [PATCH 014/195] 1190 - bug - URL not wrapping in table --- app/assets/sass/uswds/_uswds-theme-custom-styles.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss index b5f2147cd..8e841d225 100644 --- a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss +++ b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss @@ -354,6 +354,7 @@ td.table-empty-message { } .file-list-hint { margin: 0; + word-break: break-word; } .table-field, .table-field-right-aligned { width: 50%; From 330fad469e21ddb1d8b695213e82097ffc6ad759 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 7 Feb 2024 12:14:00 -0800 Subject: [PATCH 015/195] make ChooseTimeForm time zone aware --- app/main/forms.py | 2 +- tests/app/main/forms/test_choose_time_form.py | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index d9a35b72a..76b695dd8 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -70,7 +70,7 @@ from app.utils.user_permissions import all_ui_permissions, permission_options def get_time_value_and_label(future_time): preferred_tz = pytz.timezone(get_user_preferred_timezone()) return ( - future_time.astimezone(preferred_tz).replace(tzinfo=None).isoformat(), + future_time.astimezone(preferred_tz).isoformat(), "{} at {} {}".format( get_human_day(future_time.astimezone(preferred_tz)), get_human_time(future_time.astimezone(preferred_tz)), diff --git a/tests/app/main/forms/test_choose_time_form.py b/tests/app/main/forms/test_choose_time_form.py index e87c96744..4f8b13aa4 100644 --- a/tests/app/main/forms/test_choose_time_form.py +++ b/tests/app/main/forms/test_choose_time_form.py @@ -10,21 +10,21 @@ def test_form_contains_next_24h(notify_admin): # Friday assert choices[0] == ("", "Now") - assert choices[1] == ("2016-01-01T07:00:00", "Today at 7am US/Eastern") - assert choices[13] == ("2016-01-01T19:00:00", "Today at 7pm US/Eastern") + assert choices[1] == ("2016-01-01T07:00:00-05:00", "Today at 7am US/Eastern") + assert choices[13] == ("2016-01-01T19:00:00-05:00", "Today at 7pm US/Eastern") # Saturday - assert choices[14] == ("2016-01-01T20:00:00", "Today at 8pm US/Eastern") - assert choices[37] == ("2016-01-02T19:00:00", "Tomorrow at 7pm US/Eastern") + assert choices[14] == ("2016-01-01T20:00:00-05:00", "Today at 8pm US/Eastern") + assert choices[37] == ("2016-01-02T19:00:00-05:00", "Tomorrow at 7pm US/Eastern") # Sunday - assert choices[38] == ("2016-01-02T20:00:00", "Tomorrow at 8pm US/Eastern") + assert choices[38] == ("2016-01-02T20:00:00-05:00", "Tomorrow at 8pm US/Eastern") # Monday - assert choices[62] == ("2016-01-03T20:00:00", "Sunday at 8pm US/Eastern") - assert choices[80] == ("2016-01-04T14:00:00", "Monday at 2pm US/Eastern") - assert choices[84] == ("2016-01-04T18:00:00", "Monday at 6pm US/Eastern") - assert choices[85] == ("2016-01-04T19:00:00", "Monday at 7pm US/Eastern") + assert choices[62] == ("2016-01-03T20:00:00-05:00", "Sunday at 8pm US/Eastern") + assert choices[80] == ("2016-01-04T14:00:00-05:00", "Monday at 2pm US/Eastern") + assert choices[84] == ("2016-01-04T18:00:00-05:00", "Monday at 6pm US/Eastern") + assert choices[85] == ("2016-01-04T19:00:00-05:00", "Monday at 7pm US/Eastern") with pytest.raises(IndexError): assert choices[ From fb469545b48cc09c6441fd8ecaaddd645f7bd1e5 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Thu, 8 Feb 2024 12:09:01 -0500 Subject: [PATCH 016/195] 1154 - pushing up this change so Ken can take a look --- app/main/forms.py | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index d9a35b72a..6f22734d2 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1239,22 +1239,27 @@ class ChangeNameForm(StripWhitespaceForm): class ChangePreferredTimezoneForm(StripWhitespaceForm): def __init__(self, *args, **kwargs): super(ChangePreferredTimezoneForm, self).__init__(*args, **kwargs) - self.new_preferred_timezone.choices = [ - ("America/Puerto_Rico", "America/Puerto_Rico"), - ("US/Eastern", "US/Eastern"), - ("US/Central", "US/Central"), - ("US/Mountain", "US/Mountain"), - ("US/Pacific", "US/Pacific"), - ("US/Alaska", "US/Alaska"), - ("US/Hawaii", "US/Hawaii"), - ("US/Aleutian", "US/Aleutian"), - ("US/Samoa", "US/Samoa"), - ] - new_preferred_timezone = GovukRadiosField( - "What timezone would you like to use?", - default="US/Eastern", - ) + # Get the current preferred timezone from the form data + current_timezone = kwargs.get('obj', None).new_preferred_timezone if 'obj' in kwargs else "US/Eastern" + + # Set the choices + self.new_preferred_timezone = GovukRadiosField( + label="What timezone would you like to use?", + choices=[ + ("America/Puerto_Rico", "America/Puerto_Rico"), + ("US/Eastern", "US/Eastern"), + ("US/Central", "US/Central"), + ("US/Mountain", "US/Mountain"), + ("US/Pacific", "US/Pacific"), + ("US/Alaska", "US/Alaska"), + ("US/Hawaii", "US/Hawaii"), + ("US/Aleutian", "US/Aleutian"), + ("US/Samoa", "US/Samoa"), + ], + default=current_timezone + ) + class ChangeEmailForm(StripWhitespaceForm): From 7832797628acee9a7e976f6abc892f4d284af469 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Thu, 8 Feb 2024 15:10:07 -0500 Subject: [PATCH 017/195] Just removing the default selection --- app/main/forms.py | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index 6f22734d2..93ccd8a55 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -1239,27 +1239,21 @@ class ChangeNameForm(StripWhitespaceForm): class ChangePreferredTimezoneForm(StripWhitespaceForm): def __init__(self, *args, **kwargs): super(ChangePreferredTimezoneForm, self).__init__(*args, **kwargs) + self.new_preferred_timezone.choices = [ + ("America/Puerto_Rico", "America/Puerto_Rico"), + ("US/Eastern", "US/Eastern"), + ("US/Central", "US/Central"), + ("US/Mountain", "US/Mountain"), + ("US/Pacific", "US/Pacific"), + ("US/Alaska", "US/Alaska"), + ("US/Hawaii", "US/Hawaii"), + ("US/Aleutian", "US/Aleutian"), + ("US/Samoa", "US/Samoa"), + ] - # Get the current preferred timezone from the form data - current_timezone = kwargs.get('obj', None).new_preferred_timezone if 'obj' in kwargs else "US/Eastern" - - # Set the choices - self.new_preferred_timezone = GovukRadiosField( - label="What timezone would you like to use?", - choices=[ - ("America/Puerto_Rico", "America/Puerto_Rico"), - ("US/Eastern", "US/Eastern"), - ("US/Central", "US/Central"), - ("US/Mountain", "US/Mountain"), - ("US/Pacific", "US/Pacific"), - ("US/Alaska", "US/Alaska"), - ("US/Hawaii", "US/Hawaii"), - ("US/Aleutian", "US/Aleutian"), - ("US/Samoa", "US/Samoa"), - ], - default=current_timezone - ) - + new_preferred_timezone = GovukRadiosField( + "What timezone would you like to use?", + ) class ChangeEmailForm(StripWhitespaceForm): From b019dc3fe9cfd4ca944a491b4a94a8956941fb3c Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Thu, 8 Feb 2024 18:43:17 -0800 Subject: [PATCH 018/195] updated pytest --- app/assets/sass/uswds/_legacy-styles.scss | 2 +- app/main/views/send.py | 43 ++++++--- app/templates/views/check/ok.html | 6 +- app/templates/views/check/preview.html | 6 +- app/templates/views/notifications/check.html | 5 +- tests/app/main/views/test_conversation.py | 2 +- tests/app/main/views/test_send.py | 97 ++++++++++++-------- tests/app/main/views/test_tour.py | 3 +- tests/app/test_navigation.py | 2 + 9 files changed, 102 insertions(+), 64 deletions(-) diff --git a/app/assets/sass/uswds/_legacy-styles.scss b/app/assets/sass/uswds/_legacy-styles.scss index a4a6e3d2c..242bb0f74 100644 --- a/app/assets/sass/uswds/_legacy-styles.scss +++ b/app/assets/sass/uswds/_legacy-styles.scss @@ -48,7 +48,7 @@ } } -.sms-message-sender { +.sms-message-sender, .sms-message-file-name, .sms-message-scheduler { margin: units(1) 0 0; } diff --git a/app/main/views/send.py b/app/main/views/send.py index d81eca83d..90834d965 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -535,7 +535,10 @@ def _check_messages(service_id, template_id, upload_id, preview_row): "main.send_messages", service_id=service_id, template_id=template.id ) back_link_from_preview = url_for( - "main.check_messages", service_id=service_id, template_id=template.id, upload_id=upload_id + "main.check_messages", + service_id=service_id, + template_id=template.id, + upload_id=upload_id, ) choose_time_form = ChooseTimeForm() @@ -570,7 +573,7 @@ def _check_messages(service_id, template_id, upload_id, preview_row): sent_previously=job_api_client.has_sent_previously( service_id, template.id, db_template["version"], original_file_name ), - template_id=template_id + template_id=template_id, ) @@ -614,17 +617,20 @@ def check_messages(service_id, template_id, upload_id, row_index=2): metadata_kwargs["sender_id"] = session["sender_id"] set_metadata_on_csv_upload(service_id, upload_id, **metadata_kwargs) - session['scheduled_for'] = request.form.get("scheduled_for", "") return render_template("views/check/ok.html", **data) @main.route( "/services///check//preview", - methods=["POST"], + methods=["GET"], +) +@main.route( + "/services///check//preview/row-", + methods=["GET"], ) @user_has_permissions("send_messages", restrict_admin_usage=True) def preview_job(service_id, template_id, upload_id, row_index=2): - session['scheduled_for'] = request.form.get('scheduled_for', 'Not specified') + session["scheduled_for"] = request.args.get("scheduled_for", "") data = _check_messages(service_id, template_id, upload_id, row_index) data["allowed_file_extensions"] = Spreadsheet.ALLOWED_FILE_EXTENSIONS if ( @@ -643,13 +649,15 @@ def preview_job(service_id, template_id, upload_id, row_index=2): if data["errors"]: return render_template("views/check/column-errors.html", **data) - return render_template('views/check/preview.html', scheduled_for=session['scheduled_for'], **data) + return render_template( + "views/check/preview.html", scheduled_for=session["scheduled_for"], **data + ) @main.route("/services//start-job/", methods=["POST"]) @user_has_permissions("send_messages", restrict_admin_usage=True) def start_job(service_id, upload_id): - scheduled_for = session.pop('scheduled_for', None) + scheduled_for = session.pop("scheduled_for", None) job_api_client.create_job( upload_id, service_id, @@ -712,7 +720,13 @@ def get_send_test_page_title(template_type, entering_recipient, name=None): return "Personalize this message" -def get_back_link(service_id, template, step_index, placeholders=None, preview=False,): +def get_back_link( + service_id, + template, + step_index, + placeholders=None, + preview=False, +): if preview: return url_for( "main.check_notification", @@ -824,7 +838,9 @@ def _check_notification(service_id, template_id, exception=None): back_link = get_back_link(service_id, template, len(placeholders), placeholders) - back_link_from_preview = get_back_link(service_id, template, len(placeholders), placeholders, preview=True) + back_link_from_preview = get_back_link( + service_id, template, len(placeholders), placeholders, preview=True + ) choose_time_form = ChooseTimeForm() @@ -873,7 +889,7 @@ def get_template_error_dict(exception): @main.route( "/services//template//notification/check/preview", - methods=["POST"], + methods=["GET"], ) @user_has_permissions("send_messages", restrict_admin_usage=True) def preview_notification(service_id, template_id): @@ -887,11 +903,12 @@ def preview_notification(service_id, template_id): ) ) - session['scheduled_for'] = request.form.get('scheduled_for', 'Not specified') + session["scheduled_for"] = request.args.get("scheduled_for", "") return render_template( "views/notifications/preview.html", - **_check_notification(service_id, template_id), data=session['scheduled_for'] + **_check_notification(service_id, template_id), + scheduled_for=session["scheduled_for"], ) @@ -901,7 +918,7 @@ def preview_notification(service_id, template_id): ) @user_has_permissions("send_messages", restrict_admin_usage=True) def send_notification(service_id, template_id): - scheduled_for = session.pop('scheduled_for', None) + scheduled_for = session.pop("scheduled_for", "") recipient = get_recipient() if not recipient: return redirect( diff --git a/app/templates/views/check/ok.html b/app/templates/views/check/ok.html index f70b6232e..95fd1abea 100644 --- a/app/templates/views/check/ok.html +++ b/app/templates/views/check/ok.html @@ -1,6 +1,5 @@ {% extends "withnav_template.html" %} {% from "components/banner.html" import banner_wrapper %} -{% from "components/table.html" import list_table, field, text_field, index_field, hidden_field_heading %} {% from "components/page-header.html" import page_header %} {% from "components/components/button/macro.njk" import usaButton %} {% from "components/components/skip-link/macro.njk" import usaSkipLink %} @@ -9,7 +8,7 @@ {% set file_contents_header_id = 'file-preview' %} {% block service_page_title %} - {{ "Preview of {}".format(template.name) }} + {{ "Select delivery time" }} {% endblock %} @@ -23,8 +22,7 @@ {{ template|string }}
-