Files
notifications-admin/tests/app/main/views/test_manage_users.py
T

2023 lines
60 KiB
Python
Raw Normal View History

import copy
import uuid
2018-02-20 11:22:17 +00:00
import pytest
2018-02-20 11:22:17 +00:00
from flask import url_for
2025-09-17 12:22:09 -07:00
from hypothesis import given
2025-09-17 12:16:12 -07:00
from hypothesis import strategies as st
2018-04-25 14:12:58 +01:00
import app
from app.enums import ServicePermission
2021-06-09 13:19:05 +01:00
from app.utils.user import is_gov_user
2018-02-20 11:22:17 +00:00
from tests.conftest import (
ORGANISATION_ID,
ORGANISATION_TWO_ID,
2018-02-20 11:22:17 +00:00
SERVICE_ONE_ID,
USER_ONE_ID,
2019-12-19 16:59:07 +00:00
create_active_user_empty_permissions,
create_active_user_manage_template_permissions,
create_active_user_view_permissions,
create_active_user_with_permissions,
2023-11-08 07:51:57 -08:00
create_platform_admin_user,
2018-02-20 11:22:17 +00:00
normalize_spaces,
sample_uuid,
2018-02-20 11:22:17 +00:00
)
2016-02-19 15:02:13 +00:00
2023-10-26 11:38:03 -07:00
@pytest.mark.parametrize(
("user", "expected_self_text", "add_details"),
[
2017-08-17 10:49:21 +01:00
(
create_active_user_with_permissions(),
(
2025-05-14 11:07:12 -04:00
"Test User test@user.gsa.gov (you) "
"Permissions "
"Can See dashboard "
"Can Send messages "
"Can Add and edit templates "
2024-10-21 12:27:44 -07:00
"Can Manage settings, team and usage"
),
2023-10-26 11:38:03 -07:00
True,
2017-08-17 10:49:21 +01:00
),
(
create_active_user_empty_permissions(),
2025-05-14 11:07:12 -04:00
("Test User With Empty Permissions test@user.gsa.gov (you) " "Permissions"),
2023-10-26 11:38:03 -07:00
False,
2018-08-06 11:10:37 +01:00
),
(
create_active_user_view_permissions(),
2025-05-20 10:26:54 -07:00
(
"Test User With Permissions test@user.gsa.gov (you) "
"Permissions "
"Can See dashboard"
),
2023-10-26 11:38:03 -07:00
False,
),
(
create_active_user_manage_template_permissions(),
(
2025-05-14 11:07:12 -04:00
"Test User With Permissions test@user.gsa.gov (you) "
"Permissions "
"Can See dashboard "
2023-11-09 12:00:31 -07:00
"Can Add and edit templates"
),
2023-10-26 11:38:03 -07:00
False,
2018-06-12 14:29:47 +01:00
),
],
)
2016-02-29 17:35:21 +00:00
def test_should_show_overview_page(
client_request,
2017-02-03 10:42:01 +00:00
mocker,
mock_get_invites_for_service,
mock_get_template_folders,
2018-08-06 11:10:37 +01:00
mock_has_no_jobs,
2018-06-12 14:29:47 +01:00
service_one,
2017-08-17 10:49:21 +01:00
user,
expected_self_text,
active_user_view_permissions,
2023-10-26 11:38:03 -07:00
add_details,
2016-02-29 17:35:21 +00:00
):
2019-12-19 16:59:07 +00:00
current_user = user
other_user = copy.deepcopy(active_user_view_permissions)
other_user["email_address"] = "zzzzzzz@example.gsa.gov"
other_user["name"] = "ZZZZZZZZ"
other_user["id"] = "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz"
2023-01-19 17:29:21 -05:00
client_request.login(current_user)
mock_get_users = mocker.patch(
"app.models.user.Users.client_method",
return_value=[
current_user,
other_user,
],
)
page = client_request.get("main.manage_users", service_id=SERVICE_ONE_ID)
2016-02-29 17:35:21 +00:00
assert normalize_spaces(page.select_one("h1").text) == "Team members"
assert (
normalize_spaces(page.select(".user-list-item")[0].text) == expected_self_text
)
2023-10-26 11:38:03 -07:00
2023-11-09 12:00:31 -07:00
expected = "ZZZZZZZZ zzzzzzz@example.gsa.gov " "Permissions " "Can See dashboard"
2023-10-26 11:38:03 -07:00
if add_details is True:
expected = f"{expected} Change details for ZZZZZZZZ zzzzzzz@example.gsa.gov"
assert normalize_spaces(page.select(".user-list-item")[6].text) == expected
mock_get_users.assert_called_once_with(SERVICE_ONE_ID)
2016-02-19 15:02:13 +00:00
@pytest.mark.parametrize(
"state",
2023-09-11 16:51:30 -04:00
[
"active",
"pending",
2023-09-11 16:51:30 -04:00
],
)
2022-05-04 16:46:00 +01:00
def test_should_show_change_details_link(
client_request,
mocker,
mock_get_invites_for_service,
mock_get_template_folders,
service_one,
active_user_with_permissions,
active_caseworking_user,
state,
):
current_user = active_user_with_permissions
other_user = active_caseworking_user
other_user["id"] = uuid.uuid4()
other_user["email_address"] = "zzzzzzz@example.gsa.gov"
other_user["state"] = state
2022-05-04 16:46:00 +01:00
mocker.patch("app.user_api_client.get_user", return_value=current_user)
mocker.patch(
"app.models.user.Users.client_method",
return_value=[
current_user,
other_user,
],
)
2022-05-04 16:46:00 +01:00
page = client_request.get("main.manage_users", service_id=SERVICE_ONE_ID)
link = page.select(".user-list-item")[-1].select_one("a")
2022-05-04 16:46:00 +01:00
assert normalize_spaces(link.text) == (
"Change details for Test User zzzzzzz@example.gsa.gov"
2022-05-04 16:46:00 +01:00
)
assert link["href"] == url_for(
".edit_user_permissions",
2022-05-04 16:46:00 +01:00
service_id=SERVICE_ONE_ID,
user_id=other_user["id"],
2022-05-04 16:46:00 +01:00
)
@pytest.mark.parametrize(
"number_of_users",
2023-09-11 16:51:30 -04:00
[
pytest.param(7),
pytest.param(8),
2023-09-11 16:51:30 -04:00
],
)
def test_should_show_live_search_if_more_than_7_users(
client_request,
mocker,
mock_get_invites_for_service,
mock_get_template_folders,
mock_has_no_jobs,
active_user_with_permissions,
active_user_view_permissions,
number_of_users,
):
mocker.patch(
"app.user_api_client.get_user", return_value=active_user_with_permissions
)
mocker.patch("app.models.user.InvitedUsers.client_method", return_value=[])
mocker.patch(
"app.models.user.Users.client_method",
return_value=[active_user_with_permissions] * number_of_users,
)
page = client_request.get("main.manage_users", service_id=SERVICE_ONE_ID)
2023-05-26 14:52:33 -07:00
if number_of_users == 7:
with pytest.raises(expected_exception=TypeError):
assert page.select_one("div[data-module=live-search]")["data-targets"] == (
2023-05-26 14:52:33 -07:00
".user-list-item"
)
return
assert page.select_one("div[data-module=live-search]")["data-targets"] == (
".user-list-item"
)
assert len(page.select(".user-list-item")) == number_of_users
2025-04-18 09:54:31 -04:00
textbox = page.select_one(".usa-input")
assert "value" not in textbox
assert textbox["name"] == "search"
# data-module=autofocus is set on a containing element so it
# shouldnt also be set on the textbox itself
assert "data-module" not in textbox
assert not page.select_one("[data-force-focus]")
assert textbox["class"] == [
"usa-input",
]
assert (
2025-02-25 13:58:49 -05:00
normalize_spaces(page.select_one("label:contains('Search by')").text)
== "Search by name or email address"
)
2018-06-12 14:29:47 +01:00
def test_should_show_caseworker_on_overview_page(
client_request,
mocker,
mock_get_invites_for_service,
mock_get_template_folders,
2018-06-12 14:29:47 +01:00
service_one,
2019-12-19 16:59:07 +00:00
active_user_view_permissions,
active_caseworking_user,
2018-06-12 14:29:47 +01:00
):
service_one["permissions"].append("caseworking")
2019-12-19 16:59:07 +00:00
current_user = active_user_view_permissions
other_user = active_caseworking_user
other_user["id"] = uuid.uuid4()
other_user["email_address"] = "zzzzzzz@example.gsa.gov"
2018-06-12 14:29:47 +01:00
2023-01-19 17:29:21 -05:00
client_request.login(current_user)
mocker.patch(
"app.models.user.Users.client_method",
return_value=[
current_user,
other_user,
],
)
2018-06-12 14:29:47 +01:00
page = client_request.get("main.manage_users", service_id=SERVICE_ONE_ID)
2018-06-12 14:29:47 +01:00
assert normalize_spaces(page.select_one("h1").text) == "Team members"
assert normalize_spaces(page.select(".user-list-item")[0].text) == (
2025-05-20 10:26:54 -07:00
"Test User With Permissions test@user.gsa.gov (you) "
"Permissions "
"Can See dashboard"
2018-06-12 14:29:47 +01:00
)
# [1:5] are invited users
assert normalize_spaces(page.select(".user-list-item")[6].text) == (
2023-11-09 12:00:31 -07:00
"Test User zzzzzzz@example.gsa.gov " "Permissions " "Can Send messages"
2018-06-12 14:29:47 +01:00
)
@pytest.mark.parametrize(
2023-09-11 16:51:30 -04:00
("endpoint", "extra_args", "service_has_email_auth", "auth_options_hidden"),
[
("main.edit_user_permissions", {"user_id": sample_uuid()}, True, False),
("main.edit_user_permissions", {"user_id": sample_uuid()}, False, True),
("main.invite_user", {}, True, False),
("main.invite_user", {}, False, True),
],
)
def test_service_with_no_email_auth_hides_auth_type_options(
client_request,
endpoint,
extra_args,
service_has_email_auth,
auth_options_hidden,
service_one,
mock_get_users_by_service,
mock_get_template_folders,
platform_admin_user,
):
if service_has_email_auth:
2025-07-21 16:37:55 -07:00
service_one["permissions"].append(ServicePermission.EMAIL_AUTH)
client_request.login(platform_admin_user)
page = client_request.get(endpoint, service_id=service_one["id"], **extra_args)
assert (
page.find("input", attrs={"name": "login_authentication"}) is None
) == auth_options_hidden
2023-09-11 16:51:30 -04:00
@pytest.mark.parametrize("service_has_caseworking", [True, False])
@pytest.mark.parametrize(
2023-09-11 16:51:30 -04:00
("endpoint", "extra_args"),
[
(
"main.edit_user_permissions",
{"user_id": sample_uuid()},
),
(
"main.invite_user",
{},
),
],
)
2018-06-12 14:29:47 +01:00
def test_service_without_caseworking_doesnt_show_admin_vs_caseworker(
client_request,
mock_get_users_by_service,
mock_get_template_folders,
2018-06-12 14:29:47 +01:00
endpoint,
service_has_caseworking,
2018-08-06 11:10:37 +01:00
extra_args,
platform_admin_user,
2018-06-12 14:29:47 +01:00
):
client_request.login(platform_admin_user)
page = client_request.get(endpoint, service_id=SERVICE_ONE_ID, **extra_args)
permission_checkboxes = page.select("input[type=checkbox]")
for idx in range(len(permission_checkboxes)):
assert permission_checkboxes[idx]["name"] == "permissions_field"
assert permission_checkboxes[0]["value"] == ServicePermission.VIEW_ACTIVITY
assert permission_checkboxes[1]["value"] == ServicePermission.SEND_MESSAGES
assert permission_checkboxes[2]["value"] == ServicePermission.MANAGE_TEMPLATES
assert permission_checkboxes[3]["value"] == ServicePermission.MANAGE_SERVICE
2018-06-12 14:29:47 +01:00
@pytest.mark.parametrize(
2023-09-11 16:51:30 -04:00
("service_has_email_auth", "displays_auth_type"), [(True, True), (False, False)]
)
def test_manage_users_page_shows_member_auth_type_if_service_has_email_auth_activated(
client_request,
service_has_email_auth,
service_one,
mock_get_users_by_service,
mock_get_invites_for_service,
mock_get_template_folders,
displays_auth_type,
):
if service_has_email_auth:
2025-07-21 16:37:55 -07:00
service_one["permissions"].append(ServicePermission.EMAIL_AUTH)
page = client_request.get("main.manage_users", service_id=service_one["id"])
assert bool(page.select_one(".tick-cross-list-hint")) == displays_auth_type
@pytest.mark.parametrize(
2023-09-11 16:51:30 -04:00
("sms_option_disabled", "mobile_number", "expected_label"),
[
(
True,
None,
"""
Text message code
2019-09-13 12:49:40 +01:00
Not available because this team member has not added a
phone number to their profile
""",
),
(
False,
"202-867-5303",
"""
Text message code
""",
),
],
)
def test_user_with_no_mobile_number_cant_be_set_to_sms_auth(
client_request,
mock_get_users_by_service,
mock_get_template_folders,
sms_option_disabled,
2019-12-19 16:59:07 +00:00
mobile_number,
expected_label,
service_one,
2019-06-05 12:14:50 +01:00
mocker,
2019-12-19 16:59:07 +00:00
active_user_with_permissions,
):
active_user_with_permissions["mobile_number"] = mobile_number
2019-12-19 16:59:07 +00:00
2025-07-21 16:37:55 -07:00
service_one["permissions"].append(ServicePermission.EMAIL_AUTH)
mocker.patch(
"app.user_api_client.get_user", return_value=active_user_with_permissions
)
page = client_request.get(
"main.edit_user_permissions",
service_id=service_one["id"],
user_id=sample_uuid(),
)
sms_auth_radio_button = page.select_one('input[value="sms_auth"]')
assert sms_auth_radio_button.has_attr("disabled") == sms_option_disabled
assert normalize_spaces(
page.select_one("label[for=login_authentication-0]").text
) == normalize_spaces(expected_label)
2025-02-26 12:09:34 -05:00
@pytest.mark.parametrize(
2023-09-11 16:51:30 -04:00
("endpoint", "extra_args", "expected_checkboxes"),
[
(
"main.edit_user_permissions",
{"user_id": sample_uuid()},
[
(ServicePermission.VIEW_ACTIVITY, True),
(ServicePermission.SEND_MESSAGES, True),
(ServicePermission.MANAGE_TEMPLATES, True),
(ServicePermission.MANAGE_SERVICE, True),
],
),
(
"main.invite_user",
{},
[
(ServicePermission.VIEW_ACTIVITY, False),
(ServicePermission.SEND_MESSAGES, False),
(ServicePermission.MANAGE_TEMPLATES, False),
(ServicePermission.MANAGE_SERVICE, False),
],
),
],
)
2016-02-19 15:02:13 +00:00
def test_should_show_page_for_one_user(
client_request,
mock_get_users_by_service,
mock_get_template_folders,
2017-08-17 10:49:21 +01:00
endpoint,
extra_args,
expected_checkboxes,
platform_admin_user,
2016-02-19 15:02:13 +00:00
):
client_request.login(platform_admin_user)
2017-08-17 10:49:21 +01:00
page = client_request.get(endpoint, service_id=SERVICE_ONE_ID, **extra_args)
checkboxes = page.select("input[type=checkbox]")
2017-08-17 10:49:21 +01:00
2024-10-21 12:27:44 -07:00
assert len(checkboxes) == 4
2017-08-17 10:49:21 +01:00
for index, expected in enumerate(expected_checkboxes):
2020-04-23 10:57:24 +01:00
expected_input_value, expected_checked = expected
assert checkboxes[index]["name"] == "permissions_field"
assert checkboxes[index]["value"] == expected_input_value
assert checkboxes[index].has_attr("checked") == expected_checked
2016-02-19 15:02:13 +00:00
def test_invite_user_allows_to_choose_auth(
client_request,
mock_get_users_by_service,
mock_get_template_folders,
service_one,
platform_admin_user,
):
2025-07-21 16:37:55 -07:00
service_one["permissions"].append(ServicePermission.EMAIL_AUTH)
client_request.login(platform_admin_user)
page = client_request.get("main.invite_user", service_id=SERVICE_ONE_ID)
2021-06-30 15:29:02 +01:00
radio_buttons = page.select("input[name=login_authentication]")
values = {button["value"] for button in radio_buttons}
assert values == {"sms_auth", "email_auth"}
2021-06-30 15:29:02 +01:00
assert not any(button.has_attr("disabled") for button in radio_buttons)
def test_invite_user_has_correct_email_field(
client_request,
mock_get_users_by_service,
mock_get_template_folders,
platform_admin_user,
2025-05-02 11:59:13 -04:00
service_one,
mocker,
):
2025-05-02 11:59:13 -04:00
mocker.patch("app.models.user.InvitedUsers.client_method", return_value=[])
mocker.patch(
"app.models.user.Users.client_method", return_value=[platform_admin_user]
)
client_request.login(platform_admin_user)
email_field = client_request.get(
"main.invite_user", service_id=SERVICE_ONE_ID
2025-05-02 11:59:13 -04:00
).select_one("#email_address")
assert email_field["spellcheck"] == "false"
assert "autocomplete" not in email_field
def test_should_not_show_page_for_non_team_member(
client_request,
mock_get_users_by_service,
):
client_request.get(
"main.edit_user_permissions",
service_id=SERVICE_ONE_ID,
user_id=USER_ONE_ID,
_expected_status=404,
)
@pytest.mark.parametrize(
2023-09-11 16:51:30 -04:00
("submitted_permissions", "permissions_sent_to_api"),
[
(
{
"permissions_field": [
ServicePermission.VIEW_ACTIVITY,
ServicePermission.SEND_MESSAGES,
ServicePermission.MANAGE_TEMPLATES,
ServicePermission.MANAGE_SERVICE,
]
},
{
ServicePermission.VIEW_ACTIVITY,
ServicePermission.SEND_MESSAGES,
ServicePermission.MANAGE_SERVICE,
ServicePermission.MANAGE_TEMPLATES,
},
),
(
{
"permissions_field": [
ServicePermission.VIEW_ACTIVITY,
ServicePermission.SEND_MESSAGES,
ServicePermission.MANAGE_TEMPLATES,
]
},
{
ServicePermission.VIEW_ACTIVITY,
ServicePermission.SEND_MESSAGES,
ServicePermission.MANAGE_TEMPLATES,
},
),
(
{},
set(),
),
],
)
2018-08-06 11:10:37 +01:00
def test_edit_user_permissions(
client_request,
2017-02-03 10:42:01 +00:00
mocker,
mock_get_users_by_service,
2017-02-03 10:42:01 +00:00
mock_get_invites_for_service,
mock_set_user_permissions,
mock_get_template_folders,
2018-08-06 11:10:37 +01:00
fake_uuid,
submitted_permissions,
permissions_sent_to_api,
2016-03-03 14:32:19 +00:00
):
2018-08-06 11:10:37 +01:00
client_request.post(
"main.edit_user_permissions",
2018-08-06 11:10:37 +01:00
service_id=SERVICE_ONE_ID,
user_id=fake_uuid,
_data=dict(email_address="test@example.com", **submitted_permissions),
2018-08-06 11:10:37 +01:00
_expected_status=302,
_expected_redirect=url_for(
"main.manage_users",
2018-08-06 11:10:37 +01:00
service_id=SERVICE_ONE_ID,
),
2017-02-03 12:07:21 +00:00
)
mock_set_user_permissions.assert_called_with(
2018-08-06 11:10:37 +01:00
fake_uuid,
SERVICE_ONE_ID,
permissions=permissions_sent_to_api,
folder_permissions=[],
)
def test_edit_user_folder_permissions(
client_request,
mocker,
service_one,
mock_get_users_by_service,
mock_get_invites_for_service,
mock_set_user_permissions,
mock_get_template_folders,
fake_uuid,
):
mock_get_template_folders.return_value = [
{
"id": "folder-id-1",
"name": "folder_one",
"parent_id": None,
"users_with_permission": [],
},
{
"id": "folder-id-2",
"name": "folder_one",
"parent_id": None,
"users_with_permission": [],
},
{
"id": "folder-id-3",
"name": "folder_one",
"parent_id": "folder-id-1",
"users_with_permission": [],
},
]
page = client_request.get(
"main.edit_user_permissions",
service_id=SERVICE_ONE_ID,
user_id=fake_uuid,
)
assert [
item["value"] for item in page.select("input[name=folder_permissions]")
] == ["folder-id-1", "folder-id-3", "folder-id-2"]
client_request.post(
"main.edit_user_permissions",
service_id=SERVICE_ONE_ID,
user_id=fake_uuid,
_data=dict(folder_permissions=["folder-id-1", "folder-id-3"]),
_expected_status=302,
_expected_redirect=url_for(
"main.manage_users",
service_id=SERVICE_ONE_ID,
),
)
mock_set_user_permissions.assert_called_with(
fake_uuid,
SERVICE_ONE_ID,
permissions=set(),
folder_permissions=["folder-id-1", "folder-id-3"],
2017-02-03 12:07:21 +00:00
)
2016-02-19 15:02:13 +00:00
def test_cant_edit_user_folder_permissions_for_platform_admin_users(
client_request,
mocker,
service_one,
mock_get_users_by_service,
mock_get_invites_for_service,
mock_set_user_permissions,
mock_get_template_folders,
2019-12-19 16:59:07 +00:00
platform_admin_user,
):
2025-07-21 16:37:55 -07:00
service_one["permissions"] = [ServicePermission.EDIT_FOLDER_PERMISSIONS]
mocker.patch("app.user_api_client.get_user", return_value=platform_admin_user)
mock_get_template_folders.return_value = [
{
"id": "folder-id-1",
"name": "folder_one",
"parent_id": None,
"users_with_permission": [],
},
{
"id": "folder-id-2",
"name": "folder_one",
"parent_id": None,
"users_with_permission": [],
},
{
"id": "folder-id-3",
"name": "folder_one",
"parent_id": "folder-id-1",
"users_with_permission": [],
},
]
page = client_request.get(
"main.edit_user_permissions",
service_id=SERVICE_ONE_ID,
user_id=platform_admin_user["id"],
)
assert (
normalize_spaces(page.select("main .usa-body")[0].text)
== "platform@admin.gsa.gov Change email address"
)
assert normalize_spaces(page.select("main .usa-body")[1].text) == (
"Platform admin users can access all template folders."
)
assert page.select("input[name=folder_permissions]") == []
client_request.post(
"main.edit_user_permissions",
service_id=SERVICE_ONE_ID,
user_id=platform_admin_user["id"],
_data={},
_expected_status=302,
_expected_redirect=url_for(
"main.manage_users",
service_id=SERVICE_ONE_ID,
),
)
mock_set_user_permissions.assert_called_with(
platform_admin_user["id"],
SERVICE_ONE_ID,
permissions={
ServicePermission.MANAGE_SERVICE,
ServicePermission.MANAGE_TEMPLATES,
ServicePermission.SEND_MESSAGES,
ServicePermission.VIEW_ACTIVITY,
},
folder_permissions=None,
)
def test_cant_edit_non_member_user_permissions(
client_request,
mocker,
mock_get_users_by_service,
mock_set_user_permissions,
):
client_request.post(
"main.edit_user_permissions",
service_id=SERVICE_ONE_ID,
user_id=USER_ONE_ID,
_data={
"email_address": "test@example.com",
ServicePermission.MANAGE_SERVICE: "y",
},
_expected_status=404,
)
assert mock_set_user_permissions.called is False
def test_edit_user_permissions_including_authentication_with_email_auth_service(
2019-03-26 12:35:32 +00:00
client_request,
service_one,
active_user_with_permissions,
mock_get_users_by_service,
mock_get_invites_for_service,
mock_set_user_permissions,
mock_update_user_attribute,
mock_get_template_folders,
):
active_user_with_permissions["auth_type"] = "email_auth"
2025-07-21 16:37:55 -07:00
service_one["permissions"].append(ServicePermission.EMAIL_AUTH)
2019-03-26 12:35:32 +00:00
client_request.post(
"main.edit_user_permissions",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
2019-03-26 12:35:32 +00:00
_data={
"email_address": active_user_with_permissions["email_address"],
"permissions_field": [
ServicePermission.SEND_MESSAGES,
ServicePermission.MANAGE_TEMPLATES,
ServicePermission.MANAGE_SERVICE,
2020-04-23 10:57:24 +01:00
],
"login_authentication": "sms_auth",
2019-03-26 12:35:32 +00:00
},
_expected_status=302,
_expected_redirect=url_for(
"main.manage_users",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
),
)
mock_set_user_permissions.assert_called_with(
str(active_user_with_permissions["id"]),
2019-03-26 12:35:32 +00:00
SERVICE_ONE_ID,
permissions={
ServicePermission.SEND_MESSAGES,
ServicePermission.MANAGE_TEMPLATES,
ServicePermission.MANAGE_SERVICE,
},
folder_permissions=[],
)
mock_update_user_attribute.assert_called_with(
str(active_user_with_permissions["id"]), auth_type="sms_auth"
)
2021-06-30 15:29:02 +01:00
def test_edit_user_permissions_shows_authentication_for_email_auth_service(
client_request,
service_one,
mock_get_users_by_service,
mock_get_template_folders,
active_user_with_permissions,
):
2025-07-21 16:37:55 -07:00
service_one["permissions"].append(ServicePermission.EMAIL_AUTH)
2021-06-30 15:29:02 +01:00
page = client_request.get(
"main.edit_user_permissions",
2021-06-30 15:29:02 +01:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
2021-06-30 15:29:02 +01:00
)
radio_buttons = page.select("input[name=login_authentication]")
values = {button["value"] for button in radio_buttons}
assert values == {"sms_auth", "email_auth"}
2021-06-30 15:29:02 +01:00
assert not any(button.has_attr("disabled") for button in radio_buttons)
2016-02-19 15:02:13 +00:00
def test_should_show_page_for_inviting_user(
2019-03-26 12:35:32 +00:00
client_request,
mock_get_template_folders,
active_user_with_permissions,
2016-02-19 15:02:13 +00:00
):
client_request.login(active_user_with_permissions)
2019-03-26 12:35:32 +00:00
page = client_request.get(
"main.invite_user",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
)
2016-02-19 15:02:13 +00:00
assert "Invite a team member" in page.find("h1").text.strip()
assert not page.find("div", class_="checkboxes-nested")
def test_should_not_show_page_for_inviting_user_without_permissions(
client_request, mock_get_template_folders, active_user_empty_permissions
):
client_request.login(active_user_empty_permissions)
page = client_request.get(
"main.invite_user", service_id=SERVICE_ONE_ID, _expected_status=403
)
assert "not allowed to see this page" in page.h1.string.strip()
2020-06-08 10:58:15 +01:00
def test_should_show_page_for_inviting_user_with_email_prefilled(
client_request,
mocker,
service_one,
2020-06-08 10:58:15 +01:00
mock_get_template_folders,
fake_uuid,
2020-06-08 11:19:58 +01:00
active_user_with_permissions,
active_user_with_permission_to_other_service,
2023-07-12 12:09:44 -04:00
mock_get_organization_by_domain,
mock_get_invites_for_service,
2020-06-08 10:58:15 +01:00
):
2023-01-19 17:29:21 -05:00
client_request.login(active_user_with_permissions)
service_one["organization"] = ORGANISATION_ID
mocker.patch(
"app.models.user.user_api_client.get_user",
side_effect=[
active_user_with_permission_to_other_service,
],
)
2020-06-08 11:19:58 +01:00
page = client_request.get(
"main.invite_user",
2020-06-08 11:19:58 +01:00
service_id=SERVICE_ONE_ID,
user_id=fake_uuid,
# We have the users name in the H1 but dont want it duplicated
# in the page title
_test_page_title=False,
2020-06-08 11:19:58 +01:00
)
assert normalize_spaces(page.select_one("title").text).startswith(
"Invite a team member"
)
assert normalize_spaces(page.select_one("h1").text) == ("Invite Service Two User")
assert not page.select("input#email_address") or page.select("input[type=email]")
2020-06-08 11:19:58 +01:00
def test_should_show_page_if_prefilled_user_is_already_a_team_member(
mocker,
client_request,
mock_get_template_folders,
fake_uuid,
active_user_with_permissions,
active_caseworking_user,
2020-06-08 11:19:58 +01:00
):
client_request.login(active_user_with_permissions)
mocker.patch(
"app.models.user.user_api_client.get_user",
side_effect=[
active_caseworking_user,
],
)
2020-06-08 10:58:15 +01:00
page = client_request.get(
"main.invite_user",
2020-06-08 10:58:15 +01:00
service_id=SERVICE_ONE_ID,
user_id=fake_uuid,
)
assert normalize_spaces(page.select_one("title").text).startswith(
"This person is already a team member"
2020-06-08 11:19:58 +01:00
)
assert normalize_spaces(page.select_one("h1").text) == (
"This person is already a team member"
2020-06-08 10:58:15 +01:00
)
assert normalize_spaces(page.select_one("main p").text) == (
"Test User is already member of service one."
2020-06-08 10:58:15 +01:00
)
2020-06-08 11:19:58 +01:00
assert not page.select("form")
2020-06-08 10:58:15 +01:00
def test_should_show_page_if_prefilled_user_is_already_invited(
mocker,
client_request,
mock_get_template_folders,
fake_uuid,
active_user_with_permission_to_other_service,
mock_get_invites_for_service,
platform_admin_user,
):
active_user_with_permission_to_other_service["email_address"] = (
"user_1@testnotify.gsa.gov"
)
client_request.login(platform_admin_user)
mocker.patch(
"app.models.user.user_api_client.get_user",
side_effect=[
active_user_with_permission_to_other_service,
],
)
page = client_request.get(
"main.invite_user",
service_id=SERVICE_ONE_ID,
user_id=fake_uuid,
)
assert normalize_spaces(page.select_one("title").text).startswith(
"This person has already received an invite"
)
assert normalize_spaces(page.select_one("h1").text) == (
"This person has already received an invite"
)
assert normalize_spaces(page.select_one("main .usa-body").text) == (
"Service Two User has not accepted their invitation to "
"service one yet. You do not need to do anything."
)
assert not page.select("form")
2023-07-12 12:09:44 -04:00
def test_should_403_if_trying_to_prefill_email_address_for_user_with_no_organization(
mocker,
client_request,
service_one,
mock_get_template_folders,
fake_uuid,
active_user_with_permissions,
active_user_with_permission_to_other_service,
mock_get_invites_for_service,
2023-07-12 12:09:44 -04:00
mock_get_no_organization_by_domain,
):
service_one["organization"] = ORGANISATION_ID
2023-01-19 17:29:21 -05:00
client_request.login(active_user_with_permissions)
mocker.patch(
"app.models.user.user_api_client.get_user",
side_effect=[
active_user_with_permission_to_other_service,
],
)
client_request.get(
"main.invite_user",
service_id=SERVICE_ONE_ID,
user_id=fake_uuid,
_expected_status=403,
)
2023-07-12 12:09:44 -04:00
def test_should_403_if_trying_to_prefill_email_address_for_user_from_other_organization(
mocker,
client_request,
service_one,
mock_get_template_folders,
fake_uuid,
active_user_with_permissions,
active_user_with_permission_to_other_service,
mock_get_invites_for_service,
2023-07-12 12:09:44 -04:00
mock_get_organization_by_domain,
):
service_one["organization"] = ORGANISATION_TWO_ID
2023-01-19 17:29:21 -05:00
client_request.login(active_user_with_permissions)
mocker.patch(
"app.models.user.user_api_client.get_user",
side_effect=[
active_user_with_permission_to_other_service,
],
)
client_request.get(
"main.invite_user",
service_id=SERVICE_ONE_ID,
user_id=fake_uuid,
_expected_status=403,
)
def test_should_show_folder_permission_form_if_service_has_folder_permissions_enabled(
client_request, mocker, mock_get_template_folders, service_one, platform_admin_user
):
client_request.login(platform_admin_user)
mock_get_template_folders.return_value = [
{
"id": "folder-id-1",
"name": "folder_one",
"parent_id": None,
"users_with_permission": [],
},
{
"id": "folder-id-2",
"name": "folder_two",
"parent_id": None,
"users_with_permission": [],
},
{
"id": "folder-id-3",
"name": "folder_three",
"parent_id": "folder-id-1",
"users_with_permission": [],
},
]
2019-03-26 12:35:32 +00:00
page = client_request.get(
"main.invite_user",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
)
assert "Invite a team member" in page.find("h1").text.strip()
folder_checkboxes = page.find("div", class_="selection-wrapper").find_all("li")
assert len(folder_checkboxes) == 3
2016-02-19 15:02:13 +00:00
2016-02-29 17:35:21 +00:00
@pytest.mark.parametrize(
2023-09-11 16:51:30 -04:00
("email_address", "gov_user"),
[("test@example.gsa.gov", True), ("test@example.com", False)],
)
2016-02-29 17:35:21 +00:00
def test_invite_user(
2019-03-26 12:35:32 +00:00
client_request,
platform_admin_user,
2017-02-03 10:42:01 +00:00
mocker,
sample_invite,
email_address,
gov_user,
mock_get_template_folders,
2023-07-12 12:09:44 -04:00
mock_get_organizations,
2016-02-29 17:35:21 +00:00
):
sample_invite["email_address"] = email_address
2016-02-29 17:35:21 +00:00
2017-02-03 12:07:21 +00:00
assert is_gov_user(email_address) == gov_user
mocker.patch(
"app.models.user.InvitedUsers.client_method", return_value=[sample_invite]
)
mocker.patch(
"app.models.user.Users.client_method",
return_value=[platform_admin_user],
)
mocker.patch("app.invite_api_client.create_invite", return_value=sample_invite)
client_request.login(platform_admin_user)
2019-03-26 12:35:32 +00:00
page = client_request.post(
"main.invite_user",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
_data={
"email_address": email_address,
"permissions_field": [
ServicePermission.VIEW_ACTIVITY,
ServicePermission.SEND_MESSAGES,
ServicePermission.MANAGE_TEMPLATES,
ServicePermission.MANAGE_SERVICE,
],
},
2019-03-26 12:35:32 +00:00
_follow_redirects=True,
2017-02-03 12:07:21 +00:00
)
assert page.h1.string.strip() == "Team members"
flash_banner = page.find("div", class_="banner-default-with-tick").string.strip()
2021-03-04 16:54:41 +00:00
assert flash_banner == f"Invite sent to {email_address}"
expected_permissions = {
ServicePermission.MANAGE_SERVICE,
ServicePermission.MANAGE_TEMPLATES,
ServicePermission.SEND_MESSAGES,
ServicePermission.VIEW_ACTIVITY,
}
app.invite_api_client.create_invite.assert_called_once_with(
sample_invite["from_user"],
sample_invite["service"],
email_address,
expected_permissions,
"sms_auth",
[],
)
2020-06-08 10:58:15 +01:00
def test_invite_user_when_email_address_is_prefilled(
client_request,
service_one,
platform_admin_user,
2020-06-08 11:19:58 +01:00
active_user_with_permission_to_other_service,
2020-06-08 10:58:15 +01:00
fake_uuid,
mocker,
sample_invite,
mock_get_template_folders,
mock_get_invites_for_service,
2023-07-12 12:09:44 -04:00
mock_get_organization_by_domain,
2020-06-08 10:58:15 +01:00
):
service_one["organization"] = ORGANISATION_ID
client_request.login(platform_admin_user)
mocker.patch(
"app.models.user.user_api_client.get_user",
side_effect=[
active_user_with_permission_to_other_service,
],
)
mocker.patch("app.invite_api_client.create_invite", return_value=sample_invite)
2020-06-08 10:58:15 +01:00
client_request.post(
"main.invite_user",
2020-06-08 10:58:15 +01:00
service_id=SERVICE_ONE_ID,
user_id=fake_uuid,
_data={
# No posted email address
"permissions_field": [
ServicePermission.SEND_MESSAGES,
2020-06-08 10:58:15 +01:00
],
},
)
app.invite_api_client.create_invite.assert_called_once_with(
platform_admin_user["id"],
2020-06-08 10:58:15 +01:00
SERVICE_ONE_ID,
active_user_with_permission_to_other_service["email_address"],
{"send_messages"},
"sms_auth",
2020-06-08 10:58:15 +01:00
[],
)
@pytest.mark.parametrize("auth_type", [("sms_auth"), ("email_auth")])
@pytest.mark.parametrize(
2023-09-11 16:51:30 -04:00
("email_address", "gov_user"),
[("test@example.gsa.gov", True), ("test@example.com", False)],
)
def test_invite_user_with_email_auth_service(
2019-03-26 12:35:32 +00:00
client_request,
service_one,
platform_admin_user,
sample_invite,
email_address,
gov_user,
mocker,
auth_type,
2023-07-12 12:09:44 -04:00
mock_get_organizations,
mock_get_template_folders,
):
2025-07-21 16:37:55 -07:00
service_one["permissions"].append(ServicePermission.EMAIL_AUTH)
sample_invite["email_address"] = "test@example.gsa.gov"
assert is_gov_user(email_address) is gov_user
mocker.patch(
"app.models.user.InvitedUsers.client_method", return_value=[sample_invite]
)
mocker.patch(
"app.models.user.Users.client_method",
return_value=[platform_admin_user],
)
mocker.patch("app.invite_api_client.create_invite", return_value=sample_invite)
client_request.login(platform_admin_user)
2019-03-26 12:35:32 +00:00
page = client_request.post(
"main.invite_user",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
_data={
"email_address": email_address,
"permissions_field": [
ServicePermission.VIEW_ACTIVITY,
ServicePermission.SEND_MESSAGES,
ServicePermission.MANAGE_TEMPLATES,
ServicePermission.MANAGE_SERVICE,
2020-04-23 10:57:24 +01:00
],
"login_authentication": auth_type,
2019-03-26 12:35:32 +00:00
},
_follow_redirects=True,
_expected_status=200,
)
assert page.h1.string.strip() == "Team members"
flash_banner = page.find("div", class_="banner-default-with-tick").string.strip()
assert flash_banner == "Invite sent to test@example.gsa.gov"
expected_permissions = {
ServicePermission.MANAGE_SERVICE,
ServicePermission.MANAGE_TEMPLATES,
ServicePermission.SEND_MESSAGES,
ServicePermission.VIEW_ACTIVITY,
}
app.invite_api_client.create_invite.assert_called_once_with(
sample_invite["from_user"],
sample_invite["service"],
email_address,
expected_permissions,
auth_type,
[],
)
2023-12-21 10:58:32 -05:00
def test_resend_expired_invitation(
client_request,
mock_get_invites_for_service,
expired_invite,
active_user_with_permissions,
mock_get_users_by_service,
mock_get_template_folders,
mocker,
):
2023-12-07 07:52:40 -05:00
mock_resend = mocker.patch("app.invite_api_client.resend_invite")
2023-12-21 10:58:32 -05:00
mocker.patch(
"app.invite_api_client.get_invited_user_for_service",
return_value=expired_invite,
)
2023-12-07 07:52:40 -05:00
page = client_request.get(
"main.resend_invite",
service_id=SERVICE_ONE_ID,
invited_user_id=expired_invite["id"],
_follow_redirects=True,
)
assert normalize_spaces(page.h1.text) == "Team members"
assert mock_resend.called
2023-12-21 10:58:32 -05:00
called_args = set(mock_resend.call_args.args) | set(
mock_resend.call_args.kwargs.values()
)
assert SERVICE_ONE_ID in called_args
assert expired_invite["id"] in called_args
2023-12-07 07:52:40 -05:00
2017-02-03 10:42:01 +00:00
def test_cancel_invited_user_cancels_user_invitations(
client_request,
mock_get_invites_for_service,
sample_invite,
2017-02-03 10:42:01 +00:00
active_user_with_permissions,
mock_get_users_by_service,
mock_get_template_folders,
2017-02-03 10:42:01 +00:00
mocker,
):
mock_cancel = mocker.patch("app.invite_api_client.cancel_invited_user")
mocker.patch(
2023-12-21 10:58:32 -05:00
"app.invite_api_client.get_invited_user_for_service",
return_value=sample_invite,
)
page = client_request.get(
"main.cancel_invited_user",
service_id=SERVICE_ONE_ID,
invited_user_id=sample_invite["id"],
_follow_redirects=True,
)
assert normalize_spaces(page.h1.text) == "Team members"
flash_banner = normalize_spaces(
page.find("div", class_="banner-default-with-tick").text
)
assert flash_banner == f"Invitation cancelled for {sample_invite['email_address']}"
mock_cancel.assert_called_once_with(
service_id=SERVICE_ONE_ID,
invited_user_id=sample_invite["id"],
)
2025-09-17 12:22:09 -07:00
@pytest.mark.usefixtures(
"client_request",
"mock_get_invites_for_service",
"mocker",
)
def test_cancel_invited_user_doesnt_work_if_user_not_invited_to_this_service(
client_request,
2025-09-17 12:22:09 -07:00
mock_get_invites_for_service,
mocker,
):
2025-09-17 12:22:09 -07:00
@given(fuzzed_uuid=st.uuids())
def inner(fuzzed_uuid):
mock_cancel = mocker.patch("app.invite_api_client.cancel_invited_user")
client_request.get(
"main.cancel_invited_user",
service_id=SERVICE_ONE_ID,
invited_user_id=fuzzed_uuid,
_expected_status=404,
)
assert mock_cancel.called is False
inner()
@pytest.mark.parametrize(
2023-09-11 16:51:30 -04:00
("invite_status", "expected_text"),
[
(
"pending",
(
2025-05-29 13:02:48 -07:00
"invited_user@test.gsa.gov "
2025-05-14 11:07:12 -04:00
"invited_user@test.gsa.gov (invited) "
"Permissions "
"Can See dashboard "
"Can Send messages "
"Can Manage settings, team and usage "
"Cancel invitation for invited_user@test.gsa.gov"
),
),
2024-04-22 16:09:25 -06:00
# Test case removed due to the removal of canceled users from the dashboard
# (
# "cancelled",
# (
# "invited_user@test.gsa.gov(cancelled invite) "
# "Permissions"
# # all permissions are greyed out
# ),
# ),
],
)
2017-02-03 10:42:01 +00:00
def test_manage_users_shows_invited_user(
client_request,
2017-02-03 10:42:01 +00:00
mocker,
active_user_with_permissions,
mock_get_template_folders,
2017-02-03 10:42:01 +00:00
sample_invite,
invite_status,
expected_text,
2017-02-03 10:42:01 +00:00
):
sample_invite["status"] = invite_status
mocker.patch(
"app.models.user.InvitedUsers.client_method", return_value=[sample_invite]
)
mocker.patch(
"app.models.user.Users.client_method",
return_value=[active_user_with_permissions],
)
page = client_request.get("main.manage_users", service_id=SERVICE_ONE_ID)
assert page.h1.string.strip() == "Team members"
assert normalize_spaces(page.select(".user-list-item")[0].text) == expected_text
2017-02-03 10:42:01 +00:00
def test_manage_users_does_not_show_accepted_invite(
client_request,
2017-02-03 10:42:01 +00:00
mocker,
active_user_with_permissions,
sample_invite,
mock_get_template_folders,
2017-02-03 10:42:01 +00:00
):
invited_user_id = uuid.uuid4()
sample_invite["id"] = invited_user_id
sample_invite["status"] = "accepted"
mocker.patch(
"app.models.user.InvitedUsers.client_method", return_value=[sample_invite]
)
mocker.patch(
"app.models.user.Users.client_method",
return_value=[active_user_with_permissions],
)
page = client_request.get("main.manage_users", service_id=SERVICE_ONE_ID)
assert page.h1.string.strip() == "Team members"
user_lists = page.find_all("div", {"class": "user-list"})
2017-02-03 12:07:21 +00:00
assert len(user_lists) == 1
assert not page.find(text="invited_user@test.gsa.gov")
def test_user_cant_invite_themselves(
2019-03-26 12:35:32 +00:00
client_request,
2017-02-03 10:42:01 +00:00
mocker,
active_user_with_permissions,
mock_create_invite,
mock_get_template_folders,
):
2019-03-26 12:35:32 +00:00
page = client_request.post(
"main.invite_user",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
_data={
"email_address": active_user_with_permissions["email_address"],
"permissions_field": [
ServicePermission.SEND_MESSAGES,
ServicePermission.MANAGE_SERVICE,
],
2019-03-26 12:35:32 +00:00
},
_follow_redirects=True,
_expected_status=200,
2017-02-03 12:07:21 +00:00
)
assert page.h1.string.strip() == "Invite a team member"
form_error = page.find("span", class_="usa-error-message").text.strip()
assert form_error == "Error: You cannot send an invitation to yourself"
2017-02-03 12:07:21 +00:00
assert not mock_create_invite.called
2023-11-08 07:51:57 -08:00
def test_user_cant_invite_themselves_platform_admin(
client_request,
mocker,
mock_create_invite,
mock_get_template_folders,
):
platform_admin = create_platform_admin_user()
client_request.login(platform_admin)
page = client_request.post(
"main.invite_user",
service_id=SERVICE_ONE_ID,
_follow_redirects=True,
_expected_status=200,
)
assert "Invite a team member" in page.h1.string.strip()
2017-02-03 10:42:01 +00:00
def test_no_permission_manage_users_page(
client_request,
2017-02-03 10:42:01 +00:00
service_one,
mock_get_users_by_service,
mock_get_invites_for_service,
mock_get_template_folders,
2017-02-03 10:42:01 +00:00
api_user_active,
mocker,
):
resp_text = client_request.get("main.manage_users", service_id=service_one["id"])
assert url_for(".invite_user", service_id=service_one["id"]) not in resp_text
2017-02-03 12:07:21 +00:00
assert "Edit permission" not in resp_text
assert "Team members" not in resp_text
2016-03-23 10:46:31 +00:00
@pytest.mark.parametrize(
2023-09-11 16:51:30 -04:00
("folders_user_can_see", "expected_message"),
[
(3, "Can see all folders"),
(2, "Can see 2 folders"),
(1, "Can see 1 folder"),
(0, "Cannot see any folders"),
],
)
def test_manage_user_page_shows_how_many_folders_user_can_view(
client_request,
service_one,
mock_get_template_folders,
mock_get_users_by_service,
mock_get_invites_for_service,
api_user_active,
folders_user_can_see,
expected_message,
):
2025-07-21 16:37:55 -07:00
service_one["permissions"] = [ServicePermission.EDIT_FOLDER_PERMISSIONS]
mock_get_template_folders.return_value = [
{
"id": "folder-id-1",
"name": "f1",
"parent_id": None,
"users_with_permission": [],
},
{
"id": "folder-id-2",
"name": "f2",
"parent_id": None,
"users_with_permission": [],
},
{
"id": "folder-id-3",
"name": "f3",
"parent_id": None,
"users_with_permission": [],
},
]
for i in range(folders_user_can_see):
mock_get_template_folders.return_value[i]["users_with_permission"].append(
api_user_active["id"]
)
page = client_request.get("main.manage_users", service_id=service_one["id"])
2025-10-06 09:38:54 -04:00
user_div = page.select_one("h2[title='notify@example.gov']").parent
assert user_div.select_one(".tick-cross-list-hint").text.strip() == expected_message
def test_manage_user_page_doesnt_show_folder_hint_if_service_has_no_folders(
client_request,
service_one,
mock_get_template_folders,
mock_get_users_by_service,
mock_get_invites_for_service,
api_user_active,
):
2025-07-21 16:37:55 -07:00
service_one["permissions"] = [ServicePermission.EDIT_FOLDER_PERMISSIONS]
mock_get_template_folders.return_value = []
page = client_request.get("main.manage_users", service_id=service_one["id"])
2025-10-06 09:38:54 -04:00
user_div = page.select_one("h2[title='notify@example.gov']").parent
assert user_div.find(".tick-cross-list-hint:last-child") is None
def test_manage_user_page_doesnt_show_folder_hint_if_service_cant_edit_folder_permissions(
client_request,
service_one,
mock_get_template_folders,
mock_get_users_by_service,
mock_get_invites_for_service,
api_user_active,
):
service_one["permissions"] = []
mock_get_template_folders.return_value = [
{
"id": "folder-id-1",
"name": "f1",
"parent_id": None,
"users_with_permission": [api_user_active["id"]],
},
]
page = client_request.get("main.manage_users", service_id=service_one["id"])
2025-10-06 09:38:54 -04:00
user_div = page.select_one("h2[title='notify@example.gov']").parent
assert user_div.find(".tick-cross-list-hint:last-child") is None
2019-03-26 15:51:44 +00:00
def test_remove_user_from_service(
client_request,
2017-02-03 10:42:01 +00:00
active_user_with_permissions,
2020-03-10 13:18:32 +00:00
api_user_active,
2017-02-03 10:42:01 +00:00
service_one,
mock_remove_user_from_service,
mocker,
2017-02-03 10:42:01 +00:00
):
mock_event_handler = mocker.patch(
"app.main.views.manage_users.create_remove_user_from_service_event"
)
2020-03-10 13:18:32 +00:00
client_request.post(
"main.remove_user_from_service",
service_id=service_one["id"],
user_id=active_user_with_permissions["id"],
_expected_redirect=url_for("main.manage_users", service_id=service_one["id"]),
)
mock_remove_user_from_service.assert_called_once_with(
service_one["id"], str(active_user_with_permissions["id"])
)
2020-03-10 13:18:32 +00:00
mock_event_handler.assert_called_once_with(
user_id=active_user_with_permissions["id"],
removed_by_id=api_user_active["id"],
service_id=service_one["id"],
2020-03-10 13:18:32 +00:00
)
def test_can_invite_user_as_platform_admin(
2019-03-26 12:35:32 +00:00
client_request,
2017-02-03 10:42:01 +00:00
service_one,
platform_admin_user,
active_user_with_permissions,
mock_get_invites_for_service,
mock_get_template_folders,
2017-02-03 10:42:01 +00:00
mocker,
):
mocker.patch(
"app.models.user.Users.client_method",
return_value=[active_user_with_permissions],
)
2019-03-26 12:35:32 +00:00
page = client_request.get(
"main.manage_users",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
)
assert url_for(".invite_user", service_id=service_one["id"]) in str(page)
def test_edit_user_email_page(
client_request,
active_user_with_permissions,
service_one,
mock_get_users_by_service,
mocker,
):
user = active_user_with_permissions
mocker.patch("app.user_api_client.get_user", return_value=user)
page = client_request.get(
"main.edit_user_email", service_id=service_one["id"], user_id=sample_uuid()
)
assert page.find("h1").text == "Change team members email address"
assert page.select("p[id=user_name]")[
0
].text == "This will change the email address for {}.".format(user["name"])
assert page.select("input[type=email]")[0].attrs["value"] == user["email_address"]
assert normalize_spaces(page.select("main button[type=submit]")[0].text) == "Save"
2019-02-19 18:01:01 +00:00
def test_edit_user_email_page_404_for_non_team_member(
client_request,
mock_get_users_by_service,
):
client_request.get(
"main.edit_user_email",
service_id=SERVICE_ONE_ID,
user_id=USER_ONE_ID,
_expected_status=404,
)
2019-02-19 18:01:01 +00:00
def test_edit_user_email_redirects_to_confirmation(
2019-03-26 12:35:32 +00:00
client_request,
2019-02-19 18:01:01 +00:00
active_user_with_permissions,
mock_get_users_by_service,
mock_get_user_by_email_not_found,
2019-02-19 18:01:01 +00:00
):
2019-03-26 12:35:32 +00:00
client_request.post(
"main.edit_user_email",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
2019-03-26 12:35:32 +00:00
_expected_status=302,
_expected_redirect=url_for(
"main.confirm_edit_user_email",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
2019-03-26 12:35:32 +00:00
),
2019-02-19 18:01:01 +00:00
)
with client_request.session_transaction() as session:
assert (
session[
"team_member_email_change-{}".format(active_user_with_permissions["id"])
]
== "test@user.gsa.gov"
)
2019-02-20 11:50:34 +00:00
def test_edit_user_email_without_changing_goes_back_to_team_members(
client_request,
active_user_with_permissions,
mock_get_user_by_email,
mock_get_users_by_service,
mock_update_user_attribute,
):
client_request.post(
"main.edit_user_email",
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
_data={"email_address": active_user_with_permissions["email_address"]},
_expected_status=302,
_expected_redirect=url_for(
"main.manage_users",
service_id=SERVICE_ONE_ID,
),
)
assert mock_update_user_attribute.called is False
@pytest.mark.parametrize("original_email_address", ["test@gsa.gov", "test@example.com"])
def test_edit_user_email_can_change_any_email_address_to_a_gov_email_address(
client_request,
active_user_with_permissions,
mock_get_user_by_email_not_found,
mock_get_users_by_service,
mock_update_user_attribute,
2023-07-12 12:09:44 -04:00
mock_get_organizations,
original_email_address,
):
active_user_with_permissions["email_address"] = original_email_address
client_request.post(
"main.edit_user_email",
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
_data={"email_address": "new-email-address@gsa.gov"},
_expected_status=302,
_expected_redirect=url_for(
"main.confirm_edit_user_email",
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
),
)
def test_edit_user_email_can_change_a_non_gov_email_address_to_another_non_gov_email_address(
client_request,
active_user_with_permissions,
mock_get_user_by_email_not_found,
mock_get_users_by_service,
mock_update_user_attribute,
2023-07-12 12:09:44 -04:00
mock_get_organizations,
):
active_user_with_permissions["email_address"] = "old@example.com"
client_request.post(
"main.edit_user_email",
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
_data={"email_address": "new@example.com"},
_expected_status=302,
_expected_redirect=url_for(
"main.confirm_edit_user_email",
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
),
)
def test_edit_user_email_cannot_change_a_gov_email_address_to_a_non_gov_email_address(
client_request,
active_user_with_permissions,
mock_get_user_by_email_not_found,
mock_get_users_by_service,
mock_update_user_attribute,
2023-07-12 12:09:44 -04:00
mock_get_organizations,
):
page = client_request.post(
"main.edit_user_email",
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
_data={"email_address": "new_email@example.com"},
_expected_status=200,
)
assert (
"Enter a public sector email address"
in page.select_one(".usa-error-message").text
)
with client_request.session_transaction() as session:
assert (
"team_member_email_change-{}".format(active_user_with_permissions["id"])
not in session
)
2019-02-20 11:50:34 +00:00
def test_confirm_edit_user_email_page(
2019-03-26 12:35:32 +00:00
client_request,
2019-02-20 11:50:34 +00:00
active_user_with_permissions,
mock_get_users_by_service,
2019-02-20 11:50:34 +00:00
mock_get_user,
):
new_email = "new_email@gsa.gov"
2019-03-26 12:35:32 +00:00
with client_request.session_transaction() as session:
session[
"team_member_email_change-{}".format(active_user_with_permissions["id"])
] = new_email
2019-02-20 11:50:34 +00:00
2019-03-26 12:35:32 +00:00
page = client_request.get(
"main.confirm_edit_user_email",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
2019-03-26 12:35:32 +00:00
)
assert "Confirm change of email address" in page.text
for text in [
"New email address:",
new_email,
"We will send {} an email to tell them about the change.".format(
active_user_with_permissions["name"]
),
]:
2019-03-26 12:35:32 +00:00
assert text in page.text
assert "Confirm" in page.text
2019-02-20 11:50:34 +00:00
def test_confirm_edit_user_email_page_redirects_if_session_empty(
2019-03-26 12:35:32 +00:00
client_request,
mock_get_users_by_service,
2019-03-26 12:35:32 +00:00
active_user_with_permissions,
):
2019-03-26 12:35:32 +00:00
page = client_request.get(
"main.confirm_edit_user_email",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
2019-03-26 12:35:32 +00:00
_follow_redirects=True,
)
assert "Confirm change of email address" not in page.text
def test_confirm_edit_user_email_page_404s_for_non_team_member(
client_request,
mock_get_users_by_service,
):
client_request.get(
"main.confirm_edit_user_email",
service_id=SERVICE_ONE_ID,
user_id=USER_ONE_ID,
_expected_status=404,
)
2019-02-20 11:50:34 +00:00
def test_confirm_edit_user_email_changes_user_email(
2019-03-26 12:35:32 +00:00
client_request,
2019-02-20 11:50:34 +00:00
active_user_with_permissions,
api_user_active,
2019-02-20 11:50:34 +00:00
service_one,
mocker,
mock_update_user_attribute,
2019-02-20 11:50:34 +00:00
):
# We want active_user_with_permissions (the current user) to update the email address for api_user_active
# By default both users would have the same id, so we change the id of api_user_active
api_user_active["id"] = str(uuid.uuid4())
mocker.patch(
"app.models.user.Users.client_method",
return_value=[api_user_active, active_user_with_permissions],
)
# get_user gets called twice - first to check if current user can see the page, then to see if the team member
# whose email address we're changing belongs to the service
mocker.patch(
"app.user_api_client.get_user",
side_effect=[active_user_with_permissions, api_user_active],
)
mock_event_handler = mocker.patch(
"app.main.views.manage_users.create_email_change_event"
)
new_email = "new_email@gsa.gov"
2019-03-26 12:35:32 +00:00
with client_request.session_transaction() as session:
session["team_member_email_change-{}".format(api_user_active["id"])] = new_email
2019-03-26 12:35:32 +00:00
client_request.post(
"main.confirm_edit_user_email",
service_id=service_one["id"],
user_id=api_user_active["id"],
2019-03-26 12:35:32 +00:00
_expected_status=302,
_expected_redirect=url_for(
"main.manage_users",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
),
)
mock_update_user_attribute.assert_called_once_with(
api_user_active["id"],
email_address=new_email,
updated_by=active_user_with_permissions["id"],
)
mock_event_handler.assert_called_once_with(
user_id=api_user_active["id"],
updated_by_id=active_user_with_permissions["id"],
original_email_address=api_user_active["email_address"],
new_email_address=new_email,
)
def test_confirm_edit_user_email_doesnt_change_user_email_for_non_team_member(
client_request,
mock_get_users_by_service,
):
with client_request.session_transaction() as session:
session["team_member_email_change"] = "new_email@gsa.gov"
client_request.post(
"main.confirm_edit_user_email",
service_id=SERVICE_ONE_ID,
user_id=USER_ONE_ID,
_expected_status=404,
)
2019-02-22 11:31:35 +00:00
def test_edit_user_permissions_page_displays_redacted_mobile_number_and_change_link(
client_request,
active_user_with_permissions,
mock_get_users_by_service,
mock_get_template_folders,
service_one,
mocker,
):
page = client_request.get(
"main.edit_user_permissions",
service_id=service_one["id"],
user_id=active_user_with_permissions["id"],
)
assert active_user_with_permissions["name"] in page.find("h1").text
mobile_number_paragraph = page.select("p[id=user_mobile_number]")[0]
assert "202-8 • • • • 303" in mobile_number_paragraph.text
2019-02-22 11:31:35 +00:00
change_link = mobile_number_paragraph.findChild()
assert change_link.attrs[
"href"
] == "/services/{}/users/{}/edit-mobile-number".format(
service_one["id"], active_user_with_permissions["id"]
)
2019-03-26 15:51:44 +00:00
def test_edit_user_permissions_with_delete_query_shows_banner(
client_request,
active_user_with_permissions,
mock_get_users_by_service,
mock_get_template_folders,
service_one,
2019-03-26 15:51:44 +00:00
):
page = client_request.get(
"main.edit_user_permissions",
service_id=service_one["id"],
user_id=active_user_with_permissions["id"],
delete=1,
2019-03-26 15:51:44 +00:00
)
banner = page.find("div", class_="banner-dangerous")
2019-03-26 15:51:44 +00:00
assert banner.contents[0].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"],
user_id=active_user_with_permissions["id"],
2019-03-26 15:51:44 +00:00
)
2019-02-22 11:31:35 +00:00
def test_edit_user_mobile_number_page(
client_request,
active_user_with_permissions,
mock_get_users_by_service,
2019-02-22 11:31:35 +00:00
service_one,
mocker,
2019-02-22 11:31:35 +00:00
):
page = client_request.get(
"main.edit_user_mobile_number",
service_id=service_one["id"],
user_id=active_user_with_permissions["id"],
2019-02-22 11:31:35 +00:00
)
assert page.find("h1").text == "Change team members mobile number"
assert page.select("p[id=user_name]")[0].text == (
"This will change the mobile number for {}."
).format(active_user_with_permissions["name"])
assert page.select("input[name=mobile_number]")[0].attrs["value"] == "202-8••••303"
assert normalize_spaces(page.select("main button[type=submit]")[0].text) == "Save"
2019-02-22 11:31:35 +00:00
2019-02-22 12:28:18 +00:00
def test_edit_user_mobile_number_redirects_to_confirmation(
2019-03-26 12:35:32 +00:00
client_request,
2019-02-22 12:28:18 +00:00
active_user_with_permissions,
mock_get_users_by_service,
2019-02-22 12:28:18 +00:00
):
2019-03-26 12:35:32 +00:00
client_request.post(
"main.edit_user_mobile_number",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
_data={"mobile_number": "2028675309"},
2019-03-26 12:35:32 +00:00
_expected_status=302,
_expected_redirect=url_for(
"main.confirm_edit_user_mobile_number",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
2019-03-26 12:35:32 +00:00
),
2019-02-22 12:28:18 +00:00
)
def test_edit_user_mobile_number_redirects_to_manage_users_if_number_not_changed(
2019-03-26 12:35:32 +00:00
client_request,
active_user_with_permissions,
mock_get_users_by_service,
service_one,
mocker,
mock_get_user,
):
2019-03-26 12:35:32 +00:00
client_request.post(
"main.edit_user_mobile_number",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
_data={"mobile_number": "202-8••••303"},
2019-03-26 12:35:32 +00:00
_expected_status=302,
_expected_redirect=url_for(
"main.manage_users",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
),
)
def test_confirm_edit_user_mobile_number_page(
2019-03-26 12:35:32 +00:00
client_request,
active_user_with_permissions,
mock_get_users_by_service,
service_one,
mocker,
mock_get_user,
):
new_number = "2028675309"
2019-03-26 12:35:32 +00:00
with client_request.session_transaction() as session:
session["team_member_mobile_change"] = new_number
2019-03-26 12:35:32 +00:00
page = client_request.get(
"main.confirm_edit_user_mobile_number",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
2019-03-26 12:35:32 +00:00
)
assert "Confirm change of mobile number" in page.text
for text in [
"New mobile number:",
new_number,
"We will send {} a text message to tell them about the change.".format(
active_user_with_permissions["name"]
),
]:
2019-03-26 12:35:32 +00:00
assert text in page.text
assert "Confirm" in page.text
def test_confirm_edit_user_mobile_number_page_redirects_if_session_empty(
2019-03-26 12:35:32 +00:00
client_request,
active_user_with_permissions,
mock_get_users_by_service,
service_one,
mocker,
mock_get_user,
):
2019-03-26 12:35:32 +00:00
page = client_request.get(
"main.confirm_edit_user_mobile_number",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=active_user_with_permissions["id"],
2019-03-26 12:35:32 +00:00
_expected_status=302,
)
assert "Confirm change of mobile number" not in page.text
def test_confirm_edit_user_mobile_number_changes_user_mobile_number(
2019-03-26 12:35:32 +00:00
client_request,
active_user_with_permissions,
api_user_active,
service_one,
mocker,
mock_update_user_attribute,
):
# We want active_user_with_permissions (the current user) to update the mobile number for api_user_active
# By default both users would have the same id, so we change the id of api_user_active
api_user_active["id"] = str(uuid.uuid4())
mocker.patch(
"app.models.user.Users.client_method",
return_value=[api_user_active, active_user_with_permissions],
)
# get_user gets called twice - first to check if current user can see the page, then to see if the team member
# whose mobile number we're changing belongs to the service
mocker.patch(
"app.user_api_client.get_user",
side_effect=[active_user_with_permissions, api_user_active],
)
mock_event_handler = mocker.patch(
"app.main.views.manage_users.create_mobile_number_change_event"
)
new_number = "2028675309"
2019-03-26 12:35:32 +00:00
with client_request.session_transaction() as session:
session["team_member_mobile_change"] = new_number
2019-03-26 12:35:32 +00:00
client_request.post(
"main.confirm_edit_user_mobile_number",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
user_id=api_user_active["id"],
2019-03-26 12:35:32 +00:00
_expected_status=302,
_expected_redirect=url_for(
"main.manage_users",
2019-03-26 12:35:32 +00:00
service_id=SERVICE_ONE_ID,
),
)
mock_update_user_attribute.assert_called_once_with(
api_user_active["id"],
mobile_number=new_number,
updated_by=active_user_with_permissions["id"],
)
mock_event_handler.assert_called_once_with(
user_id=api_user_active["id"],
updated_by_id=active_user_with_permissions["id"],
original_mobile_number=api_user_active["mobile_number"],
new_mobile_number=new_number,
)
def test_confirm_edit_user_mobile_number_doesnt_change_user_mobile_for_non_team_member(
client_request,
mock_get_users_by_service,
):
with client_request.session_transaction() as session:
session["team_member_mobile_change"] = "2028675309"
client_request.post(
"main.confirm_edit_user_mobile_number",
service_id=SERVICE_ONE_ID,
user_id=USER_ONE_ID,
_expected_status=404,
)