From 6999d72f76e2581c7023208f39326720cf381f14 Mon Sep 17 00:00:00 2001 From: Andrew Shumway Date: Wed, 7 Feb 2024 09:38:18 -0700 Subject: [PATCH 01/71] Fix dashboard bug/usage page --- app/main/views/dashboard.py | 46 ++++++----------- app/utils/time.py | 2 +- .../views/organizations/test_organizations.py | 10 ++-- tests/app/main/views/test_dashboard.py | 49 ++++++++++++------- tests/app/utils/test_time.py | 8 +-- 5 files changed, 55 insertions(+), 60 deletions(-) diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index a88203ae7e..f5f38087a1 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -123,11 +123,17 @@ def get_monthly_template_stats(month_name, stats): months=months, stats=stats, most_used_template_count=max( - max( - (template["requested_count"] for template in month["templates_used"]), - default=0, - ) - for month in months + ( + max( + ( + template["requested_count"] + for template in month["templates_used"] + ), + default=0, + ) + for month in months + ), + default=0, ), years=get_tuples_of_financial_years( partial(url_for, ".template_usage", service_id=service_id), @@ -144,31 +150,16 @@ def usage(service_id): year, current_financial_year = requested_and_current_financial_year(request) free_sms_allowance = billing_api_client.get_free_sms_fragment_limit_for_year( - service_id, year + service_id ) + units = billing_api_client.get_monthly_usage_for_service(service_id, year) + yearly_usage = billing_api_client.get_annual_usage_for_service(service_id, year) more_stats = format_monthly_stats_to_list( service_api_client.get_monthly_notification_stats(service_id, year)["data"] ) - if year == current_financial_year: - # This includes Oct, Nov, Dec - # but we don't need next year's data yet - more_stats = [ - month - for month in more_stats - if month["name"] in ["October", "November", "December"] - ] - elif year == (current_financial_year + 1): - # This is all the other months - # and we need last year's data - more_stats = [ - month - for month in more_stats - if month["name"] not in ["October", "November", "December"] - ] - return render_template( "views/usage.html", months=list(get_monthly_usage_breakdown(year, units, more_stats)), @@ -330,7 +321,6 @@ def get_dashboard_partials(service_id): dashboard_totals = (get_dashboard_totals(stats),) free_sms_allowance = billing_api_client.get_free_sms_fragment_limit_for_year( current_service.id, - get_current_financial_year(), ) yearly_usage = billing_api_client.get_annual_usage_for_service( service_id, @@ -422,13 +412,7 @@ def aggregate_status_types(counts_dict): def get_months_for_financial_year(year, time_format="%B"): - return [ - month.strftime(time_format) - for month in ( - get_months_for_year(10, 13, year) + get_months_for_year(1, 10, year + 1) - ) - if month < datetime.now() - ] + return [month.strftime(time_format) for month in (get_months_for_year(1, 13, year))] def get_months_for_year(start, end, year): diff --git a/app/utils/time.py b/app/utils/time.py index 9ae24b1bd7..e2f4a8e362 100644 --- a/app/utils/time.py +++ b/app/utils/time.py @@ -11,7 +11,7 @@ def get_current_financial_year(): now = datetime.now(preferred_tz) current_month = int(now.strftime("%-m")) current_year = int(now.strftime("%Y")) - return current_year if current_month > 9 else current_year - 1 + return current_year if current_month < 10 else current_year + 1 def is_less_than_days_ago(date_from_db, number_of_days): diff --git a/tests/app/main/views/organizations/test_organizations.py b/tests/app/main/views/organizations/test_organizations.py index 7679e14293..27663ad22f 100644 --- a/tests/app/main/views/organizations/test_organizations.py +++ b/tests/app/main/views/organizations/test_organizations.py @@ -388,7 +388,7 @@ def test_organization_services_shows_live_services_and_usage( client_request.login(active_user_with_permissions) page = client_request.get(".organization_dashboard", org_id=ORGANISATION_ID) - mock.assert_called_once_with(ORGANISATION_ID, 2019) + mock.assert_called_once_with(ORGANISATION_ID, 2020) services = page.select("main h3") usage_rows = page.select("main .grid-col-6") @@ -459,9 +459,9 @@ def test_organization_services_shows_live_services_and_usage_with_count_of_1( @pytest.mark.parametrize( ("financial_year", "expected_selected"), [ - (2017, "2017 to 2018 fiscal year"), (2018, "2018 to 2019 fiscal year"), (2019, "2019 to 2020 fiscal year"), + (2020, "2020 to 2021 fiscal year"), ], ) def test_organization_services_filters_by_financial_year( @@ -483,9 +483,9 @@ def test_organization_services_filters_by_financial_year( ) mock.assert_called_once_with(ORGANISATION_ID, financial_year) assert normalize_spaces(page.select_one(".pill").text) == ( + "2020 to 2021 fiscal year " "2019 to 2020 fiscal year " - "2018 to 2019 fiscal year " - "2017 to 2018 fiscal year" + "2018 to 2019 fiscal year" ) assert normalize_spaces(page.select_one(".pill-item--selected").text) == ( expected_selected @@ -610,7 +610,7 @@ def test_organization_services_links_to_downloadable_report( assert link_to_report.attrs["href"] == url_for( ".download_organization_usage_report", org_id=ORGANISATION_ID, - selected_year=2021, + selected_year=2022, ) diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 8e9ecb5315..9703a2de56 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -666,12 +666,12 @@ def test_should_show_redirect_from_template_history( ) -@freeze_time("2017-01-01 12:00") # 4 months into 2016 financial year +@freeze_time("2017-1-1 12:00") # Switching to calendar year @pytest.mark.parametrize( "extra_args", [ {}, - {"year": "2016"}, + {"year": "2017"}, ], ) def test_should_show_monthly_breakdown_of_template_usage( @@ -683,7 +683,7 @@ def test_should_show_monthly_breakdown_of_template_usage( "main.template_usage", service_id=SERVICE_ONE_ID, **extra_args ) - mock_get_monthly_template_usage.assert_called_once_with(SERVICE_ONE_ID, 2016) + mock_get_monthly_template_usage.assert_called_once_with(SERVICE_ONE_ID, 2017) table_rows = page.select("tbody tr") @@ -691,9 +691,21 @@ def test_should_show_monthly_breakdown_of_template_usage( "My first template " "Text message template " "2" ) - assert len(table_rows) == len(["October"]) + assert len(table_rows) == len(["January"]) assert len(page.select(".table-no-data")) == len( - ["November", "December", "January"] + [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + ] ) @@ -736,9 +748,9 @@ def test_stats_pages_show_last_3_years( ) assert normalize_spaces(page.select_one(".pill").text) == ( + "2015 to 2016 fiscal year " "2014 to 2015 fiscal year " - "2013 to 2014 fiscal year " - "2012 to 2013 fiscal year" + "2013 to 2014 fiscal year" ) @@ -953,18 +965,18 @@ def test_usage_page( service_id=SERVICE_ONE_ID, ) - mock_get_monthly_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2011) - mock_get_annual_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2011) - mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID, 2011) + mock_get_monthly_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2012) + mock_get_annual_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2012) + mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID) nav = page.find("ul", {"class": "pill"}) unselected_nav_links = nav.select("a:not(.pill-item--selected)") assert ( normalize_spaces(nav.find("a", {"aria-current": "page"}).text) - == "2011 to 2012 fiscal year" + == "2012 to 2013 fiscal year" ) - assert normalize_spaces(unselected_nav_links[0].text) == "2010 to 2011 fiscal year" - assert normalize_spaces(unselected_nav_links[1].text) == "2009 to 2010 fiscal year" + assert normalize_spaces(unselected_nav_links[0].text) == "2011 to 2012 fiscal year" + assert normalize_spaces(unselected_nav_links[1].text) == "2010 to 2011 fiscal year" annual_usage = page.find_all("div", {"class": "keyline-block"}) @@ -1031,8 +1043,7 @@ def test_usage_page_monthly_breakdown( page = client_request.get("main.usage", service_id=SERVICE_ONE_ID) monthly_breakdown = normalize_spaces(page.find("table").text) - assert "October" in monthly_breakdown - assert "249,860 free text messages" in monthly_breakdown + assert "January" in monthly_breakdown assert "February" in monthly_breakdown assert "$16.40" in monthly_breakdown @@ -1048,8 +1059,8 @@ def test_usage_page_monthly_breakdown( @pytest.mark.parametrize( ("now", "expected_number_of_months"), [ - (freeze_time("2017-03-31 11:09:00.061258"), 6), - (freeze_time("2017-01-01 11:09:00.061258"), 4), + (freeze_time("2017-03-31 11:09:00.061258"), 12), + (freeze_time("2017-01-01 11:09:00.061258"), 12), ], ) def test_usage_page_monthly_breakdown_shows_months_so_far( @@ -1109,7 +1120,7 @@ def test_usage_page_with_year_argument( ) mock_get_monthly_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2000) mock_get_annual_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2000) - mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID, 2000) + mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID) mock_get_monthly_notification_stats.assert_called_with(SERVICE_ONE_ID, 2000) @@ -1144,7 +1155,7 @@ def test_future_usage_page( mock_get_annual_usage_for_service_in_future.assert_called_once_with( SERVICE_ONE_ID, 2014 ) - mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID, 2014) + mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID) mock_get_monthly_notification_stats.assert_called_with(SERVICE_ONE_ID, 2014) diff --git a/tests/app/utils/test_time.py b/tests/app/utils/test_time.py index 931fdb816d..ae51edb97e 100644 --- a/tests/app/utils/test_time.py +++ b/tests/app/utils/test_time.py @@ -20,10 +20,10 @@ def test_is_less_than_days_ago(date_from_db, expected_result): @pytest.mark.parametrize( ("datetime_string", "financial_year"), [ - ("2021-01-01T00:00:00+00:00", 2020), # Start of 2021 - ("2021-04-01T03:59:59+00:00", 2020), # One minute before midnight (BST) - ("2021-10-01T04:05:00+00:00", 2021), # Midnight (BST) - ("2021-12-12T12:12:12+01:00", 2021), # Later in the year + ("2021-01-01T00:00:00+00:00", 2021), # Start of 2021 + ("2021-04-01T03:59:59+00:00", 2021), # One minute before midnight (BST) + ("2021-10-01T04:05:00+00:00", 2022), # Midnight (BST) + ("2021-12-12T12:12:12+01:00", 2022), # Later in the year ], ) def test_get_financial_year(datetime_string, financial_year): From 5a440863afa1592acf51b0927fc364989ab0d326 Mon Sep 17 00:00:00 2001 From: Andrew Shumway Date: Wed, 7 Feb 2024 14:43:39 -0700 Subject: [PATCH 02/71] Fix trial mode allowance bug --- app/main/views/dashboard.py | 8 ++++++++ tests/app/main/views/test_dashboard.py | 2 ++ tests/conftest.py | 2 ++ 3 files changed, 12 insertions(+) diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index f5f38087a1..87a013547f 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -322,6 +322,14 @@ def get_dashboard_partials(service_id): free_sms_allowance = billing_api_client.get_free_sms_fragment_limit_for_year( current_service.id, ) + # These 2 calls will update the dashboard sms allowance count while in trial mode. + billing_api_client.get_monthly_usage_for_service( + service_id, get_current_financial_year() + ) + billing_api_client.create_or_update_free_sms_fragment_limit( + service_id, free_sms_fragment_limit=free_sms_allowance + ) + yearly_usage = billing_api_client.get_annual_usage_for_service( service_id, get_current_financial_year(), diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 9703a2de56..10d686a984 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -1386,7 +1386,9 @@ def test_route_for_service_permissions( mock_has_no_jobs, mock_get_template_statistics, mock_get_service_statistics, + mock_get_monthly_usage_for_service, mock_get_annual_usage_for_service, + mock_create_or_update_free_sms_fragment_limit, mock_get_free_sms_fragment_limit, mock_get_inbound_sms_summary, ): diff --git a/tests/conftest.py b/tests/conftest.py index ec4ff8ad16..1724f0234d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2327,6 +2327,8 @@ def _get(mocker): "app.billing_api_client.create_or_update_free_sms_fragment_limit", autospec=True ) + mocker.patch("app.billing_api_client.get_monthly_usage_for_service", autospec=True) + class ClientRequest: @staticmethod @contextmanager From 404ef2c3c37953cf2263b7f871a90e9fa13327df Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 25 Mar 2024 11:38:07 -0700 Subject: [PATCH 03/71] initial --- tests/end_to_end/test_accounts_page.py | 86 +------ ...est_send_message_from_existing_template.py | 225 ++++++++++++++++++ 2 files changed, 226 insertions(+), 85 deletions(-) create mode 100644 tests/end_to_end/test_send_message_from_existing_template.py diff --git a/tests/end_to_end/test_accounts_page.py b/tests/end_to_end/test_accounts_page.py index b6fe8c5ac7..e59fe7f9e3 100644 --- a/tests/end_to_end/test_accounts_page.py +++ b/tests/end_to_end/test_accounts_page.py @@ -8,88 +8,4 @@ def test_add_new_service_workflow(authenticated_page, end_to_end_context): - page = authenticated_page - - # Prepare for adding a new service later in the test. - current_date_time = datetime.datetime.now() - new_service_name = "E2E Federal Test Service {now} - {browser_type}".format( - now=current_date_time.strftime("%m/%d/%Y %H:%M:%S"), - browser_type=end_to_end_context.browser.browser_type.name, - ) - - page.goto(f"{E2E_TEST_URI}/accounts") - - # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") - - # Check to make sure that we've arrived at the next page. - # Check the page title exists and matches what we expect. - expect(page).to_have_title(re.compile("Choose service")) - - # Check for the sign in heading. - sign_in_heading = page.get_by_role("heading", name="Choose service") - expect(sign_in_heading).to_be_visible() - - # Retrieve some prominent elements on the page for testing. - add_service_button = page.get_by_role( - "button", name=re.compile("Add a new service") - ) - - expect(add_service_button).to_be_visible() - - existing_service_link = page.get_by_role("link", name=new_service_name) - - # Check to see if the service was already created - if so, we should fail. - # TODO: Figure out how to make this truly isolated, and/or work in a - # delete service workflow. - expect(existing_service_link).to_have_count(0) - - # Click on add a new service. - add_service_button.click() - - # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") - - # Check for the sign in heading. - about_heading = page.get_by_role("heading", name="About your service") - expect(about_heading).to_be_visible() - - # Retrieve some prominent elements on the page for testing. - service_name_input = page.locator('xpath=//input[@name="name"]') - add_service_button = page.get_by_role("button", name=re.compile("Add service")) - - expect(service_name_input).to_be_visible() - expect(add_service_button).to_be_visible() - - # Fill in the form. - service_name_input.fill(new_service_name) - - # Click on add service. - add_service_button.click() - - # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") - - # Check for the service name title and heading. - service_heading = page.get_by_text(new_service_name, exact=True) - expect(service_heading).to_be_visible() - expect(page).to_have_title(re.compile(new_service_name)) - - page.click("text='Settings'") - - # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") - - page.click("text='Delete this service'") - - # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") - - page.click("text='Yes, delete'") - - # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") - - # Check to make sure that we've arrived at the next page. - # Check the page title exists and matches what we expect. - expect(page).to_have_title(re.compile("Choose service")) + pass diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py new file mode 100644 index 0000000000..266160a6fa --- /dev/null +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -0,0 +1,225 @@ +import datetime +import os +import re +import uuid + +from playwright.sync_api import expect + +E2E_TEST_URI = os.getenv("NOTIFY_E2E_TEST_URI") + + +def _setup(page, end_to_end_context): + # Prepare for adding a new service later in the test. + current_date_time = datetime.datetime.now() + new_service_name = "E2E Federal Test Service {now} - {browser_type}".format( + now=current_date_time.strftime("%m/%d/%Y %H:%M:%S"), + browser_type=end_to_end_context.browser.browser_type.name, + ) + + page.goto(f"{E2E_TEST_URI}/accounts") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check to make sure that we've arrived at the next page. + # Check the page title exists and matches what we expect. + expect(page).to_have_title(re.compile("Choose service")) + + # Check for the sign in heading. + sign_in_heading = page.get_by_role("heading", name="Choose service") + expect(sign_in_heading).to_be_visible() + + # Retrieve some prominent elements on the page for testing. + add_service_button = page.get_by_role( + "button", name=re.compile("Add a new service") + ) + + expect(add_service_button).to_be_visible() + + existing_service_link = page.get_by_role("link", name=new_service_name) + + # Check to see if the service was already created - if so, we should fail. + # TODO: Figure out how to make this truly isolated, and/or work in a + # delete service workflow. + expect(existing_service_link).to_have_count(0) + + # Click on add a new service. + add_service_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check for the sign in heading. + about_heading = page.get_by_role("heading", name="About your service") + expect(about_heading).to_be_visible() + + # Retrieve some prominent elements on the page for testing. + service_name_input = page.locator('xpath=//input[@name="name"]') + add_service_button = page.get_by_role("button", name=re.compile("Add service")) + + expect(service_name_input).to_be_visible() + expect(add_service_button).to_be_visible() + + # Fill in the form. + service_name_input.fill(new_service_name) + + # Click on add service. + add_service_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check for the service name title and heading. + service_heading = page.get_by_text(new_service_name, exact=True) + + expect(service_heading).to_be_visible() + expect(page).to_have_title(re.compile(new_service_name)) + + return new_service_name + + +def test_add_new_service_workflow(authenticated_page, end_to_end_context): + page = authenticated_page + + new_service_name = _setup(page, end_to_end_context) + + print(page) + + + create_template_button = page.get_by_text("Create your first template") + expect(create_template_button).to_be_visible() + create_template_button.click() + print("GOT TO CREATE TEMPLATE") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + new_template_button = page.get_by_text("New template") + expect(new_template_button).to_be_visible() + new_template_button.click() + print("GOT TO NEW TEMPLATE") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + start_with_a_blank_template_radio = page.get_by_text("Start with a blank template") + expect(start_with_a_blank_template_radio).to_be_visible() + start_with_a_blank_template_radio.click() + print("GOT TO START WITH A BLANK TEMPLATE") + + continue_button = page.get_by_role("button", name="Continue") + + # continue_button = page.get_by_text("Continue") + expect(continue_button).to_be_visible() + continue_button.click() + print("GOT TO CONTINUE") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + template_name_input = page.get_by_text("Template name") + expect(template_name_input).to_be_visible() + template_name = str(uuid.uuid4()) + template_name_input.fill(template_name) + print("GOT TEMPLATE NAME INPUT") + message_input = page.get_by_role("textbox", name="Message") + expect(message_input).to_be_visible() + message = "Test message" + message_input.fill(message) + print("FILLED OUT NEW TEMPLATE") + + save_button = page.get_by_text("Save") + expect(save_button).to_be_visible() + save_button.click() + print("SAVED NEW TEMPLATE") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + + use_this_template_button = page.get_by_text("Use this template") + expect(use_this_template_button).to_be_visible() + use_this_template_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + + use_my_phone_number_link = page.get_by_text("Use my phone number") + expect(use_my_phone_number_link).to_be_visible() + use_my_phone_number_link.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + + preview_button = page.get_by_text("Preview") + expect(preview_button).to_be_visible() + preview_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + + send_button = page.get_by_role("button", name="Send") + expect(send_button).to_be_visible() + send_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + + dashboard_button = page.get_by_text("Dashboard") + expect(dashboard_button).to_be_visible() + dashboard_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + + download_link = page.get_by_text("Download") + expect(download_link).to_be_visible() + + # Start waiting for the download + with page.expect_download() as download_info: + # Perform the action that initiates download + download_link.click() + download = download_info.value + # Wait for the download process to complete and save the downloaded file somewhere + download.save_as("download_test_file") + f = open("download_test_file", "r") + + content = f.read() + f.close() + # We don't want to wait 5 minutes to get a response from AWS about the message we sent + # So we are using this invalid phone number the e2e_test_user signed up with (12025555555) + # to shortcircuit the sending process. Our phone number validator will insta-fail the + # message and it won't be sent, but the report will still be generated, which is all + # we care about here. + assert "Phone Number,Template,Sent by,Batch File,Carrier Response,Status,Time" in content + assert "12025555555" in content + assert "one-off-e2e_test_user" in content + os.remove("download_test_file") + + _teardown(page) + + +def _teardown(page): + page.click("text='Settings'") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + page.click("text='Delete this service'") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + page.click("text='Yes, delete'") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check to make sure that we've arrived at the next page. + # Check the page title exists and matches what we expect. + expect(page).to_have_title(re.compile("Choose service")) From 54b9d2a5d6c72c7dccc7baba588ad2151198b2db Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 25 Mar 2024 12:06:38 -0700 Subject: [PATCH 04/71] add existing template case --- ...est_send_message_from_existing_template.py | 132 ++++++++++++++++-- 1 file changed, 118 insertions(+), 14 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 266160a6fa..644c3cd675 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -78,14 +78,7 @@ def _setup(page, end_to_end_context): return new_service_name -def test_add_new_service_workflow(authenticated_page, end_to_end_context): - page = authenticated_page - - new_service_name = _setup(page, end_to_end_context) - - print(page) - - +def handle_no_existing_template_case(page): create_template_button = page.get_by_text("Create your first template") expect(create_template_button).to_be_visible() create_template_button.click() @@ -136,7 +129,6 @@ def test_add_new_service_workflow(authenticated_page, end_to_end_context): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - use_this_template_button = page.get_by_text("Use this template") expect(use_this_template_button).to_be_visible() use_this_template_button.click() @@ -144,6 +136,78 @@ def test_add_new_service_workflow(authenticated_page, end_to_end_context): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + use_my_phone_number_link = page.get_by_text("Use my phone number") + expect(use_my_phone_number_link).to_be_visible() + use_my_phone_number_link.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + preview_button = page.get_by_text("Preview") + expect(preview_button).to_be_visible() + preview_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + send_button = page.get_by_role("button", name="Send") + expect(send_button).to_be_visible() + send_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + dashboard_button = page.get_by_text("Dashboard") + expect(dashboard_button).to_be_visible() + dashboard_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + download_link = page.get_by_text("Download") + expect(download_link).to_be_visible() + + # Start waiting for the download + with page.expect_download() as download_info: + # Perform the action that initiates download + download_link.click() + download = download_info.value + # Wait for the download process to complete and save the downloaded file somewhere + download.save_as("download_test_file") + f = open("download_test_file", "r") + + content = f.read() + f.close() + # We don't want to wait 5 minutes to get a response from AWS about the message we sent + # So we are using this invalid phone number the e2e_test_user signed up with (12025555555) + # to shortcircuit the sending process. Our phone number validator will insta-fail the + # message and it won't be sent, but the report will still be generated, which is all + # we care about here. + assert ( + "Phone Number,Template,Sent by,Batch File,Carrier Response,Status,Time" + in content + ) + assert "12025555555" in content + assert "one-off-e2e_test_user" in content + os.remove("download_test_file") + + +def handle_existing_template_case(page): + existing_template_link = page.get_by_text("Existing text message template") + expect(existing_template_link).to_be_visible() + existing_template_link.click() + print("GOT TO EXISTING TEMPLATE") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + use_this_template_button = page.get_by_role("button", name="Use this template") + expect(use_this_template_button).to_be_visible() + use_this_template_button.click() + print("GOT TO USE THIS TEMPLATE") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") use_my_phone_number_link = page.get_by_text("Use my phone number") expect(use_my_phone_number_link).to_be_visible() @@ -152,6 +216,35 @@ def test_add_new_service_workflow(authenticated_page, end_to_end_context): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + day_of_week_input = page.get_by_text("day of week") + expect(day_of_week_input).to_be_visible() + day_of_week_input.fill("Monday") + print("GOT DAY OF WEEK INPUT") + + continue_button = page.get_by_role("button", name="Continue") + + # continue_button = page.get_by_text("Continue") + expect(continue_button).to_be_visible() + continue_button.click() + print("GOT TO CONTINUE") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + color_input = page.get_by_text("color") + expect(day_of_week_input).to_be_visible() + day_of_week_input.fill("Green") + print("GOT COLOR INPUT") + + continue_button = page.get_by_role("button", name="Continue") + + # continue_button = page.get_by_text("Continue") + expect(continue_button).to_be_visible() + continue_button.click() + print("GOT TO CONTINUE") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") preview_button = page.get_by_text("Preview") expect(preview_button).to_be_visible() @@ -160,7 +253,6 @@ def test_add_new_service_workflow(authenticated_page, end_to_end_context): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - send_button = page.get_by_role("button", name="Send") expect(send_button).to_be_visible() send_button.click() @@ -168,7 +260,6 @@ def test_add_new_service_workflow(authenticated_page, end_to_end_context): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - dashboard_button = page.get_by_text("Dashboard") expect(dashboard_button).to_be_visible() dashboard_button.click() @@ -176,13 +267,12 @@ def test_add_new_service_workflow(authenticated_page, end_to_end_context): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - download_link = page.get_by_text("Download") expect(download_link).to_be_visible() # Start waiting for the download with page.expect_download() as download_info: - # Perform the action that initiates download + # Perform the action that initiates download download_link.click() download = download_info.value # Wait for the download process to complete and save the downloaded file somewhere @@ -196,11 +286,25 @@ def test_add_new_service_workflow(authenticated_page, end_to_end_context): # to shortcircuit the sending process. Our phone number validator will insta-fail the # message and it won't be sent, but the report will still be generated, which is all # we care about here. - assert "Phone Number,Template,Sent by,Batch File,Carrier Response,Status,Time" in content + assert ( + "Phone Number,Template,Sent by,Batch File,Carrier Response,Status,Time" + in content + ) assert "12025555555" in content assert "one-off-e2e_test_user" in content os.remove("download_test_file") + +def test_send_message_from_existing_template(authenticated_page, end_to_end_context): + page = authenticated_page + + new_service_name = _setup(page, end_to_end_context) + + if page.get_by_text("Create your first template"): + handle_no_existing_template_case(page) + else: + handle_existing_template_case(page) + _teardown(page) From e1c2a6a2fd735bcde8bac0658ef57520850ad825 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 25 Mar 2024 12:23:53 -0700 Subject: [PATCH 05/71] add existing template case --- .../test_send_message_from_existing_template.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 644c3cd675..cd4e3deb0e 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -300,10 +300,10 @@ def test_send_message_from_existing_template(authenticated_page, end_to_end_cont new_service_name = _setup(page, end_to_end_context) - if page.get_by_text("Create your first template"): - handle_no_existing_template_case(page) - else: - handle_existing_template_case(page) + #if page.get_by_text("Create your first template"): + # handle_no_existing_template_case(page) + #else: + handle_existing_template_case(page) _teardown(page) From 6367b2ce7608950fbd35c7363a1274f4c32c918c Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 25 Mar 2024 13:09:32 -0700 Subject: [PATCH 06/71] add existing template case --- tests/end_to_end/test_send_message_from_existing_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index cd4e3deb0e..e0b0be8b26 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -193,7 +193,7 @@ def handle_no_existing_template_case(page): def handle_existing_template_case(page): - existing_template_link = page.get_by_text("Existing text message template") + existing_template_link = page.get_by_text("Example text message template") expect(existing_template_link).to_be_visible() existing_template_link.click() print("GOT TO EXISTING TEMPLATE") From dbb60fc9635976d37731e16b5109f272ba9e5bf0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 25 Mar 2024 13:15:41 -0700 Subject: [PATCH 07/71] add existing template case --- tests/end_to_end/test_send_message_from_existing_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index e0b0be8b26..3b2702c285 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -201,7 +201,7 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - use_this_template_button = page.get_by_role("button", name="Use this template") + use_this_template_button = page.get_by_text("Use this template") expect(use_this_template_button).to_be_visible() use_this_template_button.click() print("GOT TO USE THIS TEMPLATE") From 3660dce9f5fc1a261bb6ac4f8099043fefcf6cd4 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 25 Mar 2024 13:21:07 -0700 Subject: [PATCH 08/71] add existing template case --- .../test_send_message_from_existing_template.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 3b2702c285..307db7f91d 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -300,10 +300,10 @@ def test_send_message_from_existing_template(authenticated_page, end_to_end_cont new_service_name = _setup(page, end_to_end_context) - #if page.get_by_text("Create your first template"): - # handle_no_existing_template_case(page) - #else: - handle_existing_template_case(page) + if page.get_by_text("Create your first template"): + handle_no_existing_template_case(page) + else: + handle_existing_template_case(page) _teardown(page) From 9dcf157ccbbdcf8bee0bd711599fac23819fe8bc Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 25 Mar 2024 13:29:59 -0700 Subject: [PATCH 09/71] add existing template case --- .../end_to_end/test_send_message_from_existing_template.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 307db7f91d..0f7ac0051e 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -132,6 +132,7 @@ def handle_no_existing_template_case(page): use_this_template_button = page.get_by_text("Use this template") expect(use_this_template_button).to_be_visible() use_this_template_button.click() + print("DID USE THIS TEMPLATE") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -139,6 +140,7 @@ def handle_no_existing_template_case(page): use_my_phone_number_link = page.get_by_text("Use my phone number") expect(use_my_phone_number_link).to_be_visible() use_my_phone_number_link.click() + print("DID USE MY PHONE NUBMER") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -146,6 +148,7 @@ def handle_no_existing_template_case(page): preview_button = page.get_by_text("Preview") expect(preview_button).to_be_visible() preview_button.click() + print("DID PREVIEW") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -153,10 +156,13 @@ def handle_no_existing_template_case(page): send_button = page.get_by_role("button", name="Send") expect(send_button).to_be_visible() send_button.click() + print("DID SEND") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + print(f"PAGE!!! {page}") + dashboard_button = page.get_by_text("Dashboard") expect(dashboard_button).to_be_visible() dashboard_button.click() From c4cce69f719739ae2b61c50d142c60b5aa1cdf0e Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 25 Mar 2024 13:52:51 -0700 Subject: [PATCH 10/71] try button instead of text --- tests/end_to_end/test_send_message_from_existing_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 0f7ac0051e..bc7bc5eac3 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -163,7 +163,7 @@ def handle_no_existing_template_case(page): print(f"PAGE!!! {page}") - dashboard_button = page.get_by_text("Dashboard") + dashboard_button = page.get_by_role("button", name="Dashboard") expect(dashboard_button).to_be_visible() dashboard_button.click() From 86efe62b22f7b6cdaff146f6579a7170297c7c05 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 25 Mar 2024 14:07:33 -0700 Subject: [PATCH 11/71] try button instead of text --- tests/end_to_end/test_send_message_from_existing_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index bc7bc5eac3..c9ae7970f4 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -161,7 +161,7 @@ def handle_no_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(f"PAGE!!! {page}") + print(f"PAGE!!! {page.content}") dashboard_button = page.get_by_role("button", name="Dashboard") expect(dashboard_button).to_be_visible() From 8bc41c59dca78c67eecb4af7de1031e815878bc1 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Mon, 25 Mar 2024 14:12:31 -0700 Subject: [PATCH 12/71] try button instead of text --- tests/end_to_end/test_send_message_from_existing_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index c9ae7970f4..ae98784d43 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -161,7 +161,7 @@ def handle_no_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(f"PAGE!!! {page.content}") + print(f"PAGE!!! {page.content()}") dashboard_button = page.get_by_role("button", name="Dashboard") expect(dashboard_button).to_be_visible() From e1be811ed5bc5bc5ba1fe76f14ebd3d9aaaa207b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 07:57:45 -0700 Subject: [PATCH 13/71] only test chromium right now --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index aa9b404afc..14fedc411d 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ dead-code: .PHONY: e2e-test e2e-test: export NEW_RELIC_ENVIRONMENT=test e2e-test: ## Run end-to-end integration tests; note that --browser webkit isn't currently working - poetry run pytest -v --browser chromium --browser firefox tests/end_to_end + poetry run pytest -vv --browser chromium tests/end_to_end .PHONY: js-lint js-lint: ## Run javascript linting scanners From 7ebc337bb0ba78e320280f56f96d4da837e7691d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 08:06:39 -0700 Subject: [PATCH 14/71] only test chromium right now --- tests/end_to_end/test_send_message_from_existing_template.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index ae98784d43..825fbf3c48 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -79,6 +79,8 @@ def _setup(page, end_to_end_context): def handle_no_existing_template_case(page): + print(f"ENTER HANDLE_NO_EXISTING_TEMPLATE_CASE") + print(page.content()) create_template_button = page.get_by_text("Create your first template") expect(create_template_button).to_be_visible() create_template_button.click() @@ -303,6 +305,8 @@ def handle_existing_template_case(page): def test_send_message_from_existing_template(authenticated_page, end_to_end_context): page = authenticated_page + print(f"START OF TEST") + print(page.content()) new_service_name = _setup(page, end_to_end_context) From 1ecb617eac46ea7546e394265b332fb8c76a6891 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 08:14:49 -0700 Subject: [PATCH 15/71] only test chromium right now --- tests/end_to_end/test_send_message_from_existing_template.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 825fbf3c48..a138b4db2c 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -306,9 +306,10 @@ def handle_existing_template_case(page): def test_send_message_from_existing_template(authenticated_page, end_to_end_context): page = authenticated_page print(f"START OF TEST") - print(page.content()) + new_service_name = _setup(page, end_to_end_context) + print(page.content()) if page.get_by_text("Create your first template"): handle_no_existing_template_case(page) From 6700f85784e7fbd82f3ff9fab3699e864adac137 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 08:22:11 -0700 Subject: [PATCH 16/71] only test chromium right now --- .../test_send_message_from_existing_template.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index a138b4db2c..83c3015b43 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -309,12 +309,12 @@ def test_send_message_from_existing_template(authenticated_page, end_to_end_cont new_service_name = _setup(page, end_to_end_context) - print(page.content()) + #print(page.content()) - if page.get_by_text("Create your first template"): - handle_no_existing_template_case(page) - else: - handle_existing_template_case(page) + # if page.get_by_text("Create your first template"): + # handle_no_existing_template_case(page) + #else: + handle_existing_template_case(page) _teardown(page) From 5e16f210d8ca00fa8d97e3e4420d5fb0654d0df3 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 08:32:37 -0700 Subject: [PATCH 17/71] only test chromium right now --- tests/end_to_end/test_send_message_from_existing_template.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 83c3015b43..f65059059f 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -209,6 +209,8 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + print(page.content()) + use_this_template_button = page.get_by_text("Use this template") expect(use_this_template_button).to_be_visible() use_this_template_button.click() From 25f217514765b976caa1b3399966cf0ab8e3e8fd Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 08:45:30 -0700 Subject: [PATCH 18/71] only test chromium right now --- ...est_send_message_from_existing_template.py | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index f65059059f..bdad89e7d8 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -209,27 +209,27 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(page.content()) - use_this_template_button = page.get_by_text("Use this template") - expect(use_this_template_button).to_be_visible() - use_this_template_button.click() - print("GOT TO USE THIS TEMPLATE") + + # use_this_template_button = page.get_by_text("Use this template") + # expect(use_this_template_button).to_be_visible() + # use_this_template_button.click() + # print("GOT TO USE THIS TEMPLATE") # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") + # page.wait_for_load_state("domcontentloaded") - use_my_phone_number_link = page.get_by_text("Use my phone number") - expect(use_my_phone_number_link).to_be_visible() - use_my_phone_number_link.click() + # use_my_phone_number_link = page.get_by_text("Use my phone number") + # expect(use_my_phone_number_link).to_be_visible() + # use_my_phone_number_link.click() # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") + # page.wait_for_load_state("domcontentloaded") - day_of_week_input = page.get_by_text("day of week") - expect(day_of_week_input).to_be_visible() - day_of_week_input.fill("Monday") - print("GOT DAY OF WEEK INPUT") + # day_of_week_input = page.get_by_text("day of week") + # expect(day_of_week_input).to_be_visible() + # day_of_week_input.fill("Monday") + # print("GOT DAY OF WEEK INPUT") continue_button = page.get_by_role("button", name="Continue") From afefa092ed3e03b004efc6b02f447ae996173812 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 08:56:50 -0700 Subject: [PATCH 19/71] only test chromium right now --- .../test_send_message_from_existing_template.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index bdad89e7d8..faa0e796df 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -241,10 +241,12 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - color_input = page.get_by_text("color") - expect(day_of_week_input).to_be_visible() - day_of_week_input.fill("Green") - print("GOT COLOR INPUT") + print(page.content()) + + #color_input = page.get_by_text("color") + #expect(day_of_week_input).to_be_visible() + #day_of_week_input.fill("Green") + #print("GOT COLOR INPUT") continue_button = page.get_by_role("button", name="Continue") From 8b33fcc1f5cb9c8df5efb40111a6a0610ef2a48c Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 09:03:30 -0700 Subject: [PATCH 20/71] only test chromium right now --- tests/end_to_end/test_send_message_from_existing_template.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index faa0e796df..08fe913e9e 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -241,7 +241,7 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(page.content()) + #color_input = page.get_by_text("color") #expect(day_of_week_input).to_be_visible() @@ -258,6 +258,8 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + print(page.content()) + preview_button = page.get_by_text("Preview") expect(preview_button).to_be_visible() preview_button.click() From d6a0e25c38eaa3204089667c0a784aafb376bc69 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 09:10:52 -0700 Subject: [PATCH 21/71] only test chromium right now --- ...est_send_message_from_existing_template.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 08fe913e9e..6d05cc95b0 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -226,10 +226,6 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. # page.wait_for_load_state("domcontentloaded") - # day_of_week_input = page.get_by_text("day of week") - # expect(day_of_week_input).to_be_visible() - # day_of_week_input.fill("Monday") - # print("GOT DAY OF WEEK INPUT") continue_button = page.get_by_role("button", name="Continue") @@ -258,6 +254,21 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + day_of_week_input = page.get_by_text("day of week") + expect(day_of_week_input).to_be_visible() + day_of_week_input.fill("Monday") + print("GOT DAY OF WEEK INPUT") + + continue_button = page.get_by_role("button", name="Continue") + + # continue_button = page.get_by_text("Continue") + expect(continue_button).to_be_visible() + continue_button.click() + print("GOT TO CONTINUE") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + print(page.content()) preview_button = page.get_by_text("Preview") From 578d00a9ee6dd053bf902a7cd259623088aa697b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 09:18:32 -0700 Subject: [PATCH 22/71] only test chromium right now --- tests/end_to_end/test_send_message_from_existing_template.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 6d05cc95b0..7d887df892 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -254,7 +254,9 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - day_of_week_input = page.get_by_text("day of week") + + day_of_week_input = page.locator('xpath=//input[@name="day of week"]') + # day_of_week_input = page.get_by_text("day of week") expect(day_of_week_input).to_be_visible() day_of_week_input.fill("Monday") print("GOT DAY OF WEEK INPUT") From 08603c993ccafc0d21a3e1b2b151692e00323602 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 09:24:31 -0700 Subject: [PATCH 23/71] only test chromium right now --- tests/end_to_end/test_send_message_from_existing_template.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 7d887df892..8ccc61dc74 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -253,10 +253,11 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + print(page.content()) - - day_of_week_input = page.locator('xpath=//input[@name="day of week"]') + # day_of_week_input = page.locator('xpath=//input[@name="day of week"]') # day_of_week_input = page.get_by_text("day of week") + day_of_week_input = page.get_by_role("textbox", name="day of week") expect(day_of_week_input).to_be_visible() day_of_week_input.fill("Monday") print("GOT DAY OF WEEK INPUT") From 96c1a2b59f1c8dab253f0db51471acf7875f4fac Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 09:33:07 -0700 Subject: [PATCH 24/71] only test chromium right now --- ...est_send_message_from_existing_template.py | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 8ccc61dc74..f5390c408a 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -80,7 +80,7 @@ def _setup(page, end_to_end_context): def handle_no_existing_template_case(page): print(f"ENTER HANDLE_NO_EXISTING_TEMPLATE_CASE") - print(page.content()) + create_template_button = page.get_by_text("Create your first template") expect(create_template_button).to_be_visible() create_template_button.click() @@ -163,7 +163,7 @@ def handle_no_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(f"PAGE!!! {page.content()}") + dashboard_button = page.get_by_role("button", name="Dashboard") expect(dashboard_button).to_be_visible() @@ -239,10 +239,6 @@ def handle_existing_template_case(page): - #color_input = page.get_by_text("color") - #expect(day_of_week_input).to_be_visible() - #day_of_week_input.fill("Green") - #print("GOT COLOR INPUT") continue_button = page.get_by_role("button", name="Continue") @@ -253,7 +249,6 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(page.content()) # day_of_week_input = page.locator('xpath=//input[@name="day of week"]') # day_of_week_input = page.get_by_text("day of week") @@ -272,7 +267,21 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(page.content()) + color_input = page.get_by_text("color") + expect(day_of_week_input).to_be_visible() + day_of_week_input.fill("Green") + print("GOT COLOR INPUT") + + + # continue_button = page.get_by_text("Continue") + expect(continue_button).to_be_visible() + continue_button.click() + print("GOT TO CONTINUE") + + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + preview_button = page.get_by_text("Preview") expect(preview_button).to_be_visible() @@ -281,6 +290,9 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + print(page.content()) + + send_button = page.get_by_role("button", name="Send") expect(send_button).to_be_visible() send_button.click() @@ -329,7 +341,7 @@ def test_send_message_from_existing_template(authenticated_page, end_to_end_cont new_service_name = _setup(page, end_to_end_context) - #print(page.content()) + # if page.get_by_text("Create your first template"): # handle_no_existing_template_case(page) From 4874c91f0a664860be593ff9467595154160b845 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 09:38:41 -0700 Subject: [PATCH 25/71] only test chromium right now --- .../end_to_end/test_send_message_from_existing_template.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index f5390c408a..45f848c3b0 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -267,9 +267,9 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - color_input = page.get_by_text("color") - expect(day_of_week_input).to_be_visible() - day_of_week_input.fill("Green") + color_input = page.get_by_role("textbox", name="color") + expect(color_input).to_be_visible() + color_input.fill("Green") print("GOT COLOR INPUT") From 790c274a6e29d1efa63adcdb1f9b68d1bef5cc0d Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 09:43:54 -0700 Subject: [PATCH 26/71] only test chromium right now --- .../end_to_end/test_send_message_from_existing_template.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 45f848c3b0..cf270c3acd 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -290,8 +290,6 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(page.content()) - send_button = page.get_by_role("button", name="Send") expect(send_button).to_be_visible() @@ -300,6 +298,10 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + + print(page.content()) + + dashboard_button = page.get_by_text("Dashboard") expect(dashboard_button).to_be_visible() dashboard_button.click() From c4a594663bf586507d4b4f3f2aa01241505db0de Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 09:57:16 -0700 Subject: [PATCH 27/71] put back firefox tests --- Makefile | 2 +- ...est_send_message_from_existing_template.py | 45 +++++++++---------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 14fedc411d..0e4ff6a234 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ dead-code: .PHONY: e2e-test e2e-test: export NEW_RELIC_ENVIRONMENT=test e2e-test: ## Run end-to-end integration tests; note that --browser webkit isn't currently working - poetry run pytest -vv --browser chromium tests/end_to_end + poetry run pytest -vv --browser chromium --browser firefox tests/end_to_end .PHONY: js-lint js-lint: ## Run javascript linting scanners diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index cf270c3acd..7f7da53dc0 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -293,48 +293,47 @@ def handle_existing_template_case(page): send_button = page.get_by_role("button", name="Send") expect(send_button).to_be_visible() - send_button.click() + # send_button.click() # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") + # page.wait_for_load_state("domcontentloaded") - print(page.content()) - dashboard_button = page.get_by_text("Dashboard") - expect(dashboard_button).to_be_visible() - dashboard_button.click() + # dashboard_button = page.get_by_text("Dashboard") + # expect(dashboard_button).to_be_visible() + # dashboard_button.click() # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") + # page.wait_for_load_state("domcontentloaded") - download_link = page.get_by_text("Download") - expect(download_link).to_be_visible() + # download_link = page.get_by_text("Download") + # expect(download_link).to_be_visible() # Start waiting for the download - with page.expect_download() as download_info: + # with page.expect_download() as download_info: # Perform the action that initiates download - download_link.click() - download = download_info.value + # download_link.click() + #download = download_info.value # Wait for the download process to complete and save the downloaded file somewhere - download.save_as("download_test_file") - f = open("download_test_file", "r") + #download.save_as("download_test_file") + #f = open("download_test_file", "r") - content = f.read() - f.close() + #content = f.read() + #f.close() # We don't want to wait 5 minutes to get a response from AWS about the message we sent # So we are using this invalid phone number the e2e_test_user signed up with (12025555555) # to shortcircuit the sending process. Our phone number validator will insta-fail the # message and it won't be sent, but the report will still be generated, which is all # we care about here. - assert ( - "Phone Number,Template,Sent by,Batch File,Carrier Response,Status,Time" - in content - ) - assert "12025555555" in content - assert "one-off-e2e_test_user" in content - os.remove("download_test_file") + #assert ( + # "Phone Number,Template,Sent by,Batch File,Carrier Response,Status,Time" + # in content + #) + #assert "12025555555" in content + #assert "one-off-e2e_test_user" in content + #os.remove("download_test_file") def test_send_message_from_existing_template(authenticated_page, end_to_end_context): From edf3961f0d5ce244725d798a6d406e8d00b1659a Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 10:30:11 -0700 Subject: [PATCH 28/71] works locally and maybe on github as well --- Makefile | 2 +- .../test_send_message_from_existing_template.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 0e4ff6a234..255a7351d3 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ dead-code: .PHONY: e2e-test e2e-test: export NEW_RELIC_ENVIRONMENT=test e2e-test: ## Run end-to-end integration tests; note that --browser webkit isn't currently working - poetry run pytest -vv --browser chromium --browser firefox tests/end_to_end + poetry run pytest -vv --browser chromium --browser firefox --headed tests/end_to_end .PHONY: js-lint js-lint: ## Run javascript linting scanners diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 7f7da53dc0..920dee488c 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -165,7 +165,7 @@ def handle_no_existing_template_case(page): - dashboard_button = page.get_by_role("button", name="Dashboard") + dashboard_button = page.get_by_text("Dashboard") expect(dashboard_button).to_be_visible() dashboard_button.click() @@ -343,11 +343,11 @@ def test_send_message_from_existing_template(authenticated_page, end_to_end_cont new_service_name = _setup(page, end_to_end_context) - - # if page.get_by_text("Create your first template"): - # handle_no_existing_template_case(page) - #else: - handle_existing_template_case(page) + print(page.content()) + if page.get_by_text("Create your first template"): + handle_no_existing_template_case(page) + else: + handle_existing_template_case(page) _teardown(page) From 11bfc829e7b879f222bde16e90817a4a0d4a5236 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 10:45:17 -0700 Subject: [PATCH 29/71] works locally and maybe on github as well --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 255a7351d3..ed508745a6 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ dead-code: .PHONY: e2e-test e2e-test: export NEW_RELIC_ENVIRONMENT=test e2e-test: ## Run end-to-end integration tests; note that --browser webkit isn't currently working - poetry run pytest -vv --browser chromium --browser firefox --headed tests/end_to_end + poetry run pytest -vv --browser chromium --browser firefox tests/end_to_end .PHONY: js-lint js-lint: ## Run javascript linting scanners From b9b59ea453d7f0f12f6e64de780f043057e256e6 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 10:59:16 -0700 Subject: [PATCH 30/71] works locally and maybe on github as well --- tests/end_to_end/test_send_message_from_existing_template.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 920dee488c..848a7ec848 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -344,7 +344,9 @@ def test_send_message_from_existing_template(authenticated_page, end_to_end_cont new_service_name = _setup(page, end_to_end_context) print(page.content()) - if page.get_by_text("Create your first template"): + x = page.get_by_text("Create your first template") + print(f"X = {x.count()}") + if page.get_by_text("Create your first template").count() > 0: handle_no_existing_template_case(page) else: handle_existing_template_case(page) From 6f56123eeaac312b4e9a7bc65839900aa657e982 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 11:13:54 -0700 Subject: [PATCH 31/71] works locally and maybe on github as well --- ...est_send_message_from_existing_template.py | 93 ++++++------------- 1 file changed, 29 insertions(+), 64 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index 848a7ec848..f8793c27f1 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -79,12 +79,19 @@ def _setup(page, end_to_end_context): def handle_no_existing_template_case(page): - print(f"ENTER HANDLE_NO_EXISTING_TEMPLATE_CASE") + """ + This is the test path for local development. Developers have their own + databases and typically they have service or two already created, which + means they won't see the "Example text message template" which is done + as an introduction. Instead they will see "Create your first template". + Note that this test goes all the way through sending and downloading the + report and verifying the phone number, etc. in the report. This is because + developer systems are fully connected to AWS. + """ create_template_button = page.get_by_text("Create your first template") expect(create_template_button).to_be_visible() create_template_button.click() - print("GOT TO CREATE TEMPLATE") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -92,7 +99,6 @@ def handle_no_existing_template_case(page): new_template_button = page.get_by_text("New template") expect(new_template_button).to_be_visible() new_template_button.click() - print("GOT TO NEW TEMPLATE") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -100,14 +106,12 @@ def handle_no_existing_template_case(page): start_with_a_blank_template_radio = page.get_by_text("Start with a blank template") expect(start_with_a_blank_template_radio).to_be_visible() start_with_a_blank_template_radio.click() - print("GOT TO START WITH A BLANK TEMPLATE") continue_button = page.get_by_role("button", name="Continue") # continue_button = page.get_by_text("Continue") expect(continue_button).to_be_visible() continue_button.click() - print("GOT TO CONTINUE") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -116,17 +120,14 @@ def handle_no_existing_template_case(page): expect(template_name_input).to_be_visible() template_name = str(uuid.uuid4()) template_name_input.fill(template_name) - print("GOT TEMPLATE NAME INPUT") message_input = page.get_by_role("textbox", name="Message") expect(message_input).to_be_visible() message = "Test message" message_input.fill(message) - print("FILLED OUT NEW TEMPLATE") save_button = page.get_by_text("Save") expect(save_button).to_be_visible() save_button.click() - print("SAVED NEW TEMPLATE") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -134,7 +135,6 @@ def handle_no_existing_template_case(page): use_this_template_button = page.get_by_text("Use this template") expect(use_this_template_button).to_be_visible() use_this_template_button.click() - print("DID USE THIS TEMPLATE") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -142,7 +142,6 @@ def handle_no_existing_template_case(page): use_my_phone_number_link = page.get_by_text("Use my phone number") expect(use_my_phone_number_link).to_be_visible() use_my_phone_number_link.click() - print("DID USE MY PHONE NUBMER") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -150,7 +149,6 @@ def handle_no_existing_template_case(page): preview_button = page.get_by_text("Preview") expect(preview_button).to_be_visible() preview_button.click() - print("DID PREVIEW") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -158,13 +156,10 @@ def handle_no_existing_template_case(page): send_button = page.get_by_role("button", name="Send") expect(send_button).to_be_visible() send_button.click() - print("DID SEND") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - - dashboard_button = page.get_by_text("Dashboard") expect(dashboard_button).to_be_visible() dashboard_button.click() @@ -201,51 +196,37 @@ def handle_no_existing_template_case(page): def handle_existing_template_case(page): + """ + This is the test path used in the Github action. Right now the e2e tests + are not connected to AWS, so we can't actually send messages. Hence, the + test stops when it verifies that the 'Send' button exists on the page. In + the future we would like to change the way e2e tests run so they run against + staging, in which case either the code in this method can be uncommented, + or perhaps this path will be unnecessary (because staging is not completely clean) + and we will just use the same path as for local development. + """ existing_template_link = page.get_by_text("Example text message template") expect(existing_template_link).to_be_visible() existing_template_link.click() - print("GOT TO EXISTING TEMPLATE") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - - # use_this_template_button = page.get_by_text("Use this template") - # expect(use_this_template_button).to_be_visible() - # use_this_template_button.click() - # print("GOT TO USE THIS TEMPLATE") - - # Check to make sure that we've arrived at the next page. - # page.wait_for_load_state("domcontentloaded") - - # use_my_phone_number_link = page.get_by_text("Use my phone number") - # expect(use_my_phone_number_link).to_be_visible() - # use_my_phone_number_link.click() - - # Check to make sure that we've arrived at the next page. - # page.wait_for_load_state("domcontentloaded") - - continue_button = page.get_by_role("button", name="Continue") # continue_button = page.get_by_text("Continue") expect(continue_button).to_be_visible() continue_button.click() - print("GOT TO CONTINUE") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - - - continue_button = page.get_by_role("button", name="Continue") # continue_button = page.get_by_text("Continue") expect(continue_button).to_be_visible() continue_button.click() - print("GOT TO CONTINUE") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -255,14 +236,12 @@ def handle_existing_template_case(page): day_of_week_input = page.get_by_role("textbox", name="day of week") expect(day_of_week_input).to_be_visible() day_of_week_input.fill("Monday") - print("GOT DAY OF WEEK INPUT") continue_button = page.get_by_role("button", name="Continue") # continue_button = page.get_by_text("Continue") expect(continue_button).to_be_visible() continue_button.click() - print("GOT TO CONTINUE") # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") @@ -270,19 +249,14 @@ def handle_existing_template_case(page): color_input = page.get_by_role("textbox", name="color") expect(color_input).to_be_visible() color_input.fill("Green") - print("GOT COLOR INPUT") - # continue_button = page.get_by_text("Continue") expect(continue_button).to_be_visible() continue_button.click() - print("GOT TO CONTINUE") - # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - preview_button = page.get_by_text("Preview") expect(preview_button).to_be_visible() preview_button.click() @@ -290,7 +264,6 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - send_button = page.get_by_role("button", name="Send") expect(send_button).to_be_visible() # send_button.click() @@ -298,9 +271,6 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. # page.wait_for_load_state("domcontentloaded") - - - # dashboard_button = page.get_by_text("Dashboard") # expect(dashboard_button).to_be_visible() # dashboard_button.click() @@ -313,39 +283,34 @@ def handle_existing_template_case(page): # Start waiting for the download # with page.expect_download() as download_info: - # Perform the action that initiates download + # Perform the action that initiates download # download_link.click() - #download = download_info.value + # download = download_info.value # Wait for the download process to complete and save the downloaded file somewhere - #download.save_as("download_test_file") - #f = open("download_test_file", "r") + # download.save_as("download_test_file") + # f = open("download_test_file", "r") - #content = f.read() - #f.close() + # content = f.read() + # f.close() # We don't want to wait 5 minutes to get a response from AWS about the message we sent # So we are using this invalid phone number the e2e_test_user signed up with (12025555555) # to shortcircuit the sending process. Our phone number validator will insta-fail the # message and it won't be sent, but the report will still be generated, which is all # we care about here. - #assert ( + # assert ( # "Phone Number,Template,Sent by,Batch File,Carrier Response,Status,Time" # in content - #) - #assert "12025555555" in content - #assert "one-off-e2e_test_user" in content - #os.remove("download_test_file") + # ) + # assert "12025555555" in content + # assert "one-off-e2e_test_user" in content + # os.remove("download_test_file") def test_send_message_from_existing_template(authenticated_page, end_to_end_context): page = authenticated_page - print(f"START OF TEST") - new_service_name = _setup(page, end_to_end_context) - print(page.content()) - x = page.get_by_text("Create your first template") - print(f"X = {x.count()}") if page.get_by_text("Create your first template").count() > 0: handle_no_existing_template_case(page) else: From abef1230b8c36aa7f2f34f760fa8c4eb81489aa5 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 26 Mar 2024 11:22:22 -0700 Subject: [PATCH 32/71] final? --- tests/end_to_end/test_accounts_page.py | 86 ++++++++++++++++++- ...est_send_message_from_existing_template.py | 3 +- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/tests/end_to_end/test_accounts_page.py b/tests/end_to_end/test_accounts_page.py index e59fe7f9e3..b6fe8c5ac7 100644 --- a/tests/end_to_end/test_accounts_page.py +++ b/tests/end_to_end/test_accounts_page.py @@ -8,4 +8,88 @@ def test_add_new_service_workflow(authenticated_page, end_to_end_context): - pass + page = authenticated_page + + # Prepare for adding a new service later in the test. + current_date_time = datetime.datetime.now() + new_service_name = "E2E Federal Test Service {now} - {browser_type}".format( + now=current_date_time.strftime("%m/%d/%Y %H:%M:%S"), + browser_type=end_to_end_context.browser.browser_type.name, + ) + + page.goto(f"{E2E_TEST_URI}/accounts") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check to make sure that we've arrived at the next page. + # Check the page title exists and matches what we expect. + expect(page).to_have_title(re.compile("Choose service")) + + # Check for the sign in heading. + sign_in_heading = page.get_by_role("heading", name="Choose service") + expect(sign_in_heading).to_be_visible() + + # Retrieve some prominent elements on the page for testing. + add_service_button = page.get_by_role( + "button", name=re.compile("Add a new service") + ) + + expect(add_service_button).to_be_visible() + + existing_service_link = page.get_by_role("link", name=new_service_name) + + # Check to see if the service was already created - if so, we should fail. + # TODO: Figure out how to make this truly isolated, and/or work in a + # delete service workflow. + expect(existing_service_link).to_have_count(0) + + # Click on add a new service. + add_service_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check for the sign in heading. + about_heading = page.get_by_role("heading", name="About your service") + expect(about_heading).to_be_visible() + + # Retrieve some prominent elements on the page for testing. + service_name_input = page.locator('xpath=//input[@name="name"]') + add_service_button = page.get_by_role("button", name=re.compile("Add service")) + + expect(service_name_input).to_be_visible() + expect(add_service_button).to_be_visible() + + # Fill in the form. + service_name_input.fill(new_service_name) + + # Click on add service. + add_service_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check for the service name title and heading. + service_heading = page.get_by_text(new_service_name, exact=True) + expect(service_heading).to_be_visible() + expect(page).to_have_title(re.compile(new_service_name)) + + page.click("text='Settings'") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + page.click("text='Delete this service'") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + page.click("text='Yes, delete'") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check to make sure that we've arrived at the next page. + # Check the page title exists and matches what we expect. + expect(page).to_have_title(re.compile("Choose service")) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index f8793c27f1..d09ecf73fa 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -212,7 +212,6 @@ def handle_existing_template_case(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - continue_button = page.get_by_role("button", name="Continue") # continue_button = page.get_by_text("Continue") @@ -309,7 +308,7 @@ def handle_existing_template_case(page): def test_send_message_from_existing_template(authenticated_page, end_to_end_context): page = authenticated_page - new_service_name = _setup(page, end_to_end_context) + _setup(page, end_to_end_context) if page.get_by_text("Create your first template").count() > 0: handle_no_existing_template_case(page) From c9c8882dc9d465b2f66306a146b153218e39cfa9 Mon Sep 17 00:00:00 2001 From: Andrew Shumway Date: Wed, 27 Mar 2024 10:10:56 -0600 Subject: [PATCH 33/71] Fix test --- tests/app/main/views/test_dashboard.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index cd543d9034..9679f2bce3 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -679,7 +679,7 @@ def test_should_show_redirect_from_template_history( ) -@freeze_time("2017-1-1 12:00") # Switching to calendar year +@freeze_time("2017-01-01 12:00") @pytest.mark.parametrize( "extra_args", [ @@ -705,6 +705,7 @@ def test_should_show_monthly_breakdown_of_template_usage( ) assert len(table_rows) == len(["January"]) + # October is the only month with data, thus it's not in the list. assert len(page.select(".table-no-data")) == len( [ "January", @@ -716,8 +717,8 @@ def test_should_show_monthly_breakdown_of_template_usage( "July", "August", "September", - "October", "November", + "December", ] ) From 624a89a54606616cc9903501234640d7fcd6121b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 27 Mar 2024 10:21:01 -0700 Subject: [PATCH 34/71] create new template test --- tests/end_to_end/test_create_new_template.py | 180 +++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 tests/end_to_end/test_create_new_template.py diff --git a/tests/end_to_end/test_create_new_template.py b/tests/end_to_end/test_create_new_template.py new file mode 100644 index 0000000000..5bdd1546a6 --- /dev/null +++ b/tests/end_to_end/test_create_new_template.py @@ -0,0 +1,180 @@ +import datetime +import os +import re +import uuid + +from playwright.sync_api import expect + +E2E_TEST_URI = os.getenv("NOTIFY_E2E_TEST_URI") + + +def _setup(page, end_to_end_context): + # Prepare for adding a new service later in the test. + current_date_time = datetime.datetime.now() + new_service_name = "E2E Federal Test Service {now} - {browser_type}".format( + now=current_date_time.strftime("%m/%d/%Y %H:%M:%S"), + browser_type=end_to_end_context.browser.browser_type.name, + ) + + page.goto(f"{E2E_TEST_URI}/accounts") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check to make sure that we've arrived at the next page. + # Check the page title exists and matches what we expect. + expect(page).to_have_title(re.compile("Choose service")) + + # Check for the sign in heading. + sign_in_heading = page.get_by_role("heading", name="Choose service") + expect(sign_in_heading).to_be_visible() + + # Retrieve some prominent elements on the page for testing. + add_service_button = page.get_by_role( + "button", name=re.compile("Add a new service") + ) + + expect(add_service_button).to_be_visible() + + existing_service_link = page.get_by_role("link", name=new_service_name) + + # Check to see if the service was already created - if so, we should fail. + # TODO: Figure out how to make this truly isolated, and/or work in a + # delete service workflow. + expect(existing_service_link).to_have_count(0) + + # Click on add a new service. + add_service_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check for the sign in heading. + about_heading = page.get_by_role("heading", name="About your service") + expect(about_heading).to_be_visible() + + # Retrieve some prominent elements on the page for testing. + service_name_input = page.locator('xpath=//input[@name="name"]') + add_service_button = page.get_by_role("button", name=re.compile("Add service")) + + expect(service_name_input).to_be_visible() + expect(add_service_button).to_be_visible() + + # Fill in the form. + service_name_input.fill(new_service_name) + + # Click on add service. + add_service_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check for the service name title and heading. + service_heading = page.get_by_text(new_service_name, exact=True) + + expect(service_heading).to_be_visible() + expect(page).to_have_title(re.compile(new_service_name)) + + return new_service_name + + +def create_new_template(page): + + create_template_button = page.get_by_text("Create your first template") + expect(create_template_button).to_be_visible() + create_template_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + new_template_button = page.get_by_text("New template") + expect(new_template_button).to_be_visible() + new_template_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + start_with_a_blank_template_radio = page.get_by_text("Start with a blank template") + expect(start_with_a_blank_template_radio).to_be_visible() + start_with_a_blank_template_radio.click() + + continue_button = page.get_by_role("button", name="Continue") + + # continue_button = page.get_by_text("Continue") + expect(continue_button).to_be_visible() + continue_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + template_name_input = page.get_by_text("Template name") + expect(template_name_input).to_be_visible() + template_name = str(uuid.uuid4()) + template_name_input.fill(template_name) + message_input = page.get_by_role("textbox", name="Message") + expect(message_input).to_be_visible() + message = "Test message" + message_input.fill(message) + + save_button = page.get_by_text("Save") + expect(save_button).to_be_visible() + save_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + use_this_template_button = page.get_by_text("Use this template") + expect(use_this_template_button).to_be_visible() + use_this_template_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + use_my_phone_number_link = page.get_by_text("Use my phone number") + expect(use_my_phone_number_link).to_be_visible() + use_my_phone_number_link.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + preview_button = page.get_by_text("Preview") + expect(preview_button).to_be_visible() + preview_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + print(page.content()) + + + + +def test_create_new_template(authenticated_page, end_to_end_context): + page = authenticated_page + + _setup(page, end_to_end_context) + + create_new_template(page) + + + _teardown(page) + + +def _teardown(page): + page.click("text='Settings'") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + page.click("text='Delete this service'") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + page.click("text='Yes, delete'") + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + # Check to make sure that we've arrived at the next page. + # Check the page title exists and matches what we expect. + expect(page).to_have_title(re.compile("Choose service")) From bbb351861dcb50215e10783cb4d4a8d894c505c5 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 27 Mar 2024 10:26:56 -0700 Subject: [PATCH 35/71] create new template test --- tests/end_to_end/test_create_new_template.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/end_to_end/test_create_new_template.py b/tests/end_to_end/test_create_new_template.py index 5bdd1546a6..d7a0a06ce9 100644 --- a/tests/end_to_end/test_create_new_template.py +++ b/tests/end_to_end/test_create_new_template.py @@ -80,6 +80,7 @@ def _setup(page, end_to_end_context): def create_new_template(page): + print(page.content()) create_template_button = page.get_by_text("Create your first template") expect(create_template_button).to_be_visible() create_template_button.click() From 939c1c978e86890665349f943b2dc57e1cfeab85 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 27 Mar 2024 10:35:09 -0700 Subject: [PATCH 36/71] try current service link --- tests/end_to_end/test_create_new_template.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/end_to_end/test_create_new_template.py b/tests/end_to_end/test_create_new_template.py index d7a0a06ce9..645811b107 100644 --- a/tests/end_to_end/test_create_new_template.py +++ b/tests/end_to_end/test_create_new_template.py @@ -80,7 +80,14 @@ def _setup(page, end_to_end_context): def create_new_template(page): + current_service_link = page.get_by_text("Current service") + expect(current_service_link).to_be_visible() + current_service_link.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") print(page.content()) + create_template_button = page.get_by_text("Create your first template") expect(create_template_button).to_be_visible() create_template_button.click() From 70c3457dbd2ac3d7245fec37a4995c529809e1b0 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 27 Mar 2024 10:52:22 -0700 Subject: [PATCH 37/71] try current service link --- tests/end_to_end/test_create_new_template.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/end_to_end/test_create_new_template.py b/tests/end_to_end/test_create_new_template.py index 645811b107..a30722a573 100644 --- a/tests/end_to_end/test_create_new_template.py +++ b/tests/end_to_end/test_create_new_template.py @@ -88,6 +88,15 @@ def create_new_template(page): page.wait_for_load_state("domcontentloaded") print(page.content()) + send_messages_button = page.get_by_text("Send messages") + expect(send_messages_button).to_be_visible() + send_messages_button.click() + + # Check to make sure that we've arrived at the next page. + page.wait_for_load_state("domcontentloaded") + + + create_template_button = page.get_by_text("Create your first template") expect(create_template_button).to_be_visible() create_template_button.click() From f6f750e5d01c07f6d15a24c8dfa6733ef1e22efb Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 27 Mar 2024 11:02:53 -0700 Subject: [PATCH 38/71] try current service link --- tests/end_to_end/test_create_new_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end_to_end/test_create_new_template.py b/tests/end_to_end/test_create_new_template.py index a30722a573..43d35ec253 100644 --- a/tests/end_to_end/test_create_new_template.py +++ b/tests/end_to_end/test_create_new_template.py @@ -88,7 +88,7 @@ def create_new_template(page): page.wait_for_load_state("domcontentloaded") print(page.content()) - send_messages_button = page.get_by_text("Send messages") + send_messages_button = page.get_by_role("button", name="Send messages") expect(send_messages_button).to_be_visible() send_messages_button.click() From a85681252f00ff733177f688c1978d4aae03883a Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 27 Mar 2024 12:15:44 -0700 Subject: [PATCH 39/71] fix --- tests/end_to_end/test_create_new_template.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/tests/end_to_end/test_create_new_template.py b/tests/end_to_end/test_create_new_template.py index 43d35ec253..4b436d0a9c 100644 --- a/tests/end_to_end/test_create_new_template.py +++ b/tests/end_to_end/test_create_new_template.py @@ -86,31 +86,24 @@ def create_new_template(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(page.content()) - send_messages_button = page.get_by_role("button", name="Send messages") - expect(send_messages_button).to_be_visible() + + send_messages_button = page.get_by_role("link", name="Send messages") + # expect(send_messages_button).to_be_visible() send_messages_button.click() # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + print(page.content()) - - create_template_button = page.get_by_text("Create your first template") + create_template_button = page.get_by_role("button", name="New template") expect(create_template_button).to_be_visible() create_template_button.click() # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - new_template_button = page.get_by_text("New template") - expect(new_template_button).to_be_visible() - new_template_button.click() - - # Check to make sure that we've arrived at the next page. - page.wait_for_load_state("domcontentloaded") - start_with_a_blank_template_radio = page.get_by_text("Start with a blank template") expect(start_with_a_blank_template_radio).to_be_visible() start_with_a_blank_template_radio.click() From 81412ddd1e98430618a291e344a76ae315c581d8 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 27 Mar 2024 12:32:29 -0700 Subject: [PATCH 40/71] fix --- tests/end_to_end/test_create_new_template.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/end_to_end/test_create_new_template.py b/tests/end_to_end/test_create_new_template.py index 4b436d0a9c..23836ea494 100644 --- a/tests/end_to_end/test_create_new_template.py +++ b/tests/end_to_end/test_create_new_template.py @@ -87,15 +87,12 @@ def create_new_template(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - send_messages_button = page.get_by_role("link", name="Send messages") # expect(send_messages_button).to_be_visible() send_messages_button.click() # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(page.content()) - create_template_button = page.get_by_role("button", name="New template") expect(create_template_button).to_be_visible() @@ -123,7 +120,7 @@ def create_new_template(page): template_name_input.fill(template_name) message_input = page.get_by_role("textbox", name="Message") expect(message_input).to_be_visible() - message = "Test message" + message = "Test message for e2e test" message_input.fill(message) save_button = page.get_by_text("Save") @@ -153,9 +150,8 @@ def create_new_template(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") - print(page.content()) - + assert "Test message for e2e test" in page.content() def test_create_new_template(authenticated_page, end_to_end_context): @@ -165,7 +161,6 @@ def test_create_new_template(authenticated_page, end_to_end_context): create_new_template(page) - _teardown(page) From 5a81c11348225de211b9f4c133d9b10a831f7d56 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 27 Mar 2024 12:40:45 -0700 Subject: [PATCH 41/71] add comment --- tests/end_to_end/test_create_new_template.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/end_to_end/test_create_new_template.py b/tests/end_to_end/test_create_new_template.py index 23836ea494..936ce3a2f9 100644 --- a/tests/end_to_end/test_create_new_template.py +++ b/tests/end_to_end/test_create_new_template.py @@ -151,6 +151,9 @@ def create_new_template(page): # Check to make sure that we've arrived at the next page. page.wait_for_load_state("domcontentloaded") + # We are not going to send the message for this test, we just want to confirm + # that the template has been created and we are now seeing the message from the + # template in the preview. assert "Test message for e2e test" in page.content() From f46f9661f1ef5e0f04ab4ef5cdf0f6e11dc819f6 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Mon, 8 Apr 2024 11:32:09 -0400 Subject: [PATCH 42/71] 1269 - Content updates for Service Settings after login.gov integration --- app/main/views/service_settings.py | 1 + app/templates/views/service-settings/set-auth-type.html | 7 ++++++- poetry.lock | 7 ++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index 628ac59e58..7d301426fc 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -650,6 +650,7 @@ def service_set_channel(service_id, channel): def service_set_auth_type(service_id): return render_template( "views/service-settings/set-auth-type.html", + login_gov_enabled=False, ) diff --git a/app/templates/views/service-settings/set-auth-type.html b/app/templates/views/service-settings/set-auth-type.html index 2637402222..2fa545a4c5 100644 --- a/app/templates/views/service-settings/set-auth-type.html +++ b/app/templates/views/service-settings/set-auth-type.html @@ -16,7 +16,12 @@
{{ page_header('Sign-in method') }} - {% if 'email_auth' in current_service.permissions %} + + {% if login_gov_enabled %} +

Your username, password, and multi-factor authentication options are handled by Login.gov.

+

To make changes, head to Login.gov and sign-in with your credentials.

+

Any changes made to your Login.gov account will automatically be synced with Notify.gov.

+ {% elif 'email_auth' in current_service.permissions and not login_gov_enabled %}

Email link or text message code

diff --git a/poetry.lock b/poetry.lock index 930c202327..2a90e81132 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1210,6 +1210,7 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li optional = false python-versions = ">=3.6" files = [ + {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"}, {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"}, {file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"}, {file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"}, @@ -1219,6 +1220,7 @@ files = [ {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"}, {file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"}, {file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"}, {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"}, {file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"}, {file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"}, @@ -1228,6 +1230,7 @@ files = [ {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"}, {file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"}, {file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"}, {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"}, {file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"}, {file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"}, @@ -1253,8 +1256,8 @@ files = [ {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"}, {file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"}, {file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"}, {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"}, - {file = "lxml-5.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cfbac9f6149174f76df7e08c2e28b19d74aed90cad60383ad8671d3af7d0502f"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"}, @@ -1262,6 +1265,7 @@ files = [ {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"}, {file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"}, {file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"}, {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"}, {file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"}, {file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"}, @@ -2378,6 +2382,7 @@ 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"}, From 6a29d2c81459655133f67ec686b8ffe560e9b73b Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 9 Apr 2024 09:07:19 -0700 Subject: [PATCH 43/71] code review feedback --- tests/end_to_end/test_create_new_template.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/end_to_end/test_create_new_template.py b/tests/end_to_end/test_create_new_template.py index 936ce3a2f9..6d344a94fa 100644 --- a/tests/end_to_end/test_create_new_template.py +++ b/tests/end_to_end/test_create_new_template.py @@ -8,12 +8,12 @@ E2E_TEST_URI = os.getenv("NOTIFY_E2E_TEST_URI") -def _setup(page, end_to_end_context): +def _setup(page): # Prepare for adding a new service later in the test. current_date_time = datetime.datetime.now() new_service_name = "E2E Federal Test Service {now} - {browser_type}".format( now=current_date_time.strftime("%m/%d/%Y %H:%M:%S"), - browser_type=end_to_end_context.browser.browser_type.name, + browser_type=page.context.browser.browser_type.name, ) page.goto(f"{E2E_TEST_URI}/accounts") @@ -157,10 +157,10 @@ def create_new_template(page): assert "Test message for e2e test" in page.content() -def test_create_new_template(authenticated_page, end_to_end_context): +def test_create_new_template(authenticated_page): page = authenticated_page - _setup(page, end_to_end_context) + _setup(page) create_new_template(page) From 931d5f4fed96bd112b5cbb692b8c21ee8d3ce24f Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 9 Apr 2024 09:10:02 -0700 Subject: [PATCH 44/71] remove end-to-end context --- .../test_send_message_from_existing_template.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/end_to_end/test_send_message_from_existing_template.py b/tests/end_to_end/test_send_message_from_existing_template.py index d09ecf73fa..535ad6c5f3 100644 --- a/tests/end_to_end/test_send_message_from_existing_template.py +++ b/tests/end_to_end/test_send_message_from_existing_template.py @@ -8,12 +8,12 @@ E2E_TEST_URI = os.getenv("NOTIFY_E2E_TEST_URI") -def _setup(page, end_to_end_context): +def _setup(page): # Prepare for adding a new service later in the test. current_date_time = datetime.datetime.now() new_service_name = "E2E Federal Test Service {now} - {browser_type}".format( now=current_date_time.strftime("%m/%d/%Y %H:%M:%S"), - browser_type=end_to_end_context.browser.browser_type.name, + browser_type=page.context.browser.browser_type.name, ) page.goto(f"{E2E_TEST_URI}/accounts") @@ -305,10 +305,10 @@ def handle_existing_template_case(page): # os.remove("download_test_file") -def test_send_message_from_existing_template(authenticated_page, end_to_end_context): +def test_send_message_from_existing_template(authenticated_page): page = authenticated_page - _setup(page, end_to_end_context) + _setup(page) if page.get_by_text("Create your first template").count() > 0: handle_no_existing_template_case(page) From f28bbd77a4c50197ffd5aa1da0d9f31440b6ecaf Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 9 Apr 2024 10:41:54 -0700 Subject: [PATCH 45/71] code review feedback --- tests/end_to_end/test_create_new_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end_to_end/test_create_new_template.py b/tests/end_to_end/test_create_new_template.py index 6d344a94fa..293931785e 100644 --- a/tests/end_to_end/test_create_new_template.py +++ b/tests/end_to_end/test_create_new_template.py @@ -88,7 +88,7 @@ def create_new_template(page): page.wait_for_load_state("domcontentloaded") send_messages_button = page.get_by_role("link", name="Send messages") - # expect(send_messages_button).to_be_visible() + expect(send_messages_button).to_be_visible() send_messages_button.click() # Check to make sure that we've arrived at the next page. From 63bc85d8d4c477e4e49c5e546e56067a159c49d0 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 9 Apr 2024 12:52:45 -0700 Subject: [PATCH 46/71] added format_datetime_scheduled_notification to formatters and removed unneccesary format changes --- app/__init__.py | 2 ++ app/formatters.py | 24 ++++++++++++++++--- app/main/views/send.py | 8 +++++-- app/templates/views/check/preview.html | 2 +- .../views/notifications/preview.html | 2 +- app/utils/templates.py | 2 +- app/utils/time.py | 5 ---- tests/app/main/views/test_send.py | 6 ++--- 8 files changed, 35 insertions(+), 16 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 5292c767bf..d2c61d0a06 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -52,6 +52,7 @@ format_datetime_human, format_datetime_normal, format_datetime_relative, + format_datetime_scheduled_notification, format_datetime_table, format_day_of_week, format_delta, @@ -551,6 +552,7 @@ def add_template_filters(application): format_datetime, format_datetime_24h, format_datetime_normal, + format_datetime_scheduled_notification, format_datetime_table, valid_phone_number, linkable_name, diff --git a/app/formatters.py b/app/formatters.py index 2bb8854f37..397cbbc108 100644 --- a/app/formatters.py +++ b/app/formatters.py @@ -22,7 +22,7 @@ from notifications_utils.take import Take from app.utils.csv import get_user_preferred_timezone -from app.utils.time import parse_dt, parse_naive_dt +from app.utils.time import parse_naive_dt def apply_html_class(tags, html_file): @@ -93,16 +93,34 @@ def format_datetime_normal(date): ) +def format_datetime_scheduled_notification(date): + # e.g. April 09, 2024 at 04:00 PM US/Eastern. + # Everything except scheduled notifications, the time is always "now". + # Scheduled notifications are the exception to the rule. + # Here we are formating and displaying the datetime without converting datetime to a different timezone. + + datetime_obj = parse_naive_dt(date) + + format_time_without_tz = datetime_obj.replace(tzinfo=timezone.utc).strftime( + "%I:%M %p" + ) + return "{} at {} {}".format( + format_date_normal(date), format_time_without_tz, get_user_preferred_timezone() + ) + + def format_datetime_table(date): # example: 03-18-2024 at 04:53 PM, intended for datetimes in tables return "{} at {}".format(format_date_numeric(date), format_time_12h(date)) def format_time_12h(date): - date = parse_dt(date) + date = parse_naive_dt(date) preferred_tz = pytz.timezone(get_user_preferred_timezone()) - return date.astimezone(preferred_tz).strftime("%I:%M %p") + return ( + date.replace(tzinfo=timezone.utc).astimezone(preferred_tz).strftime("%I:%M %p") + ) def format_datetime_relative(date): diff --git a/app/main/views/send.py b/app/main/views/send.py index 78395d2435..02f7d21211 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -650,7 +650,9 @@ def check_messages(service_id, template_id, upload_id, row_index=2): @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", "") - data = _check_messages(service_id, template_id, upload_id, row_index, force_hide_sender=True) + data = _check_messages( + service_id, template_id, upload_id, row_index, force_hide_sender=True + ) return render_template( "views/check/preview.html", @@ -911,7 +913,9 @@ def preview_notification(service_id, template_id): return render_template( "views/notifications/preview.html", - **_check_notification(service_id, template_id, show_recipient=False, force_hide_sender=True), + **_check_notification( + service_id, template_id, show_recipient=False, force_hide_sender=True + ), scheduled_for=session["scheduled_for"], recipient=recipient, ) diff --git a/app/templates/views/check/preview.html b/app/templates/views/check/preview.html index b0f58157db..32b158013f 100644 --- a/app/templates/views/check/preview.html +++ b/app/templates/views/check/preview.html @@ -21,7 +21,7 @@ {{ page_header('Preview') }}
-

Scheduled: {{ scheduled_for |format_datetime_normal if scheduled_for else 'Now'}}

+

Scheduled: {{ scheduled_for |format_datetime_scheduled_notification if scheduled_for else 'Now'}}

File: {{original_file_name}}

Template: {{template.name}}

From: {{ template.sender }}

diff --git a/app/templates/views/notifications/preview.html b/app/templates/views/notifications/preview.html index c1fec9e206..ce94a606f3 100644 --- a/app/templates/views/notifications/preview.html +++ b/app/templates/views/notifications/preview.html @@ -43,7 +43,7 @@ {{ page_header('Preview') }} {% endif %}
-

Scheduled: {{ scheduled_for |format_datetime_normal if scheduled_for else 'Now'}}

+

Scheduled: {{ scheduled_for |format_datetime_scheduled_notification if scheduled_for else 'Now'}}

Template: {{template.name}}

From: {{ template.sender }}

To: {{ recipient }}

diff --git a/app/utils/templates.py b/app/utils/templates.py index 355f658c0a..f610398b7d 100644 --- a/app/utils/templates.py +++ b/app/utils/templates.py @@ -17,7 +17,7 @@ def get_template( redact_missing_personalisation=False, email_reply_to=None, sms_sender=None, - force_hide_sender=False + force_hide_sender=False, ): if "email" == template["template_type"]: return EmailPreviewTemplate( diff --git a/app/utils/time.py b/app/utils/time.py index 05f190f15b..9ae24b1bd7 100644 --- a/app/utils/time.py +++ b/app/utils/time.py @@ -22,8 +22,3 @@ def is_less_than_days_ago(date_from_db, number_of_days): def parse_naive_dt(dt): return parser.parse(dt, ignoretz=True) - - -def parse_dt(dt): - # Parse datetime without ignoring the timezone - return parser.parse(dt) diff --git a/tests/app/main/views/test_send.py b/tests/app/main/views/test_send.py index e157728334..ab35dd29be 100644 --- a/tests/app/main/views/test_send.py +++ b/tests/app/main/views/test_send.py @@ -979,7 +979,7 @@ def test_upload_valid_csv_shows_preview_and_table( '
A
', ( ' ' - '
' + "
" "
    " "
  • foo
  • foo
  • foo
  • " "
" @@ -992,7 +992,7 @@ def test_upload_valid_csv_shows_preview_and_table( '
B
', ( ' ' - '
' + "
" "
    " "
  • foo
  • foo
  • foo
  • " "
" @@ -1005,7 +1005,7 @@ def test_upload_valid_csv_shows_preview_and_table( '
C
', ( ' ' - '
' + "
" "
    " "
  • foo
  • foo
  • " "
" From 4a61575859e3abe9fa04cad30eb1c307f383ad40 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 9 Apr 2024 15:28:36 -0700 Subject: [PATCH 47/71] moved settings_nav to /new/components --- .../new/components/settings_navigation.html | 16 ++++++++++++++++ app/templates/new/layouts/withnav_template.html | 4 ++-- app/templates/new/templates_glossary.md | 8 ++++---- 3 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 app/templates/new/components/settings_navigation.html diff --git a/app/templates/new/components/settings_navigation.html b/app/templates/new/components/settings_navigation.html new file mode 100644 index 0000000000..d94c417e70 --- /dev/null +++ b/app/templates/new/components/settings_navigation.html @@ -0,0 +1,16 @@ +{% if help %} +{% include 'partials/tour.html' %} +{% else %} + +{% endif %} diff --git a/app/templates/new/layouts/withnav_template.html b/app/templates/new/layouts/withnav_template.html index 412a004d0c..73965df183 100644 --- a/app/templates/new/layouts/withnav_template.html +++ b/app/templates/new/layouts/withnav_template.html @@ -9,7 +9,7 @@ {% block serviceNavigation %} {% include "service_navigation.html" %} {% endblock %} - +
{% if help %}
@@ -18,7 +18,7 @@ {% endif %} {% block sideNavigation %} {% include "main_nav.html" %} - + {% endblock %}
{% if help %} diff --git a/app/templates/new/templates_glossary.md b/app/templates/new/templates_glossary.md index 04f2c41516..9cad3d101a 100644 --- a/app/templates/new/templates_glossary.md +++ b/app/templates/new/templates_glossary.md @@ -30,9 +30,9 @@ This document serves as a glossary for the templates directory structure of the - withoutnav_template.html Delete - main_template.html Delete - settings_templates.html `withnav_template` can be used to replace `settings_template`. -- settings_nav.html (move to /new/navigation directory) -- main_nav.html (move to /new/navigation directory) -- service_navigation.html (move to /new/navigation directory) +- settings_nav.html (move to /components/ directory) +- main_nav.html (move to /components/ directory) +- service_navigation.html (move to /components/ directory) - org_template, could be under it's own directory called /layout/organization -- org_nav.html (move to /new/navigation directory) +- org_nav.html (move to /components/ directory) - content_template.html Delete From 35f836e5d6f7bc0e8850d4a116b0a3a6b493ba5e Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 9 Apr 2024 15:57:15 -0700 Subject: [PATCH 48/71] service_navigation.html moved to components --- .../new/components/service_navigation.html | 19 +++++++++++++++++++ .../new/layouts/withnav_template.html | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 app/templates/new/components/service_navigation.html diff --git a/app/templates/new/components/service_navigation.html b/app/templates/new/components/service_navigation.html new file mode 100644 index 0000000000..4cd23f252f --- /dev/null +++ b/app/templates/new/components/service_navigation.html @@ -0,0 +1,19 @@ +{% macro navigation_service_name(service) %} +
+ {{ service.name }} + {% if not service.active %} + Suspended + {% endif %} +
+{% endmacro %} + + diff --git a/app/templates/new/layouts/withnav_template.html b/app/templates/new/layouts/withnav_template.html index 412a004d0c..7846513a99 100644 --- a/app/templates/new/layouts/withnav_template.html +++ b/app/templates/new/layouts/withnav_template.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends "/new/base.html" %} {% block per_page_title %} {% block service_page_title %}{% endblock %} – {{ current_service.name }} @@ -7,7 +7,7 @@ {% block main %}
{% block serviceNavigation %} - {% include "service_navigation.html" %} + {% include "new/components/service_navigation.html" %} {% endblock %}
From d250542b7f8cdf00c68d8cafcc9f7e1562cc02d6 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 9 Apr 2024 16:07:56 -0700 Subject: [PATCH 49/71] converted and moved service_navigation.html to /components --- .../new/components/service_navigation.html | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/app/templates/new/components/service_navigation.html b/app/templates/new/components/service_navigation.html index 4cd23f252f..e3826d2794 100644 --- a/app/templates/new/components/service_navigation.html +++ b/app/templates/new/components/service_navigation.html @@ -1,12 +1,3 @@ -{% macro navigation_service_name(service) %} -
- {{ service.name }} - {% if not service.active %} - Suspended - {% endif %} -
-{% endmacro %} - From 8915bf16eddc1f8b43355de1ef43a3f122b75b61 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 9 Apr 2024 16:28:05 -0700 Subject: [PATCH 50/71] moved main_nav to components --- app/templates/new/components/main_nav.html | 30 ++++++++++++++++++++++ app/templates/withnav_template.html | 4 +-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 app/templates/new/components/main_nav.html diff --git a/app/templates/new/components/main_nav.html b/app/templates/new/components/main_nav.html new file mode 100644 index 0000000000..a3b02823e6 --- /dev/null +++ b/app/templates/new/components/main_nav.html @@ -0,0 +1,30 @@ +{% if help %} + {% include 'partials/tour.html' %} +{% else %} + +{% endif %} diff --git a/app/templates/withnav_template.html b/app/templates/withnav_template.html index 40d2e10f16..407b69f21b 100644 --- a/app/templates/withnav_template.html +++ b/app/templates/withnav_template.html @@ -1,4 +1,4 @@ -{% extends "admin_template.html" %} +{% extends "/new/base.html" %} {% block per_page_title %} {% block service_page_title %}{% endblock %} – {{ current_service.name }} @@ -6,7 +6,7 @@ {% block main %}
- {% include "service_navigation.html" %} + {% include "new/components/service_navigation.html" %}
{% if help %}
From beedce179673aae22904fbb32ec54fca08e530c4 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 9 Apr 2024 16:31:53 -0700 Subject: [PATCH 51/71] moved main_nav to components --- app/templates/new/layouts/withnav_template.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/new/layouts/withnav_template.html b/app/templates/new/layouts/withnav_template.html index 412a004d0c..d5fa1acd96 100644 --- a/app/templates/new/layouts/withnav_template.html +++ b/app/templates/new/layouts/withnav_template.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends "/new/base.html" %} {% block per_page_title %} {% block service_page_title %}{% endblock %} – {{ current_service.name }} @@ -17,7 +17,7 @@
{% endif %} {% block sideNavigation %} - {% include "main_nav.html" %} + {% include "/new/components/main_nav.html" %} {% endblock %}
From 7f3728e0d5f2702658c2421422c6c1f48881f6fa Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 9 Apr 2024 16:32:56 -0700 Subject: [PATCH 52/71] moved main_nav to components --- app/templates/withnav_template.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/withnav_template.html b/app/templates/withnav_template.html index 407b69f21b..40d2e10f16 100644 --- a/app/templates/withnav_template.html +++ b/app/templates/withnav_template.html @@ -1,4 +1,4 @@ -{% extends "/new/base.html" %} +{% extends "admin_template.html" %} {% block per_page_title %} {% block service_page_title %}{% endblock %} – {{ current_service.name }} @@ -6,7 +6,7 @@ {% block main %}
- {% include "new/components/service_navigation.html" %} + {% include "service_navigation.html" %}
{% if help %}
From 7fe90a14aa13d9d0e51c8199df1451bc67abe627 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 9 Apr 2024 16:40:20 -0700 Subject: [PATCH 53/71] org_nav --- app/templates/new/components/org_nav.html | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 app/templates/new/components/org_nav.html diff --git a/app/templates/new/components/org_nav.html b/app/templates/new/components/org_nav.html new file mode 100644 index 0000000000..f7f7a5b93a --- /dev/null +++ b/app/templates/new/components/org_nav.html @@ -0,0 +1,11 @@ + From 5626267c94d49c5f69daa238d7bfe62759d71df6 Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Tue, 9 Apr 2024 16:43:01 -0700 Subject: [PATCH 54/71] org_nav --- app/templates/new/layouts/org_template.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/new/layouts/org_template.html b/app/templates/new/layouts/org_template.html index 5e04003fd4..69f49b76ab 100644 --- a/app/templates/new/layouts/org_template.html +++ b/app/templates/new/layouts/org_template.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends "/new/base.html" %} {% block per_page_title %} {% block org_page_title %}{% endblock %} – {{ current_org.name }} @@ -17,7 +17,7 @@
- {% include "org_nav.html" %} + {% include "/new/components/org_nav.html" %}
{% block beforeContent %} From 96ec868e3e0d18fd245d7a35777ed1845a9d8183 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 10 Apr 2024 07:45:10 -0700 Subject: [PATCH 55/71] fix service stats --- app/main/views/platform_admin.py | 14 ++++++++++++++ poetry.lock | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/main/views/platform_admin.py b/app/main/views/platform_admin.py index 802ed5b185..6190ac988a 100644 --- a/app/main/views/platform_admin.py +++ b/app/main/views/platform_admin.py @@ -662,7 +662,21 @@ def create_global_stats(services): "email": {"delivered": 0, "failed": 0, "requested": 0}, "sms": {"delivered": 0, "failed": 0, "requested": 0}, } + # Issue #1323. The back end is now sending 'failure' instead of + # 'failed'. Adjust it here, but keep it flexible in case + # the backend reverts to 'failed'. for service in services: + if service["statistics"]["sms"].get("failure") is not None: + service["statistics"]["sms"]["failed"] = service["statistics"]["sms"][ + "failure" + ] + if service["statistics"]["email"].get("failure") is not None: + service["statistics"]["email"]["failed"] = service["statistics"]["email"][ + "failure" + ] + + for service in services: + for msg_type, status in itertools.product( ("sms", "email"), ("delivered", "failed", "requested") ): diff --git a/poetry.lock b/poetry.lock index 96e56ec547..ad8764cfca 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1210,6 +1210,7 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li optional = false python-versions = ">=3.6" files = [ + {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"}, {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"}, {file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"}, {file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"}, @@ -1219,6 +1220,7 @@ files = [ {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"}, {file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"}, {file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"}, {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"}, {file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"}, {file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"}, @@ -1228,6 +1230,7 @@ files = [ {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"}, {file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"}, {file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"}, {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"}, {file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"}, {file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"}, @@ -1253,8 +1256,8 @@ files = [ {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"}, {file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"}, {file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"}, {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"}, - {file = "lxml-5.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cfbac9f6149174f76df7e08c2e28b19d74aed90cad60383ad8671d3af7d0502f"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"}, @@ -1262,6 +1265,7 @@ files = [ {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"}, {file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"}, {file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"}, {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"}, {file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"}, {file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"}, @@ -1512,6 +1516,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"}, ] From 460399dd68ad94d89259c8001c02e8ace27ac19c Mon Sep 17 00:00:00 2001 From: Beverly Nguyen Date: Wed, 10 Apr 2024 10:41:35 -0700 Subject: [PATCH 56/71] revised notes --- app/templates/new/templates_glossary.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/templates/new/templates_glossary.md b/app/templates/new/templates_glossary.md index 9cad3d101a..1c52e75dcc 100644 --- a/app/templates/new/templates_glossary.md +++ b/app/templates/new/templates_glossary.md @@ -14,6 +14,10 @@ This document serves as a glossary for the templates directory structure of the - `head.html`: Template for the site's , included in `base.html`. - `header.html`: Template for the site's header, included in `base.html`. - `footer.html`: Template for the site's footer, included in `base.html`. + - `settings_navigation.html`: The settings navigation used in `withnav_template.html` that previously extended `settings_template.html`. + - `org_nav.html`: The organization's navigation used solely in `org_template.html`. + - `main_nav.html`: The main navigation used in `withnav_template.html` + - `service_navigation.html`: The service navigation used in `withnav_template.html`. In withnav_template.html, the `serviceNavigation` block will be left empty in any child templates that previously extended `settings_template.html`. - **/views** (or **/pages**): Individual page templates that use the base layouts, components, and partials to present content. ### Best Practices From 5538b802ee2be813cffa9f8d52396f48c5f05b3f Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Wed, 10 Apr 2024 13:17:00 -0700 Subject: [PATCH 57/71] Exception Investigation: builtins:KeyError --- app/main/views/sign_in.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py index 402e61a080..6de46b0233 100644 --- a/app/main/views/sign_in.py +++ b/app/main/views/sign_in.py @@ -63,6 +63,10 @@ def _get_access_token(code, state): url = f"{base_url}{cli_assert}&{cli_assert_type}&{code_param}&grant_type=authorization_code" headers = {"Authorization": "Bearer %s" % token} response = requests.post(url, headers=headers) + if response.json().get("access_token") is None: + # Capture the response json here so it hopefully shows up in error reports + current_app.logger.error(f"Error when getting access token {response.json()}") + raise KeyError(f"'access_token' {response.json()}") access_token = response.json()["access_token"] return access_token @@ -84,13 +88,17 @@ def _do_login_dot_gov(): code = request.args.get("code") state = request.args.get("state") login_gov_error = request.args.get("error") - if code and state: - access_token = _get_access_token(code, state) - user_email, user_uuid = _get_user_email_and_uuid(access_token) - redirect_url = request.args.get("next") + + if login_gov_error: + current_app.logger.error(f"login.gov error: {login_gov_error}") + raise Exception(f"Could not login with login.gov {login_gov_error}") + elif code and state: # activate the user try: + access_token = _get_access_token(code, state) + user_email, user_uuid = _get_user_email_and_uuid(access_token) + redirect_url = request.args.get("next") user = user_api_client.get_user_by_uuid_or_email(user_uuid, user_email) activate_user(user["id"]) except BaseException as be: # noqa B036 @@ -99,9 +107,6 @@ def _do_login_dot_gov(): return redirect(url_for("main.show_accounts_or_dashboard", next=redirect_url)) - elif login_gov_error: - current_app.logger.error(f"login.gov error: {login_gov_error}") - raise Exception(f"Could not login with login.gov {login_gov_error}") # end login.gov From 5fd1a8c8360b15ebfe76d336a7bd2b94c3d09105 Mon Sep 17 00:00:00 2001 From: Carlo Costino Date: Thu, 11 Apr 2024 18:02:56 -0400 Subject: [PATCH 58/71] Update utils to 0.4.6 This changeset updates notifications-utils to 0.4.6 in order to address some dependency updates and incorporate a few minor changes. Signed-off-by: Carlo Costino --- poetry.lock | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/poetry.lock b/poetry.lock index ad8764cfca..984a910f7f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -171,17 +171,17 @@ files = [ [[package]] name = "boto3" -version = "1.34.79" +version = "1.34.83" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.79-py3-none-any.whl", hash = "sha256:265b0b4865e8c07e27abb32a31d2bd9129bb009b1d89ca0783776ec084886123"}, - {file = "boto3-1.34.79.tar.gz", hash = "sha256:139dd2d94eaa0e3213ff37ba7cf4cb2e3823269178fe8f3e33c965f680a9ddde"}, + {file = "boto3-1.34.83-py3-none-any.whl", hash = "sha256:33cf93f6de5176f1188c923f4de1ae149ed723b89ed12e434f2b2f628491769e"}, + {file = "boto3-1.34.83.tar.gz", hash = "sha256:9733ce811bd82feab506ad9309e375a79cabe8c6149061971c17754ce8997551"}, ] [package.dependencies] -botocore = ">=1.34.79,<1.35.0" +botocore = ">=1.34.83,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -190,13 +190,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.79" +version = "1.34.83" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.79-py3-none-any.whl", hash = "sha256:a42a014d3dbaa9ef123810592af69f9e55b456c5be3ac9efc037325685519e83"}, - {file = "botocore-1.34.79.tar.gz", hash = "sha256:6b59b0f7de219d383a2a633f6718c2600642ebcb707749dc6c67a6a436474b7a"}, + {file = "botocore-1.34.83-py3-none-any.whl", hash = "sha256:0a3fbbe018416aeefa8978454fb0b8129adbaf556647b72269bf02e4bf1f4161"}, + {file = "botocore-1.34.83.tar.gz", hash = "sha256:0f302aa76283d4df62b4fbb6d3d20115c1a8957fc02171257fc93904d69d5636"}, ] [package.dependencies] @@ -1080,13 +1080,13 @@ license = ["ukkonen"] [[package]] name = "idna" -version = "3.6" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] @@ -1210,7 +1210,6 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li optional = false python-versions = ">=3.6" files = [ - {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"}, {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"}, {file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"}, {file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"}, @@ -1220,7 +1219,6 @@ files = [ {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"}, {file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"}, {file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"}, - {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"}, {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"}, {file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"}, {file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"}, @@ -1230,7 +1228,6 @@ files = [ {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"}, {file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"}, {file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"}, - {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"}, {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"}, {file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"}, {file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"}, @@ -1256,8 +1253,8 @@ files = [ {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"}, {file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"}, {file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"}, - {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"}, {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cfbac9f6149174f76df7e08c2e28b19d74aed90cad60383ad8671d3af7d0502f"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"}, @@ -1265,7 +1262,6 @@ files = [ {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"}, {file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"}, {file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"}, - {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"}, {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"}, {file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"}, {file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"}, @@ -1516,7 +1512,6 @@ 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"}, ] @@ -1603,7 +1598,7 @@ requests = ">=2.0.0" [[package]] name = "notifications-utils" -version = "0.4.5" +version = "0.4.6" description = "" optional = false python-versions = "^3.12.2" @@ -1614,8 +1609,8 @@ develop = false async-timeout = "^4.0.2" bleach = "^6.1.0" blinker = "^1.6.2" -boto3 = "^1.34.77" -botocore = "^1.34.79" +boto3 = "^1.34.83" +botocore = "^1.34.83" cachetools = "^5.3.0" certifi = "^2024.2.2" cffi = "^1.16.0" @@ -1626,7 +1621,7 @@ flask = "^2.3.2" flask-redis = "^0.4.0" geojson = "^3.0.1" govuk-bank-holidays = "^0.14" -idna = "^3.6" +idna = "^3.7" itsdangerous = "^2.1.2" jinja2 = "^3.1.3" jmespath = "^1.0.1" @@ -1655,7 +1650,7 @@ werkzeug = "^3.0.1" type = "git" url = "https://github.com/GSA/notifications-utils.git" reference = "HEAD" -resolved_reference = "7d1d2e9bb3791316231e97433c71da6a70c4d2ab" +resolved_reference = "d0db6073406bd160d2007edb9d00e41c9d5d44b7" [[package]] name = "numpy" From ae5561862d80988e051d37dc043cfe984d922cea Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Thu, 11 Apr 2024 15:39:50 -0700 Subject: [PATCH 59/71] fix tests, eliminate or tweak bogus incoming or foreign number tests --- poetry.lock | 7 ++++++- tests/app/main/forms/test_placeholder_form.py | 1 - tests/app/main/views/test_dashboard.py | 7 +++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 984a910f7f..21064bf51d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1210,6 +1210,7 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li optional = false python-versions = ">=3.6" files = [ + {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"}, {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"}, {file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"}, {file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"}, @@ -1219,6 +1220,7 @@ files = [ {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"}, {file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"}, {file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"}, {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"}, {file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"}, {file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"}, @@ -1228,6 +1230,7 @@ files = [ {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"}, {file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"}, {file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"}, {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"}, {file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"}, {file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"}, @@ -1253,8 +1256,8 @@ files = [ {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"}, {file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"}, {file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"}, {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"}, - {file = "lxml-5.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cfbac9f6149174f76df7e08c2e28b19d74aed90cad60383ad8671d3af7d0502f"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"}, @@ -1262,6 +1265,7 @@ files = [ {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"}, {file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"}, {file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"}, {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"}, {file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"}, {file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"}, @@ -1512,6 +1516,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"}, ] diff --git a/tests/app/main/forms/test_placeholder_form.py b/tests/app/main/forms/test_placeholder_form.py index 40a12ae569..01075472f6 100644 --- a/tests/app/main/forms/test_placeholder_form.py +++ b/tests/app/main/forms/test_placeholder_form.py @@ -48,7 +48,6 @@ def test_form_class_not_mutated(notify_admin): (False, "phone number", "sms", "2028675309", None), (False, "phone number", "sms", "+1 (202) 867-5309", None), (True, "phone number", "sms", "+123", "Not enough digits"), - (True, "phone number", "sms", "+44(0)7900 900-123", None), (True, "phone number", "sms", "+1-2345-678890", None), (False, "anything else", "sms", "", "Cannot be empty"), (False, "anything else", "email", "", "Cannot be empty"), diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index 4c86fb3282..c4326ef894 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -354,10 +354,9 @@ def test_inbound_messages_shows_count_of_messages_when_there_are_no_messages( "(202) 867-5300 message-2 1 hour ago", "(202) 867-5300 message-3 1 hour ago", "(202) 867-5302 message-4 3 hours ago", - "+33 1 12 34 56 78 message-5 5 hours ago", + "+33(0)1 12345678 message-5 5 hours ago", "(202) 555-0104 message-6 7 hours ago", "(202) 555-0104 message-7 9 hours ago", - "+682 12345 message-8 9 hours ago", ] ), ) @@ -519,10 +518,10 @@ def test_download_inbox( "(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 1 12 34 56 78,message-5,07-01-2016 06: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" - "+682 12345,message-8,07-01-2016 02:59 US/Eastern\r\n" + "+68212345,message-8,07-01-2016 02:59 US/Eastern\r\n" ) From 6784cf9f3cd7b96b8073c20e892cb68f05eca7f0 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Mon, 15 Apr 2024 15:50:42 -0400 Subject: [PATCH 60/71] 1423 - Few final updates to switch over to login.gov --- app/main/views/sign_in.py | 1 - app/templates/views/signin.html | 33 ++++------------------ poetry.lock | 2 +- tests/app/main/views/test_accept_invite.py | 9 ++---- tests/app/main/views/test_sign_in.py | 31 ++++---------------- 5 files changed, 15 insertions(+), 61 deletions(-) diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py index 6de46b0233..f5870c2e17 100644 --- a/app/main/views/sign_in.py +++ b/app/main/views/sign_in.py @@ -197,7 +197,6 @@ def sign_in(): form=form, again=bool(redirect_url), other_device=other_device, - login_gov_enabled=True, password_reset_url=password_reset_url, initial_signin_url=url, ) diff --git a/app/templates/views/signin.html b/app/templates/views/signin.html index 6d6f578ee2..5532eb7c13 100644 --- a/app/templates/views/signin.html +++ b/app/templates/views/signin.html @@ -12,18 +12,6 @@ {% block maincolumn_content %} -{% if login_gov_enabled %} -
-
-
-

Login.gov is required by April 16, 2024

-

- You have left to use Login.gov to sign in -

-
-
-
-{% endif %}
{% if again %} @@ -39,22 +27,12 @@

You need to sign in again

{% endif %} {% else %}

Sign in

- {% if login_gov_enabled %} -

You can access your account by signing in with one of the options below:

- Sign in with Login.gov -

Or:

- {% endif %} +

Access your Notify.gov account by signing in with Login.gov:

+ Sign in with Login.gov {% endif %} - - {% call form_wrapper(autocomplete=True) %} - {{ form.email_address(param_extensions={"autocomplete": "email"}) }} - {{ form.password(param_extensions={"autocomplete": "current-password"}) }} - {{ page_footer("Continue", secondary_link=password_reset_url, secondary_link_text="Forgot your password?") }} - {% endcall %}
- {% if login_gov_enabled %}
-

Notify.gov is changing the sign-in experience to Login.gov effective
April 16, 2024

+

Effective April 16, 2024 Notify.gov requires you sign-in through Login.gov

Why are we doing this?

  • Enhanced security: Login.gov is really secure and trustworthy
  • @@ -64,12 +42,11 @@

    Notify.gov is changing the sign-in experience to Login.

    What do I need to do?

    • If you have a Login.gov account, start using it to sign in to Notify today.
    • -
    • If you don’t have a Login.gov account, you must create one by April 16, 2024 to continue to access Notify.
    • +
    • If you don’t have a Login.gov account, you must create one to continue to access Notify.
    - Create Login.gov account + Create Login.gov account

-{% endif %} {% endblock %} diff --git a/poetry.lock b/poetry.lock index 21064bf51d..e46765a4f3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1516,7 +1516,6 @@ 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"}, ] @@ -2383,6 +2382,7 @@ 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"}, diff --git a/tests/app/main/views/test_accept_invite.py b/tests/app/main/views/test_accept_invite.py index c677eeec2c..d1eadc28f0 100644 --- a/tests/app/main/views/test_accept_invite.py +++ b/tests/app/main/views/test_accept_invite.py @@ -222,8 +222,7 @@ def test_if_existing_user_accepts_twice_they_redirect_to_sign_in( ) == ( "You need to sign in again", # TODO: Improve this given Login.gov configuration. - # "We signed you out because you have not used Notify for a while.", - "You have left to use Login.gov to sign in", + "We signed you out because you have not used Notify for a while.", ) # We don’t let people update `email_access_validated_at` using an # already-accepted invite @@ -338,8 +337,7 @@ def test_existing_user_of_service_get_redirected_to_signin( ) == ( "You need to sign in again", # TODO: Improve this given Login.gov configuration. - # "We signed you out because you have not used Notify for a while.", - "You have left to use Login.gov to sign in", + "We signed you out because you have not used Notify for a while.", ) assert mock_accept_invite.call_count == 1 @@ -429,8 +427,7 @@ def test_existing_signed_out_user_accept_invite_redirects_to_sign_in( ) == ( "You need to sign in again", # TODO: Improve this given Login.gov configuration. - # "We signed you out because you have not used Notify for a while.", - "You have left to use Login.gov to sign in", + "We signed you out because you have not used Notify for a while.", ) diff --git a/tests/app/main/views/test_sign_in.py b/tests/app/main/views/test_sign_in.py index ddb7a8b080..e89cb6e7b1 100644 --- a/tests/app/main/views/test_sign_in.py +++ b/tests/app/main/views/test_sign_in.py @@ -12,40 +12,21 @@ def test_render_sign_in_template_for_new_user(client_request): client_request.logout() page = client_request.get("main.sign_in") assert normalize_spaces(page.select_one("h1").text) == "Sign in" - assert normalize_spaces(page.select("label")[0].text) == "Email address" - assert page.select_one("#email_address").get("value") is None - assert page.select_one("#email_address")["autocomplete"] == "email" - assert normalize_spaces(page.select("label")[1].text) == "Password" - assert page.select_one("#password").get("value") is None - assert page.select_one("#password")["autocomplete"] == "current-password" - # Removing for the pilot - # assert page.select('main a')[0].text == 'create one now' - # assert page.select('main a')[0]['href'] == url_for('main.register') + assert ( + page.select("main p")[0].text + == "Access your Notify.gov account by signing in with Login.gov:" + ) # TODO: Fix this test to be less brittle! If the Login.gov link is enabled, # then these indices need to be 1 instead of 0. # Currently it's not enabled for the test or production environments. - assert page.select("main a")[1].text == "Forgot your password?" - assert page.select("main a")[1]["href"] == url_for("main.forgot_password") + assert page.select("main a")[0].text == "Sign in with Login.gov" + assert page.select("main a")[1].text == "Create Login.gov account" # TODO: We'll have to adjust this depending on whether Login.gov is # enabled or not; fix this in the future. assert "Sign in again" not in normalize_spaces(page.text) -def test_render_sign_in_template_with_next_link_for_password_reset(client_request): - client_request.logout() - page = client_request.get( - "main.sign_in", - _optional_args=f"?next=/services/{SERVICE_ONE_ID}/templates", - _test_page_title=False, - ) - forgot_password_link = page.find("a", class_="usa-link") - assert forgot_password_link.text == "Forgot your password?" - assert forgot_password_link["href"] == url_for( - "main.forgot_password", next=f"/services/{SERVICE_ONE_ID}/templates" - ) - - def test_reformat_keystring(): orig = "-----BEGIN PRIVATE KEY----- blah blah blah -----END PRIVATE KEY-----" expected = """-----BEGIN PRIVATE KEY----- From b83019fdb722467d6f936f3ee1e9455b04c37565 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Tue, 16 Apr 2024 10:57:16 -0400 Subject: [PATCH 61/71] Fixing pa11y scan --- app/templates/error/500.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/error/500.html b/app/templates/error/500.html index af86388d7c..aca8332df9 100644 --- a/app/templates/error/500.html +++ b/app/templates/error/500.html @@ -7,7 +7,7 @@

Sorry, we can't deliver what you asked for right now.

- Please try again later or email us for more information.

+ Please try again later or email us for more information.

From 96293598f883cec509c6cc45612f673d465d6609 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Tue, 16 Apr 2024 10:57:47 -0400 Subject: [PATCH 62/71] Fixing pa11y scan --- app/templates/error/500.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/error/500.html b/app/templates/error/500.html index af86388d7c..aca8332df9 100644 --- a/app/templates/error/500.html +++ b/app/templates/error/500.html @@ -7,7 +7,7 @@

Sorry, we can't deliver what you asked for right now.

- Please try again later or email us for more information.

+ Please try again later or email us for more information.

From 0044beaeeda071d6e7c0b406ecb3230ade4e33cd Mon Sep 17 00:00:00 2001 From: Carlo Costino Date: Tue, 16 Apr 2024 11:46:57 -0400 Subject: [PATCH 63/71] Updated dependencies and ignore gunicorn audit flag This changeset updates a couple of dependencies, including our Python dependency audit check, and specifically ignores a gunicorn audit flag that appeared on 4/16/2024. As soon as there is an update available for gunicorn that addresses the issue we will remove the flag to ignore the vulnerability report and update the dependency. Signed-off-by: Carlo Costino --- .github/workflows/checks.yml | 4 ++- poetry.lock | 53 ++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index be0a6cc66d..ab67782721 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -157,9 +157,11 @@ jobs: - uses: ./.github/actions/setup-project - name: Create requirements.txt run: poetry export --without-hashes --format=requirements.txt > requirements.txt - - uses: pypa/gh-action-pip-audit@v1.0.6 + - uses: pypa/gh-action-pip-audit@v1.0.8 with: inputs: requirements.txt + ignore-vulns: | + GHSA-w3h3-4rj7-4ph4 - name: Run npm audit run: make npm-audit diff --git a/poetry.lock b/poetry.lock index 21064bf51d..13cfa6cfbd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -87,33 +87,33 @@ lxml = ["lxml"] [[package]] name = "black" -version = "24.3.0" +version = "24.4.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"}, - {file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"}, - {file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"}, - {file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"}, - {file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"}, - {file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"}, - {file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"}, - {file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"}, - {file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"}, - {file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"}, - {file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"}, - {file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"}, - {file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"}, - {file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"}, - {file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"}, - {file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"}, - {file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"}, - {file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"}, - {file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"}, - {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"}, - {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"}, - {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"}, + {file = "black-24.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6ad001a9ddd9b8dfd1b434d566be39b1cd502802c8d38bbb1ba612afda2ef436"}, + {file = "black-24.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3a3a092b8b756c643fe45f4624dbd5a389f770a4ac294cf4d0fce6af86addaf"}, + {file = "black-24.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dae79397f367ac8d7adb6c779813328f6d690943f64b32983e896bcccd18cbad"}, + {file = "black-24.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:71d998b73c957444fb7c52096c3843875f4b6b47a54972598741fe9a7f737fcb"}, + {file = "black-24.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e5537f456a22cf5cfcb2707803431d2feeb82ab3748ade280d6ccd0b40ed2e8"}, + {file = "black-24.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64e60a7edd71fd542a10a9643bf369bfd2644de95ec71e86790b063aa02ff745"}, + {file = "black-24.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cd5b4f76056cecce3e69b0d4c228326d2595f506797f40b9233424e2524c070"}, + {file = "black-24.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:64578cf99b6b46a6301bc28bdb89f9d6f9b592b1c5837818a177c98525dbe397"}, + {file = "black-24.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f95cece33329dc4aa3b0e1a771c41075812e46cf3d6e3f1dfe3d91ff09826ed2"}, + {file = "black-24.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4396ca365a4310beef84d446ca5016f671b10f07abdba3e4e4304218d2c71d33"}, + {file = "black-24.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44d99dfdf37a2a00a6f7a8dcbd19edf361d056ee51093b2445de7ca09adac965"}, + {file = "black-24.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:21f9407063ec71c5580b8ad975653c66508d6a9f57bd008bb8691d273705adcd"}, + {file = "black-24.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:652e55bb722ca026299eb74e53880ee2315b181dfdd44dca98e43448620ddec1"}, + {file = "black-24.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7f2966b9b2b3b7104fca9d75b2ee856fe3fdd7ed9e47c753a4bb1a675f2caab8"}, + {file = "black-24.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bb9ca06e556a09f7f7177bc7cb604e5ed2d2df1e9119e4f7d2f1f7071c32e5d"}, + {file = "black-24.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:d4e71cdebdc8efeb6deaf5f2deb28325f8614d48426bed118ecc2dcaefb9ebf3"}, + {file = "black-24.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6644f97a7ef6f401a150cca551a1ff97e03c25d8519ee0bbc9b0058772882665"}, + {file = "black-24.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:75a2d0b4f5eb81f7eebc31f788f9830a6ce10a68c91fbe0fade34fff7a2836e6"}, + {file = "black-24.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb949f56a63c5e134dfdca12091e98ffb5fd446293ebae123d10fc1abad00b9e"}, + {file = "black-24.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:7852b05d02b5b9a8c893ab95863ef8986e4dda29af80bbbda94d7aee1abf8702"}, + {file = "black-24.4.0-py3-none-any.whl", hash = "sha256:74eb9b5420e26b42c00a3ff470dc0cd144b80a766128b1771d07643165e08d0e"}, + {file = "black-24.4.0.tar.gz", hash = "sha256:f07b69fda20578367eaebbd670ff8fc653ab181e1ff95d84497f9fa20e7d0641"}, ] [package.dependencies] @@ -1210,7 +1210,6 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li optional = false python-versions = ">=3.6" files = [ - {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"}, {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"}, {file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"}, {file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"}, @@ -1220,7 +1219,6 @@ files = [ {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"}, {file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"}, {file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"}, - {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"}, {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"}, {file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"}, {file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"}, @@ -1230,7 +1228,6 @@ files = [ {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"}, {file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"}, {file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"}, - {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"}, {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"}, {file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"}, {file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"}, @@ -1256,8 +1253,8 @@ files = [ {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"}, {file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"}, {file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"}, - {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"}, {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cfbac9f6149174f76df7e08c2e28b19d74aed90cad60383ad8671d3af7d0502f"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"}, {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"}, @@ -1265,7 +1262,6 @@ files = [ {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"}, {file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"}, {file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"}, - {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"}, {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"}, {file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"}, {file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"}, @@ -1516,7 +1512,6 @@ 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"}, ] From f30899d762a369aac2b822e83e4eedf0365e16f7 Mon Sep 17 00:00:00 2001 From: Kenneth Kehl <@kkehl@flexion.us> Date: Tue, 16 Apr 2024 12:06:33 -0700 Subject: [PATCH 64/71] fix 90 day email validation --- app/main/views/sign_in.py | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/app/main/views/sign_in.py b/app/main/views/sign_in.py index 6de46b0233..88360dca39 100644 --- a/app/main/views/sign_in.py +++ b/app/main/views/sign_in.py @@ -6,6 +6,7 @@ import requests from flask import ( Markup, + Response, abort, current_app, flash, @@ -26,6 +27,7 @@ from app.models.user import InvitedUser, User from app.utils import hide_from_search_engines from app.utils.login import is_safe_redirect_url +from app.utils.time import is_less_than_days_ago def _reformat_keystring(orig): @@ -100,20 +102,47 @@ def _do_login_dot_gov(): user_email, user_uuid = _get_user_email_and_uuid(access_token) redirect_url = request.args.get("next") user = user_api_client.get_user_by_uuid_or_email(user_uuid, user_email) - activate_user(user["id"]) + + # Check if the email needs to be revalidated + is_fresh_email = is_less_than_days_ago( + user["email_access_validated_at"], 90 + ) + if not is_fresh_email: + return verify_email(user, redirect_url) + + usr = User.from_email_address(user["email_address"]) + activate_user(usr.id) except BaseException as be: # noqa B036 current_app.logger.error(be) error(401) - return redirect(url_for("main.show_accounts_or_dashboard", next=redirect_url)) # end login.gov +def verify_email(user, redirect_url): + user_api_client.send_verify_code(user["id"], "email", None, redirect_url) + title = "Email resent" if request.args.get("email_resent") else "Check your email" + redirect_url = request.args.get("next") + return render_template( + "views/re-validate-email-sent.html", title=title, redirect_url=redirect_url + ) + + @main.route("/sign-in", methods=(["GET", "POST"])) @hide_from_search_engines def sign_in(): - _do_login_dot_gov() + # If we have to revalidated the email, send the message + # via email and redirect to the "verify your email page" + # and don't proceed further with login + email_verify_template = _do_login_dot_gov() + if ( + email_verify_template + and not isinstance(email_verify_template, Response) + and "Check your email" in email_verify_template + ): + return email_verify_template + redirect_url = request.args.get("next") if os.getenv("NOTIFY_E2E_TEST_EMAIL"): From e14fc8b6542ca8f3a078a9bb415095ab4f107423 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Wed, 17 Apr 2024 11:03:45 -0400 Subject: [PATCH 65/71] Changed the flag to true --- app/main/views/service_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index 7d301426fc..a006845a84 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -650,7 +650,7 @@ def service_set_channel(service_id, channel): def service_set_auth_type(service_id): return render_template( "views/service-settings/set-auth-type.html", - login_gov_enabled=False, + login_gov_enabled=True, ) From 8596a9cdb33b59cada29f03c8170817ab36ef63d Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Wed, 17 Apr 2024 11:26:14 -0400 Subject: [PATCH 66/71] Removing the email and password fields in the settings area because login.gov will take care of this --- app/templates/views/user-profile.html | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/app/templates/views/user-profile.html b/app/templates/views/user-profile.html index d3e6ff7c8a..88f2f16682 100644 --- a/app/templates/views/user-profile.html +++ b/app/templates/views/user-profile.html @@ -27,21 +27,6 @@

User profile

}} {% endcall %} - {% call row() %} - {{ text_field('Email address') }} - {{ text_field(current_user.email_address) }} - {% if can_see_edit %} - {{ edit_field( - 'Change', - url_for('.user_profile_email'), - suffix='email address' - ) - }} - {% else %} - {{ text_field('') }} - {% endif %} - {% endcall %} - {% call row() %} {{ text_field('Mobile number') }} {{ optional_text_field(current_user.mobile_number) }} @@ -53,16 +38,6 @@

User profile

}} {% endcall %} - {% call row() %} - {{ text_field('Password') }} - {{ text_field('Last changed ' + current_user.password_changed_at|format_delta) }} - {{ edit_field( - 'Change', - url_for('.user_profile_password'), - suffix='password' - ) - }} - {% endcall %} {% call row() %} {{ text_field('Preferred Timezone') }} {{ optional_text_field(current_user.preferred_timezone) }} From 7755e02ad88a816a9cfbc03be1b24490ad5d7733 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Wed, 17 Apr 2024 11:49:47 -0400 Subject: [PATCH 67/71] Removing instances of the login_gov_enabled flag as it will be live with this push to production --- app/main/views/service_settings.py | 1 - .../views/service-settings/set-auth-type.html | 30 ++----------------- 2 files changed, 3 insertions(+), 28 deletions(-) diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py index a006845a84..628ac59e58 100644 --- a/app/main/views/service_settings.py +++ b/app/main/views/service_settings.py @@ -650,7 +650,6 @@ def service_set_channel(service_id, channel): def service_set_auth_type(service_id): return render_template( "views/service-settings/set-auth-type.html", - login_gov_enabled=True, ) diff --git a/app/templates/views/service-settings/set-auth-type.html b/app/templates/views/service-settings/set-auth-type.html index 2fa545a4c5..2fd5259f8b 100644 --- a/app/templates/views/service-settings/set-auth-type.html +++ b/app/templates/views/service-settings/set-auth-type.html @@ -16,33 +16,9 @@
{{ page_header('Sign-in method') }} - - {% if login_gov_enabled %} -

Your username, password, and multi-factor authentication options are handled by Login.gov.

-

To make changes, head to Login.gov and sign-in with your credentials.

-

Any changes made to your Login.gov account will automatically be synced with Notify.gov.

- {% elif 'email_auth' in current_service.permissions and not login_gov_enabled %} -

- Email link or text message code -

-

- Your team members can sign in with either a text message code - or an email link. -

-

- You can set the sign-in method for individual team members. -

- {% else %} -

- Text message code -

-

- Your team members sign in with a text message code. -

-

- Contact us if signing in with a text message is a problem for your team. -

- {% endif %} +

Your username, password, and multi-factor authentication options are handled by Login.gov.

+

To make changes, head to Login.gov and sign-in with your credentials.

+

Any changes made to your Login.gov account will automatically be synced with Notify.gov.

From 78c08e69f78eaa109519dfdbf12739d41d3f180b Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Wed, 17 Apr 2024 12:01:37 -0400 Subject: [PATCH 68/71] Fixed failing test --- .../views/service_settings/test_service_settings.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/app/main/views/service_settings/test_service_settings.py b/tests/app/main/views/service_settings/test_service_settings.py index b87ef12d5d..4629104069 100644 --- a/tests/app/main/views/service_settings/test_service_settings.py +++ b/tests/app/main/views/service_settings/test_service_settings.py @@ -2545,11 +2545,19 @@ def test_send_files_by_email_contact_details_does_not_update_invalid_contact_det @pytest.mark.parametrize( ("endpoint", "permissions", "expected_p"), [ - ("main.service_set_auth_type", [], ("Text message code")), + ( + "main.service_set_auth_type", + [], + ( + "Your username, password, and multi-factor authentication options are handled by Login.gov." + ), + ), ( "main.service_set_auth_type", ["email_auth"], - ("Email link or text message code"), + ( + "Your username, password, and multi-factor authentication options are handled by Login.gov." + ), ), ], ) From 7bd9c748e5735e48674719b4b29e1aa35f692733 Mon Sep 17 00:00:00 2001 From: Jonathan Bobel Date: Wed, 17 Apr 2024 12:39:10 -0400 Subject: [PATCH 69/71] 1436 - small content change for mobile number hint --- app/templates/views/set-up-your-profile.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/views/set-up-your-profile.html b/app/templates/views/set-up-your-profile.html index 8f37d36178..e774a921f4 100644 --- a/app/templates/views/set-up-your-profile.html +++ b/app/templates/views/set-up-your-profile.html @@ -16,7 +16,7 @@

Set up your profile

{{ form.name(param_extensions={}) }}
{{ form.mobile_number(param_extensions={ - "hint": {"text": "We'll send you a security code by text message"}, + "hint": {"text": "We need your number so you can send yourself test texts"}, }) }}