feat: T03+T04 backend - FastAPI, DB models, Rentman integration, admin auth, APScheduler
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
"""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"
|
||||
Reference in New Issue
Block a user