126 lines
4.7 KiB
Python
126 lines
4.7 KiB
Python
# ruff: noqa: PLR2004
|
|
|
|
from types import SimpleNamespace
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
|
|
def test_signup_rejects_missing_credentials(client):
|
|
response = client.post("/auth/signup", json={"provider": "credentials"})
|
|
|
|
assert response.status_code == 400
|
|
assert response.json()["detail"] == "Username or password is not provided"
|
|
|
|
|
|
def test_signup_rejects_unsupported_provider(client):
|
|
response = client.post(
|
|
"/auth/signup", json={"provider": "telegram", "username": "alice", "password": "Strong123!"}
|
|
)
|
|
|
|
assert response.status_code == 400
|
|
assert response.json()["detail"] == "Unsupported provider"
|
|
|
|
|
|
def test_signup_rejects_existing_username(client):
|
|
repository = SimpleNamespace(get_user_by_username=AsyncMock(return_value=object()))
|
|
with patch("routes.auth.UserRepository", return_value=repository):
|
|
response = client.post(
|
|
"/auth/signup",
|
|
json={"provider": "credentials", "username": "alice", "password": "Strong123!"},
|
|
)
|
|
|
|
assert response.status_code == 409
|
|
assert response.json()["detail"] == "User already exists"
|
|
|
|
|
|
def test_signup_rejects_weak_password(client):
|
|
repository = SimpleNamespace(get_user_by_username=AsyncMock(return_value=None))
|
|
with (
|
|
patch("routes.auth.UserRepository", return_value=repository),
|
|
patch("routes.auth.estimate_password_strength", return_value=False),
|
|
):
|
|
response = client.post(
|
|
"/auth/signup",
|
|
json={"provider": "credentials", "username": "alice", "password": "weak"},
|
|
)
|
|
|
|
assert response.status_code == 422
|
|
assert response.json()["detail"] == "Password is not secure."
|
|
|
|
|
|
def test_signup_accepts_unknown_referral_code(client):
|
|
created_user = SimpleNamespace(
|
|
username="alice", telegram_id=None, referal_code="new-code", balance=0
|
|
)
|
|
repository = SimpleNamespace(
|
|
get_user_by_username=AsyncMock(return_value=None),
|
|
get_user_by_ref_code=AsyncMock(return_value=None),
|
|
create=AsyncMock(return_value=created_user),
|
|
)
|
|
with (
|
|
patch("routes.auth.UserRepository", return_value=repository),
|
|
patch("routes.auth.estimate_password_strength", return_value=True),
|
|
patch("routes.auth.hash_password", return_value="hashed"),
|
|
):
|
|
response = client.post(
|
|
"/auth/signup",
|
|
json={
|
|
"provider": "credentials",
|
|
"username": "alice",
|
|
"password": "Strong123!",
|
|
"referal_code": "unknown",
|
|
},
|
|
)
|
|
|
|
assert response.status_code == 201
|
|
repository.create.assert_awaited_once_with(
|
|
username="alice", hashed_password="hashed", referal_id=None
|
|
)
|
|
assert response.json()["referal_code"] == "new-code"
|
|
|
|
|
|
def test_login_distinguishes_unknown_user_and_bad_password(client):
|
|
unknown_repository = SimpleNamespace(get_user_by_username=AsyncMock(return_value=None))
|
|
with patch("routes.auth.UserRepository", return_value=unknown_repository):
|
|
unknown_response = client.post(
|
|
"/auth/login",
|
|
json={"provider": "credentials", "username": "alice", "password": "secret"},
|
|
)
|
|
|
|
existing_user = SimpleNamespace(hashed_password="hash")
|
|
existing_repository = SimpleNamespace(
|
|
get_user_by_username=AsyncMock(return_value=existing_user)
|
|
)
|
|
with (
|
|
patch("routes.auth.UserRepository", return_value=existing_repository),
|
|
patch("routes.auth.SessionsRepository"),
|
|
patch("routes.auth.verify_password", return_value=False),
|
|
):
|
|
password_response = client.post(
|
|
"/auth/login",
|
|
json={"provider": "credentials", "username": "alice", "password": "secret"},
|
|
)
|
|
|
|
assert unknown_response.status_code == password_response.status_code == 401
|
|
assert unknown_response.json()["detail"] == "User doesn't exist."
|
|
assert password_response.json()["detail"] == "Invalid password"
|
|
|
|
|
|
def test_login_telegram_is_explicitly_unavailable(client):
|
|
response = client.post("/auth/login", json={"provider": "telegram"})
|
|
|
|
assert response.status_code == 503
|
|
|
|
|
|
def test_refresh_requires_query_parameters_and_rejects_unknown_token(client):
|
|
missing_response = client.post("/auth/refresh")
|
|
repository = SimpleNamespace(get_session_by_hash=AsyncMock(return_value=None))
|
|
with (
|
|
patch("routes.auth.SessionsRepository", return_value=repository),
|
|
patch("routes.auth.hash_refresh_token", return_value="token-hash"),
|
|
):
|
|
invalid_response = client.post("/auth/refresh?refresh_token=expired&iss=credentials")
|
|
|
|
assert missing_response.status_code == 422
|
|
assert invalid_response.status_code == 401
|
|
assert invalid_response.json()["detail"] == "Refresh token is invalid."
|