Skip to content

Commit 3e0f6ec

Browse files
committed
cleanup oas
1 parent e692c8b commit 3e0f6ec

File tree

2 files changed

+261
-0
lines changed

2 files changed

+261
-0
lines changed

api/specs/web-server/_users.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ async def update_my_profile(_body: MyProfileRestPatch): ...
5454
"/me/phone:register",
5555
description="Starts the phone registration process",
5656
status_code=status.HTTP_202_ACCEPTED,
57+
responses={
58+
status.HTTP_202_ACCEPTED: {"description": "Phone registration initiated"},
59+
status.HTTP_401_UNAUTHORIZED: {"description": "Authentication required"},
60+
status.HTTP_403_FORBIDDEN: {"description": "Insufficient permissions"},
61+
status.HTTP_422_UNPROCESSABLE_ENTITY: {
62+
"description": "Invalid phone number format"
63+
},
64+
},
5765
)
5866
async def my_phone_register(_body: MyPhoneRegister): ...
5967

@@ -62,6 +70,14 @@ async def my_phone_register(_body: MyPhoneRegister): ...
6270
"/me/phone:resend",
6371
description="Resends the phone registration code",
6472
status_code=status.HTTP_202_ACCEPTED,
73+
responses={
74+
status.HTTP_202_ACCEPTED: {"description": "Phone code resent"},
75+
status.HTTP_400_BAD_REQUEST: {
76+
"description": "No pending phone registration found"
77+
},
78+
status.HTTP_401_UNAUTHORIZED: {"description": "Authentication required"},
79+
status.HTTP_403_FORBIDDEN: {"description": "Insufficient permissions"},
80+
},
6581
)
6682
async def my_phone_resend(): ...
6783

@@ -70,6 +86,17 @@ async def my_phone_resend(): ...
7086
"/me/phone:confirm",
7187
description="Confirms the phone registration",
7288
status_code=status.HTTP_204_NO_CONTENT,
89+
responses={
90+
status.HTTP_204_NO_CONTENT: {"description": "Phone registration confirmed"},
91+
status.HTTP_400_BAD_REQUEST: {
92+
"description": "No pending registration or invalid code"
93+
},
94+
status.HTTP_401_UNAUTHORIZED: {"description": "Authentication required"},
95+
status.HTTP_403_FORBIDDEN: {"description": "Insufficient permissions"},
96+
status.HTTP_422_UNPROCESSABLE_ENTITY: {
97+
"description": "Invalid confirmation code format"
98+
},
99+
},
73100
)
74101
async def my_phone_confirm(_body: MyPhoneConfirm): ...
75102

services/web/server/tests/unit/with_dbs/03/test_users_rest_profiles.py

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,3 +814,237 @@ async def test_phone_registration_change_existing_phone(
814814
# Verify phone was updated to new phone
815815
assert updated_profile.phone == new_phone
816816
assert updated_profile.phone != first_phone
817+
818+
819+
#
820+
# PHONE REGISTRATION FAILURE TESTS
821+
#
822+
823+
824+
@pytest.mark.parametrize("user_role", [UserRole.USER])
825+
async def test_phone_resend_without_pending_registration(
826+
user_role: UserRole,
827+
logged_user: UserInfoDict,
828+
client: TestClient,
829+
):
830+
assert client.app
831+
832+
# Try to resend code without any pending registration
833+
url = client.app.router["my_phone_resend"].url_for()
834+
resp = await client.post(f"{url}")
835+
await assert_status(resp, status.HTTP_400_BAD_REQUEST)
836+
837+
838+
@pytest.mark.parametrize("user_role", [UserRole.USER])
839+
async def test_phone_confirm_without_pending_registration(
840+
user_role: UserRole,
841+
logged_user: UserInfoDict,
842+
client: TestClient,
843+
):
844+
assert client.app
845+
846+
# Try to confirm code without any pending registration
847+
url = client.app.router["my_phone_confirm"].url_for()
848+
resp = await client.post(
849+
f"{url}",
850+
json={
851+
"code": _PHONE_CODE_VALUE_FAKE,
852+
},
853+
)
854+
await assert_status(resp, status.HTTP_400_BAD_REQUEST)
855+
856+
857+
@pytest.mark.parametrize("user_role", [UserRole.USER])
858+
async def test_phone_confirm_with_wrong_code(
859+
user_role: UserRole,
860+
logged_user: UserInfoDict,
861+
client: TestClient,
862+
faker: Faker,
863+
):
864+
assert client.app
865+
866+
# STEP 1: REGISTER phone number
867+
new_phone = faker.phone_number()
868+
url = client.app.router["my_phone_register"].url_for()
869+
resp = await client.post(
870+
f"{url}",
871+
json={
872+
"phone": new_phone,
873+
},
874+
)
875+
await assert_status(resp, status.HTTP_202_ACCEPTED)
876+
877+
# STEP 2: Try to confirm with wrong code
878+
url = client.app.router["my_phone_confirm"].url_for()
879+
resp = await client.post(
880+
f"{url}",
881+
json={
882+
"code": "wrong_code",
883+
},
884+
)
885+
await assert_status(resp, status.HTTP_400_BAD_REQUEST)
886+
887+
888+
@pytest.mark.parametrize("user_role", [UserRole.USER])
889+
async def test_phone_confirm_with_invalid_code_format(
890+
user_role: UserRole,
891+
logged_user: UserInfoDict,
892+
client: TestClient,
893+
faker: Faker,
894+
):
895+
assert client.app
896+
897+
# STEP 1: REGISTER phone number
898+
new_phone = faker.phone_number()
899+
url = client.app.router["my_phone_register"].url_for()
900+
resp = await client.post(
901+
f"{url}",
902+
json={
903+
"phone": new_phone,
904+
},
905+
)
906+
await assert_status(resp, status.HTTP_202_ACCEPTED)
907+
908+
# STEP 2: Try to confirm with invalid code format (contains special characters)
909+
url = client.app.router["my_phone_confirm"].url_for()
910+
resp = await client.post(
911+
f"{url}",
912+
json={
913+
"code": "123-456", # Invalid format according to pattern
914+
},
915+
)
916+
await assert_status(resp, status.HTTP_422_UNPROCESSABLE_ENTITY)
917+
918+
919+
@pytest.mark.parametrize("user_role", [UserRole.USER])
920+
async def test_phone_register_with_empty_phone(
921+
user_role: UserRole,
922+
logged_user: UserInfoDict,
923+
client: TestClient,
924+
):
925+
assert client.app
926+
927+
# Try to register with empty phone number
928+
url = client.app.router["my_phone_register"].url_for()
929+
resp = await client.post(
930+
f"{url}",
931+
json={
932+
"phone": "", # Empty phone number
933+
},
934+
)
935+
await assert_status(resp, status.HTTP_422_UNPROCESSABLE_ENTITY)
936+
937+
# Try to register with whitespace-only phone number
938+
url = client.app.router["my_phone_register"].url_for()
939+
resp = await client.post(
940+
f"{url}",
941+
json={
942+
"phone": " ", # Whitespace only
943+
},
944+
)
945+
await assert_status(resp, status.HTTP_422_UNPROCESSABLE_ENTITY)
946+
947+
948+
@pytest.mark.parametrize("user_role", [UserRole.USER])
949+
async def test_phone_confirm_with_empty_code(
950+
user_role: UserRole,
951+
logged_user: UserInfoDict,
952+
client: TestClient,
953+
faker: Faker,
954+
):
955+
assert client.app
956+
957+
# STEP 1: REGISTER phone number
958+
new_phone = faker.phone_number()
959+
url = client.app.router["my_phone_register"].url_for()
960+
resp = await client.post(
961+
f"{url}",
962+
json={
963+
"phone": new_phone,
964+
},
965+
)
966+
await assert_status(resp, status.HTTP_202_ACCEPTED)
967+
968+
# STEP 2: Try to confirm with empty code
969+
url = client.app.router["my_phone_confirm"].url_for()
970+
resp = await client.post(
971+
f"{url}",
972+
json={
973+
"code": "", # Empty code
974+
},
975+
)
976+
await assert_status(resp, status.HTTP_422_UNPROCESSABLE_ENTITY)
977+
978+
979+
@pytest.mark.parametrize(
980+
"user_role,expected",
981+
[
982+
(UserRole.ANONYMOUS, status.HTTP_401_UNAUTHORIZED),
983+
(UserRole.GUEST, status.HTTP_403_FORBIDDEN),
984+
],
985+
)
986+
async def test_phone_register_access_rights(
987+
user_role: UserRole,
988+
logged_user: UserInfoDict,
989+
client: TestClient,
990+
expected: HTTPStatus,
991+
faker: Faker,
992+
):
993+
assert client.app
994+
995+
# Try to register phone with insufficient permissions
996+
url = client.app.router["my_phone_register"].url_for()
997+
resp = await client.post(
998+
f"{url}",
999+
json={
1000+
"phone": faker.phone_number(),
1001+
},
1002+
)
1003+
await assert_status(resp, expected)
1004+
1005+
1006+
@pytest.mark.parametrize(
1007+
"user_role,expected",
1008+
[
1009+
(UserRole.ANONYMOUS, status.HTTP_401_UNAUTHORIZED),
1010+
(UserRole.GUEST, status.HTTP_403_FORBIDDEN),
1011+
],
1012+
)
1013+
async def test_phone_resend_access_rights(
1014+
user_role: UserRole,
1015+
logged_user: UserInfoDict,
1016+
client: TestClient,
1017+
expected: HTTPStatus,
1018+
):
1019+
assert client.app
1020+
1021+
# Try to resend code with insufficient permissions
1022+
url = client.app.router["my_phone_resend"].url_for()
1023+
resp = await client.post(f"{url}")
1024+
await assert_status(resp, expected)
1025+
1026+
1027+
@pytest.mark.parametrize(
1028+
"user_role,expected",
1029+
[
1030+
(UserRole.ANONYMOUS, status.HTTP_401_UNAUTHORIZED),
1031+
(UserRole.GUEST, status.HTTP_403_FORBIDDEN),
1032+
],
1033+
)
1034+
async def test_phone_confirm_access_rights(
1035+
user_role: UserRole,
1036+
logged_user: UserInfoDict,
1037+
client: TestClient,
1038+
expected: HTTPStatus,
1039+
):
1040+
assert client.app
1041+
1042+
# Try to confirm code with insufficient permissions
1043+
url = client.app.router["my_phone_confirm"].url_for()
1044+
resp = await client.post(
1045+
f"{url}",
1046+
json={
1047+
"code": _PHONE_CODE_VALUE_FAKE,
1048+
},
1049+
)
1050+
await assert_status(resp, expected)

0 commit comments

Comments
 (0)