|
27 | 27 | UserForAdminGet, |
28 | 28 | UserGet, |
29 | 29 | ) |
| 30 | +from models_library.products import ProductName |
30 | 31 | from psycopg2 import OperationalError |
31 | 32 | from pydantic import TypeAdapter |
32 | 33 | from pytest_simcore.helpers.assert_checks import assert_status |
|
41 | 42 | switch_client_session_to, |
42 | 43 | ) |
43 | 44 | from servicelib.aiohttp import status |
44 | | -from servicelib.rest_constants import RESPONSE_MODEL_POLICY |
| 45 | +from servicelib.rest_constants import RESPONSE_MODEL_POLICY, X_PRODUCT_NAME_HEADER |
45 | 46 | from simcore_service_webserver.users._common.schemas import ( |
46 | 47 | MAX_BYTES_SIZE_EXTRAS, |
47 | 48 | PreRegisteredUserGet, |
@@ -919,3 +920,124 @@ def test_preuserprofile_pre_given_names( |
919 | 920 | print(pre_user_profile.model_dump_json(indent=1)) |
920 | 921 | assert pre_user_profile.first_name in ["Pedro-Luis", "Pedro Luis"] |
921 | 922 | assert pre_user_profile.first_name == pre_user_profile.last_name |
| 923 | + |
| 924 | + |
| 925 | +@pytest.mark.parametrize("user_role", [UserRole.PRODUCT_OWNER]) |
| 926 | +async def test_pending_users_management( |
| 927 | + client: TestClient, |
| 928 | + logged_user: UserInfoDict, |
| 929 | + account_request_form: dict[str, Any], |
| 930 | + faker: Faker, |
| 931 | + product_name: ProductName, |
| 932 | +): |
| 933 | + """Test the management of pending users: |
| 934 | + - list pending users |
| 935 | + - approve user account |
| 936 | + - reject user account |
| 937 | + - resend confirmation email |
| 938 | + """ |
| 939 | + assert client.app |
| 940 | + |
| 941 | + # Create some pre-registered users |
| 942 | + pre_registered_users = [] |
| 943 | + for _ in range(3): |
| 944 | + form_data = account_request_form.copy() |
| 945 | + form_data["firstName"] = faker.first_name() |
| 946 | + form_data["lastName"] = faker.last_name() |
| 947 | + form_data["email"] = faker.email() |
| 948 | + |
| 949 | + resp = await client.post( |
| 950 | + "/v0/admin/users:pre-register", |
| 951 | + json=form_data, |
| 952 | + headers={X_PRODUCT_NAME_HEADER: product_name}, |
| 953 | + ) |
| 954 | + pre_registered_data, _ = await assert_status(resp, status.HTTP_200_OK) |
| 955 | + pre_registered_users.append(pre_registered_data) |
| 956 | + |
| 957 | + # 1. List pending users (not yet approved) |
| 958 | + url = client.app.router["list_users_for_admin"].url_for() |
| 959 | + resp = await client.get( |
| 960 | + f"{url}?status=PENDING", headers={X_PRODUCT_NAME_HEADER: product_name} |
| 961 | + ) |
| 962 | + data, _ = await assert_status(resp, status.HTTP_200_OK) |
| 963 | + |
| 964 | + # Verify response structure and content |
| 965 | + assert "items" in data |
| 966 | + assert "pagination" in data |
| 967 | + assert len(data["items"]) >= 3 # At least our 3 pre-registered users |
| 968 | + |
| 969 | + # Verify each pre-registered user is in the list |
| 970 | + for pre_user in pre_registered_users: |
| 971 | + found = next( |
| 972 | + (item for item in data["items"] if item["email"] == pre_user["email"]), |
| 973 | + None, |
| 974 | + ) |
| 975 | + assert found is not None |
| 976 | + assert found["registered"] is False |
| 977 | + |
| 978 | + # 2. Approve one of the pre-registered users |
| 979 | + approval_data = {"email": pre_registered_users[0]["email"]} |
| 980 | + resp = await client.post( |
| 981 | + "/v0/admin/users:approve", |
| 982 | + json=approval_data, |
| 983 | + headers={X_PRODUCT_NAME_HEADER: product_name}, |
| 984 | + ) |
| 985 | + approved_data, _ = await assert_status(resp, status.HTTP_200_OK) |
| 986 | + |
| 987 | + # Verify response structure |
| 988 | + assert "invitationLink" in approved_data |
| 989 | + assert approved_data.get("email") == pre_registered_users[0]["email"] |
| 990 | + |
| 991 | + # Verify the user is no longer in the pending list |
| 992 | + resp = await client.get( |
| 993 | + f"{url}?status=PENDING", headers={X_PRODUCT_NAME_HEADER: product_name} |
| 994 | + ) |
| 995 | + data, _ = await assert_status(resp, status.HTTP_200_OK) |
| 996 | + |
| 997 | + # The approved user should no longer be in the pending list |
| 998 | + assert all( |
| 999 | + item["email"] != pre_registered_users[0]["email"] for item in data["items"] |
| 1000 | + ) |
| 1001 | + |
| 1002 | + # 3. Reject another pre-registered user |
| 1003 | + rejection_data = {"email": pre_registered_users[1]["email"]} |
| 1004 | + resp = await client.post( |
| 1005 | + "/v0/admin/users:reject", |
| 1006 | + json=rejection_data, |
| 1007 | + headers={X_PRODUCT_NAME_HEADER: product_name}, |
| 1008 | + ) |
| 1009 | + await assert_status(resp, status.HTTP_204_NO_CONTENT) |
| 1010 | + |
| 1011 | + # Verify the rejected user is no longer in the pending list |
| 1012 | + resp = await client.get( |
| 1013 | + f"{url}?status=PENDING", headers={X_PRODUCT_NAME_HEADER: product_name} |
| 1014 | + ) |
| 1015 | + data, _ = await assert_status(resp, status.HTTP_200_OK) |
| 1016 | + assert all( |
| 1017 | + item["email"] != pre_registered_users[1]["email"] for item in data["items"] |
| 1018 | + ) |
| 1019 | + |
| 1020 | + # 4. Resend confirmation email to the approved user |
| 1021 | + resend_data = {"email": pre_registered_users[0]["email"]} |
| 1022 | + resp = await client.post( |
| 1023 | + "/v0/admin/users:resendConfirmationEmail", |
| 1024 | + json=resend_data, |
| 1025 | + headers={X_PRODUCT_NAME_HEADER: product_name}, |
| 1026 | + ) |
| 1027 | + await assert_status(resp, status.HTTP_204_NO_CONTENT) |
| 1028 | + |
| 1029 | + # Search for the approved user to confirm their status |
| 1030 | + resp = await client.get( |
| 1031 | + "/v0/admin/users:search", |
| 1032 | + params={"email": pre_registered_users[0]["email"]}, |
| 1033 | + headers={X_PRODUCT_NAME_HEADER: product_name}, |
| 1034 | + ) |
| 1035 | + found_users, _ = await assert_status(resp, status.HTTP_200_OK) |
| 1036 | + |
| 1037 | + # Should find exactly one user |
| 1038 | + assert len(found_users) == 1 |
| 1039 | + found_user = UserForAdminGet(**found_users[0]) |
| 1040 | + |
| 1041 | + # User should be registered but in CONFIRMATION_PENDING status |
| 1042 | + assert found_user.registered is True |
| 1043 | + assert found_user.status == UserStatus.CONFIRMATION_PENDING |
0 commit comments