92 lines
3.4 KiB
Python
92 lines
3.4 KiB
Python
# Example: be/tests/api/v1/test_auth.py
|
|
import pytest
|
|
from httpx import AsyncClient
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.security import verify_password
|
|
from app.crud.user import get_user_by_email
|
|
from app.schemas.user import UserPublic # Import for response validation
|
|
from app.schemas.auth import Token # Import for response validation
|
|
|
|
pytestmark = pytest.mark.asyncio
|
|
|
|
async def test_signup_success(client: AsyncClient, db: AsyncSession):
|
|
email = "testsignup@example.com"
|
|
password = "testpassword123"
|
|
response = await client.post(
|
|
"/api/v1/auth/signup",
|
|
json={"email": email, "password": password, "name": "Test Signup"},
|
|
)
|
|
assert response.status_code == 201
|
|
data = response.json()
|
|
assert data["email"] == email
|
|
assert data["name"] == "Test Signup"
|
|
assert "id" in data
|
|
assert "created_at" in data
|
|
# Verify password hash is NOT returned
|
|
assert "password" not in data
|
|
assert "hashed_password" not in data
|
|
|
|
# Verify user exists in DB
|
|
user_db = await get_user_by_email(db, email=email)
|
|
assert user_db is not None
|
|
assert user_db.email == email
|
|
assert verify_password(password, user_db.hashed_password)
|
|
|
|
|
|
async def test_signup_email_exists(client: AsyncClient, db: AsyncSession):
|
|
# Create user first
|
|
email = "testexists@example.com"
|
|
password = "testpassword123"
|
|
await client.post(
|
|
"/api/v1/auth/signup",
|
|
json={"email": email, "password": password},
|
|
)
|
|
|
|
# Attempt signup again with same email
|
|
response = await client.post(
|
|
"/api/v1/auth/signup",
|
|
json={"email": email, "password": "anotherpassword"},
|
|
)
|
|
assert response.status_code == 400
|
|
assert "Email already registered" in response.json()["detail"]
|
|
|
|
|
|
async def test_login_success(client: AsyncClient, db: AsyncSession):
|
|
email = "testlogin@example.com"
|
|
password = "testpassword123"
|
|
# Create user first via signup
|
|
signup_res = await client.post(
|
|
"/api/v1/auth/signup", json={"email": email, "password": password}
|
|
)
|
|
assert signup_res.status_code == 201
|
|
|
|
# Attempt login
|
|
login_payload = {"username": email, "password": password}
|
|
response = await client.post("/api/v1/auth/login", data=login_payload) # Use data for form encoding
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "access_token" in data
|
|
assert data["token_type"] == "bearer"
|
|
# Optionally verify the token itself here using verify_access_token
|
|
|
|
|
|
async def test_login_wrong_password(client: AsyncClient, db: AsyncSession):
|
|
email = "testloginwrong@example.com"
|
|
password = "testpassword123"
|
|
await client.post(
|
|
"/api/v1/auth/signup", json={"email": email, "password": password}
|
|
)
|
|
|
|
login_payload = {"username": email, "password": "wrongpassword"}
|
|
response = await client.post("/api/v1/auth/login", data=login_payload)
|
|
assert response.status_code == 401
|
|
assert "Incorrect email or password" in response.json()["detail"]
|
|
assert "WWW-Authenticate" in response.headers
|
|
assert response.headers["WWW-Authenticate"] == "Bearer"
|
|
|
|
async def test_login_user_not_found(client: AsyncClient, db: AsyncSession):
|
|
login_payload = {"username": "nosuchuser@example.com", "password": "anypassword"}
|
|
response = await client.post("/api/v1/auth/login", data=login_payload)
|
|
assert response.status_code == 401
|
|
assert "Incorrect email or password" in response.json()["detail"] |