88 lines
2.7 KiB
Python
88 lines
2.7 KiB
Python
"""Tests for admin authentication (T04)."""
|
|
import pytest
|
|
from app.auth import create_access_token, verify_token, get_password_hash, verify_password
|
|
|
|
|
|
def test_password_hash_and_verify():
|
|
plain = "mysecret"
|
|
hashed = get_password_hash(plain)
|
|
assert hashed != plain
|
|
assert verify_password(plain, hashed) is True
|
|
assert verify_password("wrong", hashed) is False
|
|
|
|
|
|
def test_create_and_verify_token():
|
|
token = create_access_token({"sub": "admin"})
|
|
assert token is not None
|
|
payload = verify_token(token)
|
|
assert payload is not None
|
|
assert payload["sub"] == "admin"
|
|
|
|
|
|
def test_verify_invalid_token():
|
|
payload = verify_token("invalid.token.here")
|
|
assert payload is None
|
|
|
|
|
|
def test_verify_expired_token():
|
|
from datetime import timedelta
|
|
token = create_access_token({"sub": "admin"}, expires_delta=timedelta(seconds=-1))
|
|
payload = verify_token(token)
|
|
assert payload is None
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_login_success(client, seeded_admin):
|
|
"""POST /api/admin/login with valid credentials returns 200 with token."""
|
|
resp = await client.post("/api/admin/login", json={
|
|
"username": "admin",
|
|
"password": "testpassword",
|
|
})
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert "access_token" in data
|
|
assert data["token_type"] == "bearer"
|
|
assert "hms_admin_token" in resp.cookies
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_login_failure_wrong_password(client, seeded_admin):
|
|
"""POST /api/admin/login with wrong password returns 401."""
|
|
resp = await client.post("/api/admin/login", json={
|
|
"username": "admin",
|
|
"password": "wrongpassword",
|
|
})
|
|
assert resp.status_code == 401
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_login_failure_unknown_user(client, seeded_admin):
|
|
"""POST /api/admin/login with unknown user returns 401."""
|
|
resp = await client.post("/api/admin/login", json={
|
|
"username": "unknown",
|
|
"password": "testpassword",
|
|
})
|
|
assert resp.status_code == 401
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_me_without_token(client):
|
|
"""GET /api/admin/me without token returns 401."""
|
|
resp = await client.get("/api/admin/me")
|
|
assert resp.status_code == 401
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_me_with_valid_token(client, seeded_admin):
|
|
"""GET /api/admin/me with valid token returns 200 with username."""
|
|
# Login first
|
|
login_resp = await client.post("/api/admin/login", json={
|
|
"username": "admin",
|
|
"password": "testpassword",
|
|
})
|
|
token = login_resp.json()["access_token"]
|
|
|
|
resp = await client.get("/api/admin/me", cookies={"hms_admin_token": token})
|
|
assert resp.status_code == 200
|
|
assert resp.json()["username"] == "admin"
|