Files
CA/backend/tests/test_auth.py
Akiba So f092c3c550 chore: add test infrastructure and update risk router
- Add vitest config and unit tests for components, api, stores
- Add Playwright e2e test for user flows
- Add backend test files
- Update risk.py with LOD grid KDTree optimization
2026-06-09 12:54:55 +08:00

117 lines
4.2 KiB
Python

"""US-003: Authentication and security tests."""
import pytest
from fastapi.testclient import TestClient
class TestLogin:
def test_login_success(self, client: TestClient):
resp = client.post("/api/auth/login", json={
"username": "admin", "password": "admin123"
})
assert resp.status_code == 200
data = resp.json()
assert "access_token" in data
assert len(data["access_token"]) > 0
def test_login_wrong_password(self, client: TestClient):
resp = client.post("/api/auth/login", json={
"username": "admin", "password": "wrongpassword"
})
assert resp.status_code == 401
assert "Incorrect username or password" in resp.json()["detail"]
def test_login_nonexistent_user(self, client: TestClient):
resp = client.post("/api/auth/login", json={
"username": "nonexistent_user_xyz", "password": "password"
})
assert resp.status_code == 401
def test_login_empty_username(self, client: TestClient):
resp = client.post("/api/auth/login", json={
"username": "", "password": "password"
})
assert resp.status_code in (401, 422)
class TestRegister:
def test_register_new_user(self, client: TestClient):
resp = client.post("/api/auth/register", json={
"username": "testuser_001", "password": "testpass123"
})
assert resp.status_code == 201
assert resp.json()["username"] == "testuser_001"
def test_register_duplicate(self, client: TestClient):
client.post("/api/auth/register", json={
"username": "dup_user", "password": "testpass123"
})
resp = client.post("/api/auth/register", json={
"username": "dup_user", "password": "testpass123"
})
assert resp.status_code == 409
assert "already exists" in resp.json()["detail"]
def test_register_missing_password(self, client: TestClient):
resp = client.post("/api/auth/register", json={"username": "user"})
assert resp.status_code == 422
class TestTokenAuth:
def test_me_with_valid_token(self, client: TestClient, auth_token):
resp = client.get(
"/api/auth/me",
headers={"Authorization": f"Bearer {auth_token}"}
)
assert resp.status_code == 200
assert resp.json()["username"] == "admin"
def test_me_without_token(self, client: TestClient):
resp = client.get("/api/auth/me")
assert resp.status_code in (401, 403)
def test_me_with_invalid_token(self, client: TestClient):
resp = client.get(
"/api/auth/me",
headers={"Authorization": "Bearer invalid.token.here"}
)
assert resp.status_code in (401, 403)
def test_me_with_malformed_header(self, client: TestClient):
resp = client.get(
"/api/auth/me",
headers={"Authorization": "NotBearer token"}
)
assert resp.status_code in (401, 403)
def test_me_with_expired_token(self, client: TestClient):
"""Token with past expiration should be rejected."""
expired = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTcwMDAwMDAwMH0.fake"
resp = client.get(
"/api/auth/me",
headers={"Authorization": f"Bearer {expired}"}
)
assert resp.status_code in (401, 403)
def test_login_then_access_protected(self, client: TestClient):
login_resp = client.post("/api/auth/login", json={
"username": "admin", "password": "admin123"
})
token = login_resp.json()["access_token"]
resp = client.get(
"/api/auth/me",
headers={"Authorization": f"Bearer {token}"}
)
assert resp.status_code == 200
assert resp.json()["username"] == "admin"
class TestPasswordHashing:
def test_bcrypt_not_plaintext(self, client: TestClient):
"""Passwords should be hashed, not stored as plaintext."""
from auth.service import hash_password, verify_password
hashed = hash_password("test_password")
assert hashed != "test_password"
assert verify_password("test_password", hashed)
assert not verify_password("wrong_password", hashed)