Core modules: - Laws: CRUD, search, AI-powered QA - Analysis: legal research and case management - Contracts: lifecycle management with templates - Signatures: electronic signature workflow Infrastructure: - FastAPI + SQLite + async SQLAlchemy - Docker deployment support - 54 unit tests passing Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
"""Unit tests for security module."""
|
|
import pytest
|
|
from datetime import datetime, timedelta
|
|
|
|
from app.core.security import (
|
|
get_password_hash,
|
|
verify_password,
|
|
create_access_token,
|
|
decode_access_token,
|
|
)
|
|
|
|
|
|
class TestPasswordHashing:
|
|
"""Test cases for password hashing."""
|
|
|
|
def test_password_hash(self):
|
|
"""Test password hashing."""
|
|
password = "test_password_123"
|
|
hashed = get_password_hash(password)
|
|
|
|
assert hashed != password
|
|
assert len(hashed) > 0
|
|
assert hashed.startswith("$2b$")
|
|
|
|
def test_verify_password_correct(self):
|
|
"""Test verifying correct password."""
|
|
password = "test_password_123"
|
|
hashed = get_password_hash(password)
|
|
|
|
assert verify_password(password, hashed) is True
|
|
|
|
def test_verify_password_incorrect(self):
|
|
"""Test verifying incorrect password."""
|
|
password = "test_password_123"
|
|
hashed = get_password_hash(password)
|
|
|
|
assert verify_password("wrong_password", hashed) is False
|
|
|
|
def test_different_passwords_different_hashes(self):
|
|
"""Test that same password produces different hashes."""
|
|
password = "test_password_123"
|
|
hash1 = get_password_hash(password)
|
|
hash2 = get_password_hash(password)
|
|
|
|
assert hash1 != hash2
|
|
|
|
|
|
class TestJWTTokens:
|
|
"""Test cases for JWT token handling."""
|
|
|
|
def test_create_access_token(self):
|
|
"""Test creating access token."""
|
|
data = {"sub": "user123", "role": "lawyer"}
|
|
token = create_access_token(data)
|
|
|
|
assert token is not None
|
|
assert isinstance(token, str)
|
|
assert len(token) > 0
|
|
|
|
def test_decode_access_token(self):
|
|
"""Test decoding access token."""
|
|
data = {"sub": "user123", "role": "lawyer"}
|
|
token = create_access_token(data)
|
|
|
|
decoded = decode_access_token(token)
|
|
|
|
assert decoded is not None
|
|
assert decoded["sub"] == "user123"
|
|
assert decoded["role"] == "lawyer"
|
|
|
|
def test_decode_invalid_token(self):
|
|
"""Test decoding invalid token."""
|
|
decoded = decode_access_token("invalid.token.here")
|
|
|
|
assert decoded is None
|
|
|
|
def test_token_contains_exp(self):
|
|
"""Test that token contains expiration."""
|
|
data = {"sub": "user123"}
|
|
token = create_access_token(data)
|
|
|
|
decoded = decode_access_token(token)
|
|
|
|
assert "exp" in decoded
|