mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-07-26 02:49:16 -04:00
merge from main
This commit is contained in:
1
.github/workflows/checks.yml
vendored
1
.github/workflows/checks.yml
vendored
@@ -124,7 +124,6 @@ jobs:
|
||||
make e2e-test
|
||||
env:
|
||||
API_HOST_NAME: https://notify-api-staging.app.cloud.gov/
|
||||
# API_HOST_NAME: http://localhost:6011
|
||||
DANGEROUS_SALT: ${{ secrets.DANGEROUS_SALT }}
|
||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||
ADMIN_CLIENT_SECRET: ${{ secrets.ADMIN_CLIENT_SECRET }}
|
||||
|
||||
4
app/assets/js/setTimezone.js
Normal file
4
app/assets/js/setTimezone.js
Normal file
@@ -0,0 +1,4 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
document.cookie = `timezone=${timeZone}; path=/`;
|
||||
})
|
||||
@@ -162,11 +162,11 @@ class E2ETest(Staging):
|
||||
|
||||
# Borrowed from development environment
|
||||
DEBUG = True
|
||||
SESSION_COOKIE_SECURE = False
|
||||
SESSION_PROTECTION = None
|
||||
HTTP_PROTOCOL = "http"
|
||||
ASSET_DOMAIN = ""
|
||||
ASSET_PATH = "/static/"
|
||||
# SESSION_COOKIE_SECURE = False
|
||||
# SESSION_PROTECTION = None
|
||||
# HTTP_PROTOCOL = "http"
|
||||
# ASSET_DOMAIN = ""
|
||||
# ASSET_PATH = "/static/"
|
||||
|
||||
# Borrowed from test environment
|
||||
TESTING = True
|
||||
|
||||
@@ -16,6 +16,7 @@ from app import (
|
||||
)
|
||||
from app.formatters import format_date_numeric, format_datetime_numeric, get_time_left
|
||||
from app.main import main
|
||||
from app.main.views.user_profile import set_timezone
|
||||
from app.statistics_utils import get_formatted_percentage
|
||||
from app.utils import (
|
||||
DELIVERED_STATUSES,
|
||||
@@ -39,6 +40,7 @@ def old_service_dashboard(service_id):
|
||||
@main.route("/services/<uuid:service_id>")
|
||||
@user_has_permissions()
|
||||
def service_dashboard(service_id):
|
||||
|
||||
if session.get("invited_user_id"):
|
||||
session.pop("invited_user_id", None)
|
||||
session["service_id"] = service_id
|
||||
@@ -402,11 +404,13 @@ def get_dashboard_partials(service_id):
|
||||
|
||||
|
||||
def get_dashboard_totals(statistics):
|
||||
|
||||
for msg_type in statistics.values():
|
||||
msg_type["failed_percentage"] = get_formatted_percentage(
|
||||
msg_type["failed"], msg_type["requested"]
|
||||
)
|
||||
msg_type["show_warning"] = float(msg_type["failed_percentage"]) > 3
|
||||
|
||||
return statistics
|
||||
|
||||
|
||||
@@ -465,6 +469,8 @@ def get_months_for_financial_year(year, time_format="%B"):
|
||||
|
||||
|
||||
def get_current_month_for_financial_year(year):
|
||||
# Setting the timezone here because we need to set it somewhere.
|
||||
set_timezone()
|
||||
current_month = datetime.now().month
|
||||
return current_month
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ from app.main.forms import (
|
||||
SetSenderForm,
|
||||
get_placeholder_form_instance,
|
||||
)
|
||||
from app.main.views.user_profile import set_timezone
|
||||
from app.models.user import Users
|
||||
from app.s3_client.s3_csv_client import (
|
||||
get_csv_metadata,
|
||||
@@ -1075,6 +1076,7 @@ def get_spreadsheet_column_headings_from_template(template):
|
||||
|
||||
|
||||
def get_recipient():
|
||||
set_timezone()
|
||||
if {"recipient", "placeholders"} - set(session.keys()):
|
||||
return None
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ from app.main.forms import (
|
||||
TwoFactorForm,
|
||||
)
|
||||
from app.models.user import User
|
||||
from app.utils import hilite
|
||||
from app.utils.user import user_is_gov_user, user_is_logged_in
|
||||
from notifications_utils.url_safe_token import check_token
|
||||
|
||||
@@ -275,3 +276,15 @@ def user_profile_disable_platform_admin_view():
|
||||
return render_template(
|
||||
"views/user-profile/disable-platform-admin-view.html", form=form
|
||||
)
|
||||
|
||||
|
||||
def set_timezone():
|
||||
# Cookie is set in dashboard.html on page load
|
||||
try:
|
||||
timezone = request.cookies.get("timezone", "US/Eastern")
|
||||
current_app.logger.debug(hilite(f"User's timezone is {timezone}"))
|
||||
serialized_user = current_user.serialize()
|
||||
if serialized_user["preferred_timezone"] is not timezone:
|
||||
current_user.update(preferred_timezone=timezone)
|
||||
except Exception:
|
||||
current_app.logger.exception(hilite("Can't get timezone"))
|
||||
|
||||
@@ -58,6 +58,7 @@ class User(JSONModel, UserMixin):
|
||||
super().__init__(_dict)
|
||||
self.permissions = _dict.get("permissions", {})
|
||||
self._platform_admin = _dict["platform_admin"]
|
||||
self.preferred_timezone = _dict.get("preferred_timezone", "America/New_York")
|
||||
|
||||
@classmethod
|
||||
def from_id(cls, user_id):
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
{% extends "withnav_template.html" %}
|
||||
|
||||
{% from "components/table.html" import list_table, field, text_field, link_field, right_aligned_field_heading, hidden_field_heading, row_heading, notification_status_field, notification_carrier_field, notification_carrier_message_field %}
|
||||
@@ -8,6 +10,8 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block maincolumn_content %}
|
||||
<script type="text/javascript" src="{{ asset_url('js/setTimezone.js') }}"></script>
|
||||
|
||||
|
||||
<div class="dashboard margin-bottom-2">
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
{% from "components/file-upload.html" import file_upload %}
|
||||
{% from "components/table.html" import list_table, text_field, index_field, index_field_heading %}
|
||||
{% from "components/components/back-link/macro.njk" import usaBackLink %}
|
||||
<script type="text/javascript" src="{{ asset_url('js/setTimezone.js') }}"></script>
|
||||
|
||||
{% block service_page_title %}
|
||||
Upload a list of {{ 999|recipient_count_label(template.template_type) }}
|
||||
|
||||
@@ -45,14 +45,9 @@
|
||||
{% endcall %}
|
||||
|
||||
{% call row() %}
|
||||
{{ text_field('Preferred Timezone') }}
|
||||
{{ text_field('Preferred timezone') }}
|
||||
{{ optional_text_field(current_user.preferred_timezone) }}
|
||||
{{ edit_field(
|
||||
'Change',
|
||||
url_for('.user_profile_preferred_timezone'),
|
||||
suffix='preferred timezone'
|
||||
)
|
||||
}}
|
||||
{{ text_field('Set automatically') }}
|
||||
{% endcall %}
|
||||
|
||||
{% if current_user.platform_admin or session.get('disable_platform_admin_view') %}
|
||||
|
||||
@@ -97,6 +97,13 @@ const copyGtmHead = () => {
|
||||
.pipe(dest(paths.dist + 'js/'));
|
||||
};
|
||||
|
||||
// Task to copy `setTimezone.js`
|
||||
const copySetTimezone = () => {
|
||||
return src(paths.src + 'js/setTimezone.js')
|
||||
.pipe(dest(paths.dist + 'js/'));
|
||||
};
|
||||
|
||||
|
||||
// Task to copy images
|
||||
const copyImages = () => {
|
||||
return src(paths.src + 'images/**/*', { encoding: false })
|
||||
@@ -122,4 +129,4 @@ const copyAssets = async () => {
|
||||
await uswds.copyAssets();
|
||||
};
|
||||
|
||||
exports.default = series(styles, javascripts, copyGtmHead, copyImages, copyAssets);
|
||||
exports.default = series(styles, javascripts, copyGtmHead, copySetTimezone, copyImages, copyAssets);
|
||||
|
||||
6
poetry.lock
generated
6
poetry.lock
generated
@@ -1285,13 +1285,9 @@ files = [
|
||||
{file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b590b39ef90c6b22ec0be925b211298e810b4856909c8ca60d27ffbca6c12e6"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:c2faf60c583af0d135e853c86ac2735ce178f0e338a3c7f9ae8f622fd2eb788c"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7ff762670cada8e05b32bf1e4dc50b140790909caa8303cfddc4d702b71ea184"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:a6d2092797b388342c1bc932077ad232f914351932353e2e8706851c870bca1f"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"},
|
||||
{file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"},
|
||||
@@ -1626,6 +1622,7 @@ files = [
|
||||
{file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"},
|
||||
{file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"},
|
||||
{file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"},
|
||||
{file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"},
|
||||
{file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"},
|
||||
]
|
||||
|
||||
@@ -2433,7 +2430,6 @@ files = [
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
||||
|
||||
@@ -113,55 +113,55 @@ def test_view_conversation(
|
||||
[
|
||||
(
|
||||
"message-8",
|
||||
"yesterday at 14:59 US/Eastern",
|
||||
"yesterday at 14:59 America/New_York",
|
||||
),
|
||||
(
|
||||
"message-7",
|
||||
"yesterday at 14:59 US/Eastern",
|
||||
"yesterday at 14:59 America/New_York",
|
||||
),
|
||||
(
|
||||
"message-6",
|
||||
"yesterday at 16:59 US/Eastern",
|
||||
"yesterday at 16:59 America/New_York",
|
||||
),
|
||||
(
|
||||
"message-5",
|
||||
"yesterday at 18:59 US/Eastern",
|
||||
"yesterday at 18:59 America/New_York",
|
||||
),
|
||||
(
|
||||
"message-4",
|
||||
"yesterday at 20:59 US/Eastern",
|
||||
"yesterday at 20:59 America/New_York",
|
||||
),
|
||||
(
|
||||
"message-3",
|
||||
"yesterday at 22:59 US/Eastern",
|
||||
"yesterday at 22:59 America/New_York",
|
||||
),
|
||||
(
|
||||
"message-2",
|
||||
"yesterday at 22:59 US/Eastern",
|
||||
"yesterday at 22:59 America/New_York",
|
||||
),
|
||||
(
|
||||
"message-1",
|
||||
"yesterday at 23:00 US/Eastern",
|
||||
"yesterday at 23:00 America/New_York",
|
||||
),
|
||||
(
|
||||
expected_outbound_content,
|
||||
"yesterday at 00:00 US/Eastern",
|
||||
"yesterday at 00:00 America/New_York",
|
||||
),
|
||||
(
|
||||
expected_outbound_content,
|
||||
"yesterday at 00:00 US/Eastern",
|
||||
"yesterday at 00:00 America/New_York",
|
||||
),
|
||||
(
|
||||
expected_outbound_content,
|
||||
"yesterday at 00:00 US/Eastern",
|
||||
"yesterday at 00:00 America/New_York",
|
||||
),
|
||||
(
|
||||
expected_outbound_content,
|
||||
"yesterday at 00:00 US/Eastern",
|
||||
"yesterday at 00:00 America/New_York",
|
||||
),
|
||||
(
|
||||
expected_outbound_content,
|
||||
"yesterday at 00:00 US/Eastern",
|
||||
"yesterday at 00:00 America/New_York",
|
||||
),
|
||||
]
|
||||
):
|
||||
|
||||
@@ -550,14 +550,14 @@ def test_download_inbox(
|
||||
)
|
||||
assert response.get_data(as_text=True) == (
|
||||
"Phone number,Message,Received\r\n"
|
||||
"(202) 867-5300,message-1,07-01-2016 11:00 US/Eastern\r\n"
|
||||
"(202) 867-5300,message-2,07-01-2016 10:59 US/Eastern\r\n"
|
||||
"(202) 867-5300,message-3,07-01-2016 10:59 US/Eastern\r\n"
|
||||
"(202) 867-5302,message-4,07-01-2016 08:59 US/Eastern\r\n"
|
||||
"+33(0)1 12345678,message-5,07-01-2016 06:59 US/Eastern\r\n"
|
||||
"(202) 555-0104,message-6,07-01-2016 04:59 US/Eastern\r\n"
|
||||
"(202) 555-0104,message-7,07-01-2016 02:59 US/Eastern\r\n"
|
||||
"+68212345,message-8,07-01-2016 02:59 US/Eastern\r\n"
|
||||
"(202) 867-5300,message-1,07-01-2016 11:00 America/New_York\r\n"
|
||||
"(202) 867-5300,message-2,07-01-2016 10:59 America/New_York\r\n"
|
||||
"(202) 867-5300,message-3,07-01-2016 10:59 America/New_York\r\n"
|
||||
"(202) 867-5302,message-4,07-01-2016 08:59 America/New_York\r\n"
|
||||
"+33(0)1 12345678,message-5,07-01-2016 06:59 America/New_York\r\n"
|
||||
"(202) 555-0104,message-6,07-01-2016 04:59 America/New_York\r\n"
|
||||
"(202) 555-0104,message-7,07-01-2016 02:59 America/New_York\r\n"
|
||||
"+68212345,message-8,07-01-2016 02:59 America/New_York\r\n"
|
||||
)
|
||||
|
||||
|
||||
@@ -849,7 +849,7 @@ def test_should_show_upcoming_jobs_on_dashboard(
|
||||
assert normalize_spaces(page.select_one("main h2").text) == ("In the next few days")
|
||||
|
||||
assert normalize_spaces(page.select_one("a.banner-dashboard").text) == (
|
||||
"2 files waiting to send " "- sending starts today at 06:09 US/Eastern"
|
||||
"2 files waiting to send " "- sending starts today at 06:09 America/New_York"
|
||||
)
|
||||
|
||||
assert page.select_one("a.banner-dashboard")["href"] == url_for(
|
||||
@@ -1786,7 +1786,6 @@ def test_org_breadcrumbs_show_if_user_is_platform_admin(
|
||||
|
||||
client_request.login(platform_admin_user, service_one_json)
|
||||
page = client_request.get("main.service_dashboard", service_id=SERVICE_ONE_ID)
|
||||
|
||||
assert page.select_one(".navigation-organization-link")["href"] == url_for(
|
||||
"main.organization_dashboard",
|
||||
org_id=ORGANISATION_ID,
|
||||
|
||||
@@ -349,7 +349,7 @@ def test_should_show_scheduled_job(
|
||||
)
|
||||
|
||||
assert normalize_spaces(page.select("main div p")[1].text) == (
|
||||
"Example template - service one was scheduled on January 02, 2016 at 12:00 AM US/Eastern by Test User"
|
||||
"Example template - service one was scheduled on January 02, 2016 at 12:00 AM America/New_York by Test User"
|
||||
)
|
||||
|
||||
assert page.select("main p a")[0]["href"] == url_for(
|
||||
|
||||
@@ -497,7 +497,7 @@ def test_caseworker_sees_template_page_if_template_is_deleted(
|
||||
)
|
||||
assert (
|
||||
page.select("p.hint")[0].text.strip()
|
||||
== "This template was deleted today at 15:00 US/Eastern."
|
||||
== "This template was deleted today at 15:00 America/New_York."
|
||||
)
|
||||
|
||||
mock_get_deleted_template.assert_called_with(SERVICE_ONE_ID, template_id, None)
|
||||
@@ -1591,7 +1591,7 @@ def test_should_show_page_for_a_deleted_template(
|
||||
)
|
||||
assert (
|
||||
page.select("p.hint")[0].text.strip()
|
||||
== "This template was deleted today at 15:00 US/Eastern."
|
||||
== "This template was deleted today at 15:00 America/New_York."
|
||||
)
|
||||
assert "Delete this template" not in page.select_one("main").text
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ def test_get_upload_hub_page(
|
||||
|
||||
assert normalize_spaces(uploads[0].text.strip()) == (
|
||||
"some.csv "
|
||||
"Sent 1 January 2016 at 06:09 US/Eastern "
|
||||
"Sent 1 January 2016 at 06:09 America/New_York "
|
||||
"0 pending 8 delivered 2 failed"
|
||||
)
|
||||
assert uploads[0].select_one("a.file-list-filename-large")["href"] == (
|
||||
@@ -82,12 +82,12 @@ def test_uploads_page_shows_scheduled_jobs(
|
||||
("File Status"),
|
||||
(
|
||||
"even_later.csv "
|
||||
"Sending 1 January 2016 at 18:09 US/Eastern "
|
||||
"Sending 1 January 2016 at 18:09 America/New_York "
|
||||
"1 text message waiting to send"
|
||||
),
|
||||
(
|
||||
"send_me_later.csv "
|
||||
"Sending 1 January 2016 at 06:09 US/Eastern "
|
||||
"Sending 1 January 2016 at 06:09 America/New_York "
|
||||
"1 text message waiting to send"
|
||||
),
|
||||
]
|
||||
|
||||
@@ -18,6 +18,7 @@ def test_user(notify_admin):
|
||||
"email_address": "test@user.gsa.gov",
|
||||
"mobile_number": "+12021231234",
|
||||
"state": "pending",
|
||||
"preferred_timezone": "America/Chicago",
|
||||
"failed_login_count": 0,
|
||||
"platform_admin": False,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user