- Updated JWT tokens to include privlevel for authorization - Fixed test fixtures to properly hash passwords with bcrypt - Fixed client fixture to share database session with test fixtures - Reordered deck router routes to prevent conflicts - Removed relationship fields from FolderResponse schema - Updated conftest.py with proper async session management
124 lines
4.1 KiB
Python
124 lines
4.1 KiB
Python
"""
|
|
Tests for authentication endpoints.
|
|
"""
|
|
import pytest
|
|
from httpx import AsyncClient
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.models.models import User
|
|
from app.core.security import hash_password, create_access_token
|
|
|
|
|
|
class TestAuthentication:
|
|
"""Test authentication endpoints."""
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_login_success(self, client: AsyncClient, test_user: User):
|
|
"""Test successful login."""
|
|
response = await client.post(
|
|
"/api/v1/auth/login",
|
|
json={
|
|
"username": "regular_test",
|
|
"password": "testpassword123",
|
|
},
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "access_token" in data
|
|
assert "refresh_token" in data
|
|
assert data["user"]["username"] == "regular_test"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_login_invalid_password(self, client: AsyncClient, test_user: User):
|
|
"""Test login with invalid password."""
|
|
response = await client.post(
|
|
"/api/v1/auth/login",
|
|
json={
|
|
"username": "regular_test",
|
|
"password": "wrongpassword",
|
|
},
|
|
)
|
|
assert response.status_code == 401
|
|
assert response.json()["detail"] == "Invalid username or password"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_login_nonexistent_user(self, client: AsyncClient):
|
|
"""Test login with non-existent user."""
|
|
response = await client.post(
|
|
"/api/v1/auth/login",
|
|
json={
|
|
"username": "nonexistent",
|
|
"password": "password123",
|
|
},
|
|
)
|
|
assert response.status_code == 401
|
|
assert response.json()["detail"] == "Invalid username or password"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_register_success(self, client: AsyncClient):
|
|
"""Test successful user registration."""
|
|
response = await client.post(
|
|
"/api/v1/auth/register",
|
|
json={
|
|
"username": "newuser",
|
|
"password": "newpassword123",
|
|
"email": "new@example.com",
|
|
"country": "US",
|
|
},
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["username"] == "newuser"
|
|
assert data["email"] == "new@example.com"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_register_duplicate_username(self, client: AsyncClient, test_user: User):
|
|
"""Test registration with duplicate username."""
|
|
response = await client.post(
|
|
"/api/v1/auth/register",
|
|
json={
|
|
"username": "regular_test", # Already exists
|
|
"password": "newpassword123",
|
|
"email": "new@example.com",
|
|
},
|
|
)
|
|
assert response.status_code == 409
|
|
assert response.json()["detail"] == "Username already exists"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_current_user(self, client: AsyncClient, regular_token: str):
|
|
"""Test getting current user."""
|
|
response = await client.get(
|
|
"/api/v1/auth/me",
|
|
params={"token": regular_token},
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["username"] == "regular_test"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_refresh_token(self, client: AsyncClient, test_user: User):
|
|
"""Test refreshing access token."""
|
|
from app.core.security import create_refresh_token
|
|
|
|
# First login to get refresh token
|
|
login_response = await client.post(
|
|
"/api/v1/auth/login",
|
|
json={
|
|
"username": "regular_test",
|
|
"password": "testpassword123",
|
|
},
|
|
)
|
|
refresh_token = login_response.json()["refresh_token"]
|
|
|
|
# Refresh token
|
|
response = await client.post(
|
|
"/api/v1/auth/refresh",
|
|
json={
|
|
"refresh_token": refresh_token,
|
|
},
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "access_token" in data
|