StressDetect / tests /test_security_auth.py
Ace-119's picture
Add Streamlit dashboard, test suite, and Colab notebooks
0304d75
"""
tests/test_security_auth.py
============================
Unit tests for security/auth.py — JWT, bcrypt hashing, Fernet encryption.
"""
import time
import pytest
from jose import jwt, JWTError
from security.auth import (
JWT_ALGORITHM,
JWT_SECRET_KEY,
create_jwt_token,
decode_jwt_token,
decrypt_data,
encrypt_data,
hash_password,
verify_password,
)
# ---------------------------------------------------------------------------
# Password hashing (bcrypt)
# ---------------------------------------------------------------------------
class TestPasswordHashing:
def test_hash_is_not_plaintext(self):
hashed = hash_password("mysecret123")
assert hashed != "mysecret123"
assert hashed.startswith("$2b$")
def test_verify_correct_password(self):
hashed = hash_password("testpass")
assert verify_password("testpass", hashed) is True
def test_reject_wrong_password(self):
hashed = hash_password("correct")
assert verify_password("wrong", hashed) is False
def test_different_hashes_for_same_password(self):
"""bcrypt uses a random salt, so two hashes of the same password differ."""
h1 = hash_password("same")
h2 = hash_password("same")
assert h1 != h2
# But both verify
assert verify_password("same", h1)
assert verify_password("same", h2)
# ---------------------------------------------------------------------------
# JWT tokens
# ---------------------------------------------------------------------------
class TestJWT:
def test_create_and_decode(self):
token = create_jwt_token({"sub": "alice"})
payload = decode_jwt_token(token)
assert payload["sub"] == "alice"
assert "exp" in payload
def test_token_contains_custom_data(self):
token = create_jwt_token({"sub": "bob", "role": "admin"})
payload = decode_jwt_token(token)
assert payload["role"] == "admin"
def test_expired_token_raises(self):
from datetime import timedelta
token = create_jwt_token(
{"sub": "charlie"}, expires_delta=timedelta(seconds=-1)
)
with pytest.raises(Exception):
decode_jwt_token(token)
def test_tampered_token_raises(self):
token = create_jwt_token({"sub": "dave"})
# Tamper with the token
tampered = token[:-5] + "XXXXX"
with pytest.raises(Exception):
decode_jwt_token(tampered)
# ---------------------------------------------------------------------------
# Fernet encryption (AES-256)
# ---------------------------------------------------------------------------
class TestFernetEncryption:
def test_encrypt_decrypt_dict(self):
data = {"scores": [0.5, 0.8], "timestamps": [1000.0, 2000.0]}
encrypted = encrypt_data(data)
assert isinstance(encrypted, str)
assert encrypted != str(data)
decrypted = decrypt_data(encrypted)
assert decrypted == data
def test_encrypt_decrypt_list(self):
data = [[1000.0, 0.5], [2000.0, 0.8]]
encrypted = encrypt_data(data)
decrypted = decrypt_data(encrypted)
assert decrypted == data
def test_encrypted_is_not_plaintext(self):
data = {"secret": "value"}
encrypted = encrypt_data(data)
assert "secret" not in encrypted
assert "value" not in encrypted
def test_decrypt_corrupted_returns_none(self):
result = decrypt_data("not-a-valid-ciphertext")
assert result is None
def test_encrypt_empty_list(self):
encrypted = encrypt_data([])
assert decrypt_data(encrypted) == []