Files
space-booking/backend/tests/test_registration.py
Claude Agent df4031d99c feat: Space Booking System - MVP complet
Sistem web pentru rezervarea de birouri și săli de ședință
cu flux de aprobare administrativă.

Stack: FastAPI + Vue.js 3 + SQLite + TypeScript

Features implementate:
- Autentificare JWT + Self-registration cu email verification
- CRUD Spații, Utilizatori, Settings (Admin)
- Calendar interactiv (FullCalendar) cu drag-and-drop
- Creare rezervări cu validare (durată, program, overlap, max/zi)
- Rezervări recurente (săptămânal)
- Admin: aprobare/respingere/anulare cereri
- Admin: creare directă rezervări (bypass approval)
- Admin: editare orice rezervare
- User: editare/anulare rezervări proprii
- Notificări in-app (bell icon + dropdown)
- Notificări email (async SMTP cu BackgroundTasks)
- Jurnal acțiuni administrative (audit log)
- Rapoarte avansate (utilizare, top users, approval rate)
- Șabloane rezervări (booking templates)
- Atașamente fișiere (upload/download)
- Conflict warnings (verificare disponibilitate real-time)
- Integrare Google Calendar (OAuth2)
- Suport timezone (UTC storage + user preference)
- 225+ teste backend

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 17:51:29 +00:00

334 lines
8.9 KiB
Python

"""Tests for user registration and email verification."""
from datetime import datetime, timedelta
from unittest.mock import patch
import pytest
from jose import jwt
from app.core.config import settings
from app.models.user import User
def test_register_success(client):
"""Test successful registration."""
response = client.post(
"/api/auth/register",
json={
"email": "newuser@example.com",
"password": "Test1234",
"confirm_password": "Test1234",
"full_name": "New User",
"organization": "Test Org",
},
)
assert response.status_code == 201
data = response.json()
assert data["email"] == "newuser@example.com"
assert "verify" in data["message"].lower()
def test_register_duplicate_email(client, test_user):
"""Test registering with existing email."""
response = client.post(
"/api/auth/register",
json={
"email": test_user.email,
"password": "Test1234",
"confirm_password": "Test1234",
"full_name": "Duplicate User",
"organization": "Test Org",
},
)
assert response.status_code == 400
assert "already registered" in response.json()["detail"].lower()
def test_register_weak_password(client):
"""Test password validation."""
# No uppercase
response = client.post(
"/api/auth/register",
json={
"email": "test@example.com",
"password": "test1234",
"confirm_password": "test1234",
"full_name": "Test User",
"organization": "Test Org",
},
)
assert response.status_code == 422
# No digit
response = client.post(
"/api/auth/register",
json={
"email": "test@example.com",
"password": "Testtest",
"confirm_password": "Testtest",
"full_name": "Test User",
"organization": "Test Org",
},
)
assert response.status_code == 422
# Too short
response = client.post(
"/api/auth/register",
json={
"email": "test@example.com",
"password": "Test12",
"confirm_password": "Test12",
"full_name": "Test User",
"organization": "Test Org",
},
)
assert response.status_code == 422
def test_register_passwords_mismatch(client):
"""Test password confirmation."""
response = client.post(
"/api/auth/register",
json={
"email": "test@example.com",
"password": "Test1234",
"confirm_password": "Different1234",
"full_name": "Test User",
"organization": "Test Org",
},
)
assert response.status_code == 422
assert "password" in response.json()["detail"][0]["msg"].lower()
def test_verify_email_success(client, db_session):
"""Test email verification."""
# Create unverified user
user = User(
email="verify@example.com",
hashed_password="hashed",
full_name="Test User",
organization="Test Org",
role="user",
is_active=False,
)
db_session.add(user)
db_session.commit()
db_session.refresh(user)
# Generate token
token = jwt.encode(
{
"sub": str(user.id),
"type": "email_verification",
"exp": datetime.utcnow() + timedelta(hours=24),
},
settings.secret_key,
algorithm="HS256",
)
# Verify
response = client.post("/api/auth/verify", json={"token": token})
assert response.status_code == 200
assert "successfully" in response.json()["message"].lower()
# Check user is now active
db_session.refresh(user)
assert user.is_active is True
def test_verify_email_expired_token(client, db_session):
"""Test expired verification token."""
# Create unverified user
user = User(
email="verify@example.com",
hashed_password="hashed",
full_name="Test User",
organization="Test Org",
role="user",
is_active=False,
)
db_session.add(user)
db_session.commit()
db_session.refresh(user)
# Generate expired token
token = jwt.encode(
{
"sub": str(user.id),
"type": "email_verification",
"exp": datetime.utcnow() - timedelta(hours=1), # Expired
},
settings.secret_key,
algorithm="HS256",
)
# Try to verify
response = client.post("/api/auth/verify", json={"token": token})
assert response.status_code == 400
assert "expired" in response.json()["detail"].lower()
def test_verify_email_invalid_token(client):
"""Test invalid verification token."""
response = client.post("/api/auth/verify", json={"token": "invalid-token"})
assert response.status_code == 400
assert "invalid" in response.json()["detail"].lower()
def test_verify_email_wrong_token_type(client, db_session):
"""Test token with wrong type."""
# Create unverified user
user = User(
email="verify@example.com",
hashed_password="hashed",
full_name="Test User",
organization="Test Org",
role="user",
is_active=False,
)
db_session.add(user)
db_session.commit()
db_session.refresh(user)
# Generate token with wrong type
token = jwt.encode(
{
"sub": str(user.id),
"type": "access_token", # Wrong type
"exp": datetime.utcnow() + timedelta(hours=24),
},
settings.secret_key,
algorithm="HS256",
)
# Try to verify
response = client.post("/api/auth/verify", json={"token": token})
assert response.status_code == 400
assert "invalid" in response.json()["detail"].lower()
def test_verify_email_already_verified(client, db_session):
"""Test verifying already verified account."""
# Create verified user
user = User(
email="verify@example.com",
hashed_password="hashed",
full_name="Test User",
organization="Test Org",
role="user",
is_active=True, # Already active
)
db_session.add(user)
db_session.commit()
db_session.refresh(user)
# Generate token
token = jwt.encode(
{
"sub": str(user.id),
"type": "email_verification",
"exp": datetime.utcnow() + timedelta(hours=24),
},
settings.secret_key,
algorithm="HS256",
)
# Try to verify
response = client.post("/api/auth/verify", json={"token": token})
assert response.status_code == 200
assert "already verified" in response.json()["message"].lower()
def test_resend_verification(client, db_session):
"""Test resending verification email."""
# Create unverified user
user = User(
email="resend@example.com",
hashed_password="hashed",
full_name="Test User",
organization="Test Org",
role="user",
is_active=False,
)
db_session.add(user)
db_session.commit()
# Request resend
response = client.post(
"/api/auth/resend-verification", params={"email": user.email}
)
assert response.status_code == 200
assert "verification link" in response.json()["message"].lower()
def test_resend_verification_nonexistent_email(client):
"""Test resending to non-existent email."""
response = client.post(
"/api/auth/resend-verification",
params={"email": "nonexistent@example.com"},
)
# Should not reveal if email exists
assert response.status_code == 200
assert "if the email exists" in response.json()["message"].lower()
def test_resend_verification_already_verified(client, db_session):
"""Test resending for already verified account."""
# Create verified user
user = User(
email="verified@example.com",
hashed_password="hashed",
full_name="Test User",
organization="Test Org",
role="user",
is_active=True,
)
db_session.add(user)
db_session.commit()
# Try to resend
response = client.post(
"/api/auth/resend-verification", params={"email": user.email}
)
assert response.status_code == 400
assert "already verified" in response.json()["detail"].lower()
def test_login_before_verification(client, db_session):
"""Test that unverified users cannot log in."""
# Create unverified user
from app.core.security import get_password_hash
password = "Test1234"
user = User(
email="unverified@example.com",
hashed_password=get_password_hash(password),
full_name="Test User",
organization="Test Org",
role="user",
is_active=False, # Not verified
)
db_session.add(user)
db_session.commit()
# Try to login
response = client.post(
"/api/auth/login",
json={"email": user.email, "password": password},
)
assert response.status_code == 403
assert "disabled" in response.json()["detail"].lower()