diff --git a/.ds.baseline b/.ds.baseline index 0c5680c97..d77350fb1 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -573,7 +573,7 @@ "filename": "tests/app/main/views/test_user_profile.py", "hashed_secret": "8072d7aad32964ec43fbcb699c75dc38890792f7", "is_verified": false, - "line_number": 336, + "line_number": 337, "is_secret": false }, { @@ -581,7 +581,7 @@ "filename": "tests/app/main/views/test_user_profile.py", "hashed_secret": "4c9dbb972da179e4f66f023eaa5fb9451d835030", "is_verified": false, - "line_number": 337, + "line_number": 338, "is_secret": false } ], @@ -634,5 +634,5 @@ } ] }, - "generated_at": "2025-10-14T19:59:45Z" + "generated_at": "2025-10-31T00:30:15Z" } diff --git a/app/main/views/organizations.py b/app/main/views/organizations.py index ce0b58597..5a42f986b 100644 --- a/app/main/views/organizations.py +++ b/app/main/views/organizations.py @@ -90,7 +90,9 @@ def get_organization_message_allowance(org_id): def get_services_dashboard_data(organization, year): try: - dashboard_data = organizations_client.get_organization_dashboard(organization.id, year) + dashboard_data = organizations_client.get_organization_dashboard( + organization.id, year + ) services = dashboard_data.get("services", []) except Exception as e: current_app.logger.error(f"Error fetching dashboard data: {e}") @@ -112,7 +114,9 @@ def get_services_dashboard_data(organization, year): usage_parts.append(f"{emails_sent:,} emails") if sms_sent > 0 or sms_remainder > 0: if sms_cost > 0: - usage_parts.append(f"{sms_sent:,} sms ({sms_remainder:,} remaining, ${sms_cost:,.2f})") + usage_parts.append( + f"{sms_sent:,} sms ({sms_remainder:,} remaining, ${sms_cost:,.2f})" + ) else: usage_parts.append(f"{sms_sent:,} sms ({sms_remainder:,} remaining)") @@ -135,7 +139,8 @@ def organization_dashboard(org_id): if action == "create-service" or request.form.get("form_name") == "create_service": create_service_form = CreateServiceForm( - organization_type=current_user.default_organization_type or OrganizationType.FEDERAL + organization_type=current_user.default_organization_type + or OrganizationType.FEDERAL ) if request.method == "POST" and create_service_form.validate_on_submit(): @@ -148,23 +153,30 @@ def organization_dashboard(org_id): ) if not error: current_organization.associate_service(service_id) - current_app.logger.info(f"Service {service_id} created and associated with org {org_id}") + current_app.logger.info( + f"Service {service_id} created and associated with org {org_id}" + ) flash(f"Service '{service_name}' has been created", "default_with_tick") - session['new_service_id'] = service_id + session["new_service_id"] = service_id return redirect(url_for(".organization_dashboard", org_id=org_id)) else: current_app.logger.error(f"Error creating service: {error}") flash("Error creating service", "error") if action == "invite-user" or request.form.get("form_name") == "invite_user": - invite_user_form = InviteOrgUserForm(inviter_email_address=current_user.email_address) + invite_user_form = InviteOrgUserForm( + inviter_email_address=current_user.email_address + ) if request.method == "POST" and invite_user_form.validate_on_submit(): try: invited_org_user = InvitedOrgUser.create( current_user.id, org_id, invite_user_form.email_address.data ) - flash(f"Invite sent to {invited_org_user.email_address}", "default_with_tick") + flash( + f"Invite sent to {invited_org_user.email_address}", + "default_with_tick", + ) return redirect(url_for(".organization_dashboard", org_id=org_id)) except Exception as e: current_app.logger.error(f"Error inviting user: {e}") @@ -173,7 +185,7 @@ def organization_dashboard(org_id): message_allowance = get_organization_message_allowance(org_id) services_with_usage = get_services_dashboard_data(current_organization, year) - new_service_id = session.pop('new_service_id', None) + new_service_id = session.pop("new_service_id", None) return render_template( "views/organizations/organization/index.html", diff --git a/tests/app/main/test_errorhandlers.py b/tests/app/main/test_errorhandlers.py index 6b0178382..67dac9d46 100644 --- a/tests/app/main/test_errorhandlers.py +++ b/tests/app/main/test_errorhandlers.py @@ -39,7 +39,7 @@ def test_malformed_token_returns_page_not_found(client_request, url): page = client_request.get_url(url, _expected_status=404) assert page.h1.string.strip() == "Page not found" - flash_banner = page.find("div", class_="banner-dangerous").string.strip() + flash_banner = page.select_one(".usa-alert--error .usa-alert__text").text.strip() assert flash_banner == "There’s something wrong with the link you’ve used." assert page.title.string.strip() == "Page not found – Notify.gov" diff --git a/tests/app/main/views/organizations/test_organizations.py b/tests/app/main/views/organizations/test_organizations.py index 70389b8d6..53996d68f 100644 --- a/tests/app/main/views/organizations/test_organizations.py +++ b/tests/app/main/views/organizations/test_organizations.py @@ -686,7 +686,7 @@ def test_manage_org_users_shows_correct_link_next_to_each_user( ) # No banner confirming a user to be deleted shown - assert not page.select_one(".banner-dangerous") + assert not page.select_one(".usa-alert--error") users = page.find_all(class_="user-list-item") @@ -841,9 +841,10 @@ def test_edit_organization_user_shows_the_delete_confirmation_banner( assert normalize_spaces(page.h1) == "Team members" - banner = page.select_one(".banner-dangerous") + banner = page.select_one(".usa-alert--error") + banner_text = banner.select_one(".usa-alert__text") assert "Are you sure you want to remove Test User?" in normalize_spaces( - banner.contents[0] + banner_text.text ) assert banner.form.attrs["action"] == url_for( "main.remove_user_from_organization", @@ -1215,7 +1216,7 @@ def test_update_organization_domains_when_domain_already_exists( ) assert ( - response.find("div", class_="banner-dangerous").text.strip() + response.select_one(".usa-alert--error .usa-alert__text").text.strip() == "This domain is already in use" ) @@ -1585,9 +1586,24 @@ def test_organization_dashboard_shows_service_counts( "app.organizations_client.get_organization_dashboard", return_value={ "services": [ - {"service_id": "1", "service_name": "Live Service", "active": True, "restricted": False}, - {"service_id": "2", "service_name": "Trial Service", "active": True, "restricted": True}, - {"service_id": "3", "service_name": "Suspended", "active": False, "restricted": False}, + { + "service_id": "1", + "service_name": "Live Service", + "active": True, + "restricted": False, + }, + { + "service_id": "2", + "service_name": "Trial Service", + "active": True, + "restricted": True, + }, + { + "service_id": "3", + "service_name": "Suspended", + "active": False, + "restricted": False, + }, ] }, ) @@ -1615,11 +1631,17 @@ def test_organization_dashboard_services_table( mocker, active_user_with_permissions, ): - mocker.patch.dict("flask.current_app.config", {"ORGANIZATION_DASHBOARD_ENABLED": True}) + mocker.patch.dict( + "flask.current_app.config", {"ORGANIZATION_DASHBOARD_ENABLED": True} + ) mocker.patch( "app.organizations_client.get_organization_message_usage", - return_value={"messages_sent": 0, "messages_remaining": 0, "total_message_limit": 0}, + return_value={ + "messages_sent": 0, + "messages_remaining": 0, + "total_message_limit": 0, + }, ) mocker.patch( "app.organizations_client.get_organization_services", diff --git a/tests/app/main/views/test_manage_users.py b/tests/app/main/views/test_manage_users.py index b7b65c254..05b12afd2 100644 --- a/tests/app/main/views/test_manage_users.py +++ b/tests/app/main/views/test_manage_users.py @@ -1027,7 +1027,7 @@ def test_invite_user( _follow_redirects=True, ) assert page.h1.string.strip() == "Team members" - flash_banner = page.find("div", class_="banner-default-with-tick").string.strip() + flash_banner = page.select_one(".usa-alert--success .usa-alert__text").text.strip() assert flash_banner == f"Invite sent to {email_address}" expected_permissions = { @@ -1139,7 +1139,7 @@ def test_invite_user_with_email_auth_service( ) assert page.h1.string.strip() == "Team members" - flash_banner = page.find("div", class_="banner-default-with-tick").string.strip() + flash_banner = page.select_one(".usa-alert--success .usa-alert__text").text.strip() assert flash_banner == "Invite sent to test@example.gsa.gov" expected_permissions = { @@ -1212,7 +1212,7 @@ def test_cancel_invited_user_cancels_user_invitations( assert normalize_spaces(page.h1.text) == "Team members" flash_banner = normalize_spaces( - page.find("div", class_="banner-default-with-tick").text + page.select_one(".usa-alert--success .usa-alert__text").text ) assert flash_banner == f"Invitation cancelled for {sample_invite['email_address']}" mock_cancel.assert_called_once_with( @@ -1839,8 +1839,11 @@ def test_edit_user_permissions_with_delete_query_shows_banner( delete=1, ) - banner = page.find("div", class_="banner-dangerous") - assert banner.contents[0].strip() == "Are you sure you want to remove Test User?" + banner = page.select_one(".usa-alert--error") + assert ( + banner.select_one(".usa-alert__text").text.strip() + == "Are you sure you want to remove Test User?" + ) assert banner.form.attrs["action"] == url_for( "main.remove_user_from_service", service_id=service_one["id"], diff --git a/tests/app/main/views/test_send.py b/tests/app/main/views/test_send.py index 4c93ce745..0d7e82277 100644 --- a/tests/app/main/views/test_send.py +++ b/tests/app/main/views/test_send.py @@ -464,9 +464,9 @@ def test_upload_files_in_different_formats( ) else: assert not mock_s3_upload.called - assert normalize_spaces(page.select_one(".banner-dangerous").text) == ( - "Could not read {}. Try using a different file format.".format(filename) - ) + assert normalize_spaces( + page.select_one(".usa-alert--error .usa-alert__text").text + ) == ("Could not read {}. Try using a different file format.".format(filename)) def test_send_messages_sanitises_and_truncates_file_name_for_metadata( @@ -574,9 +574,9 @@ def test_shows_error_if_parsing_exception( _expected_status=200, ) - assert normalize_spaces(page.select_one(".banner-dangerous").text) == ( - expected_error_message - ) + assert normalize_spaces( + page.select_one(".usa-alert--error .usa-alert__text").text + ) == (expected_error_message) def test_upload_csv_file_with_errors_shows_check_page_with_errors( @@ -672,7 +672,9 @@ def test_upload_csv_file_with_empty_message_shows_check_page_with_errors( with client_request.session_transaction() as session: assert "file_uploads" not in session - assert normalize_spaces(page.select_one(".banner-dangerous").text) == ( + assert normalize_spaces( + page.select_one(".usa-alert--error .usa-alert__text").text + ) == ( "There’s a problem with example.csv " "You need to check you have content for the empty message in 1 row." ) @@ -730,7 +732,9 @@ def test_upload_csv_file_with_very_long_placeholder_shows_check_page_with_errors with client_request.session_transaction() as session: assert "file_uploads" not in session - assert normalize_spaces(page.select_one(".banner-dangerous").text) == ( + assert normalize_spaces( + page.select_one(".usa-alert--error .usa-alert__text").text + ) == ( "There’s a problem with example.csv " "You need to shorten the messages in 2 rows." ) @@ -870,7 +874,7 @@ def test_upload_csv_file_with_missing_columns_shows_error( page.select_one("input[type=file]")["accept"] == ".csv,.xlsx,.xls,.ods,.xlsm,.tsv" ) - assert normalize_spaces(page.select(".banner-dangerous")[0].text) == expected_error + assert normalize_spaces(page.select(".usa-alert--error")[0].text) == expected_error def test_upload_csv_invalid_extension( @@ -2345,13 +2349,11 @@ def test_check_messages_shows_too_many_messages_errors( ) assert page.find("h1").text.strip() == "Too many recipients" - assert ( - page.find("div", class_="banner-dangerous").find("a").text.strip() - == "trial mode" - ) + assert page.select_one(".usa-alert--error").find("a").text.strip() == "trial mode" # remove excess whitespace from element - details = page.find("div", class_="banner-dangerous").find_all("p")[1] + alert_texts = page.select(".usa-alert--error .usa-alert__text") + details = alert_texts[-1] details = " ".join( [line.strip() for line in details.text.split("\n") if line.strip() != ""] ) @@ -2394,7 +2396,9 @@ def test_check_messages_shows_trial_mode_error( upload_id=fake_uuid, ) - assert " ".join(page.find("div", class_="banner-dangerous").text.split()) == ( + assert " ".join( + page.select_one(".usa-alert--error .usa-alert__text").text.split() + ) == ( "You cannot send to this phone number " "In trial mode you can only send to yourself and members of your team" ) @@ -2435,7 +2439,9 @@ def test_warns_if_file_sent_already( original_file_name=uploaded_file_name, ) - assert normalize_spaces(page.select_one(".banner-dangerous").text) == ( + assert normalize_spaces( + page.select_one(".usa-alert--error .usa-alert__text").text + ) == ( "These messages have already been sent today " "If you need to resend them, rename the file and upload it again." ) @@ -2490,7 +2496,9 @@ def stmt_for_test_warns_if_file_sent_already_errors( upload_id=fake_uuid, original_file_name=uploaded_file_name, ) - assert normalize_spaces(page.select_one(".banner-dangerous").text) == ( + assert normalize_spaces( + page.select_one(".usa-alert--error .usa-alert__text").text + ) == ( "These messages have already been sent today " "If you need to resend them, rename the file and upload it again." ) @@ -2537,7 +2545,9 @@ def test_check_messages_column_error_doesnt_show_optional_columns( _test_page_title=False, ) - banner_text = normalize_spaces(page.select_one(".banner-dangerous").text) + banner_text = normalize_spaces( + page.select_one(".usa-alert--error .usa-alert__text").text + ) assert "problem with your column names" in banner_text assert "phone number" in banner_text assert "address_line_1" in banner_text @@ -2628,7 +2638,9 @@ def test_check_messages_shows_over_max_row_error( upload_id=fake_uuid, ) - assert " ".join(page.find("div", class_="banner-dangerous").text.split()) == ( + assert " ".join( + page.select_one(".usa-alert--error .usa-alert__text").text.split() + ) == ( "Your file has too many rows " "Notify can process up to 11,111 rows at once. " "Your file has 99,999 rows." diff --git a/tests/app/main/views/test_templates.py b/tests/app/main/views/test_templates.py index e5ac219aa..be5e205e4 100644 --- a/tests/app/main/views/test_templates.py +++ b/tests/app/main/views/test_templates.py @@ -1442,11 +1442,11 @@ def test_should_show_delete_template_page_with_time_block( ) assert ( "Are you sure you want to delete ‘Two week reminder’?" - in page.select(".banner-dangerous")[0].text - ) - assert normalize_spaces(page.select(".banner-dangerous p")[0].text) == ( - "This template was last used 10 minutes ago." + in page.select(".usa-alert--error")[0].text ) + assert normalize_spaces( + page.select(".usa-alert--error .usa-alert__text")[1].text + ) == ("This template was last used 10 minutes ago.") assert normalize_spaces(page.select(".sms-message-wrapper")[0].text) == ( "service one: Template content with & entity" ) @@ -1474,11 +1474,11 @@ def test_should_show_delete_template_page_with_time_block_for_empty_notification ) assert ( "Are you sure you want to delete ‘Two week reminder’?" - in page.select(".banner-dangerous")[0].text - ) - assert normalize_spaces(page.select(".banner-dangerous p")[0].text) == ( - "This template has never been used." + in page.select(".usa-alert--error")[0].text ) + assert normalize_spaces( + page.select(".usa-alert--error .usa-alert__text")[1].text + ) == ("This template has never been used.") assert normalize_spaces(page.select(".sms-message-wrapper")[0].text) == ( "service one: Template content with & entity" ) @@ -1506,9 +1506,10 @@ def test_should_show_delete_template_page_with_never_used_block( ) assert ( "Are you sure you want to delete ‘Two week reminder’?" - in page.select(".banner-dangerous")[0].text + in page.select(".usa-alert--error")[0].text ) - assert not page.select(".banner-dangerous p") + # When message is None, there's only one .usa-alert__text (the main message), not two + assert len(page.select(".usa-alert--error .usa-alert__text")) == 1 assert normalize_spaces(page.select(".sms-message-wrapper")[0].text) == ( "service one: Template content with & entity" ) @@ -1880,7 +1881,7 @@ def test_should_show_message_before_redacting_template( assert ( "Are you sure you want to hide all personalized and conditional" " content after sending for increased privacy protection?" - ) in page.select(".banner-dangerous")[0].text + ) in page.select(".usa-alert--error")[0].text form = page.select(".banner-dangerous form")[0] @@ -1903,7 +1904,7 @@ def test_should_show_redact_template( _follow_redirects=True, ) - assert normalize_spaces(page.select(".banner-default-with-tick")[0].text) == ( + assert normalize_spaces(page.select(".usa-alert--success")[0].text) == ( "Personalized content will be hidden for messages sent with this template" ) diff --git a/tests/app/main/views/test_user_profile.py b/tests/app/main/views/test_user_profile.py index 0d71b0736..059593f65 100644 --- a/tests/app/main/views/test_user_profile.py +++ b/tests/app/main/views/test_user_profile.py @@ -202,11 +202,12 @@ def test_confirm_delete_mobile_number( _test_page_title=False, ) - assert normalize_spaces(page.select_one(".banner-dangerous").text) == ( - "Are you sure you want to delete your mobile number from Notify? " "Yes, delete" + assert ( + normalize_spaces(page.select_one(".usa-alert--error .usa-alert__text").text) + == "Are you sure you want to delete your mobile number from Notify?" ) - assert "action" not in page.select_one(".banner-dangerous form") - assert page.select_one(".banner-dangerous form")["method"] == "post" + assert "action" not in page.select_one(".usa-alert--error form") + assert page.select_one(".usa-alert--error form")["method"] == "post" def test_delete_mobile_number(client_request, api_user_active_email_auth, mocker): diff --git a/tests/app/main/views/test_verify.py b/tests/app/main/views/test_verify.py index b082a5c82..2790a4d39 100644 --- a/tests/app/main/views/test_verify.py +++ b/tests/app/main/views/test_verify.py @@ -217,7 +217,7 @@ def test_verify_email_redirects_to_sign_in_if_user_active( ) assert page.h1.text == "Sign in" - flash_banner = page.find("div", class_="banner-dangerous").string.strip() + flash_banner = page.select_one(".usa-alert--error .usa-alert__text").text.strip() assert flash_banner == "That verification link has expired."