import pytest from backend.auth.jwt import create_access_token, verify_access_token, generate_refresh_token def test_create_and_verify_access_token(): token = create_access_token("user-123", "student", "batch-456", "test@example.com") payload = verify_access_token(token) assert payload["user_id"] == "user-123" assert payload["role"] == "student" assert payload["batch_id"] == "batch-456" assert payload["email"] == "test@example.com" def test_verify_invalid_token_raises(): with pytest.raises(ValueError): verify_access_token("not.a.valid.token") def test_generate_refresh_token_returns_pair(): raw, hashed = generate_refresh_token() assert isinstance(raw, str) assert isinstance(hashed, str) assert raw != hashed assert len(raw) > 20 def test_refresh_token_hashes_consistently(): import hashlib raw, hashed = generate_refresh_token() assert hashlib.sha256(raw.encode()).hexdigest() == hashed def test_expired_token_raises(): from datetime import datetime, timedelta, timezone from jose import jwt as jose_jwt import os secret = os.getenv("JWT_SECRET", "dev-secret-key-32-chars-minimum!!") expired_payload = { "user_id": "u1", "role": "student", "batch_id": None, "email": "a@b.com", "exp": datetime.now(timezone.utc) - timedelta(seconds=1), } expired_token = jose_jwt.encode(expired_payload, secret, algorithm="HS256") with pytest.raises(ValueError): verify_access_token(expired_token) def test_wrong_secret_raises(): token = create_access_token("u1", "student", None, "a@b.com") from jose import jwt as jose_jwt # Tamper: re-sign with different secret import os wrong_secret = "wrong-secret-completely-different!!" payload = jose_jwt.decode(token, os.getenv("JWT_SECRET", "dev-secret-key-32-chars-minimum!!"), algorithms=["HS256"]) tampered = jose_jwt.encode(payload, wrong_secret, algorithm="HS256") with pytest.raises(ValueError): verify_access_token(tampered) def test_batch_id_none_roundtrip(): token = create_access_token("u1", "student", None, "a@b.com") payload = verify_access_token(token) assert payload["batch_id"] is None