"""Тесты для функций безопасности из app.utils.security.""" import hashlib import pytest from app.utils.security import generate_api_token, hash_api_token def test_hash_api_token_default_algorithm_matches_hashlib() -> None: """Проверяем, что алгоритм по умолчанию совпадает с hashlib.sha256.""" sample = "secret-token" # Самостоятельно считаем эталонное значение. expected = hashlib.sha256(sample.encode("utf-8")).hexdigest() # Сравниваем с функцией проекта. assert hash_api_token(sample) == expected @pytest.mark.parametrize( "algorithm,hash_factory", [ ("sha256", hashlib.sha256), ("sha384", hashlib.sha384), ("sha512", hashlib.sha512), ], ) def test_hash_api_token_accepts_supported_algorithms(algorithm, hash_factory) -> None: """Каждый поддерживаемый алгоритм должен выдавать корректный результат.""" sample = "token-value" expected = hash_factory(sample.encode("utf-8")).hexdigest() assert hash_api_token(sample, algorithm=algorithm) == expected def test_hash_api_token_rejects_unknown_algorithm() -> None: """Некорректное имя алгоритма должно приводить к ValueError.""" with pytest.raises(ValueError): hash_api_token("value", algorithm="md5") # type: ignore[arg-type] @pytest.mark.parametrize("length", [8, 24, 48, 256]) def test_generate_api_token_respects_length_bounds(length: int) -> None: """Функция должна ограничивать длину токена безопасным диапазоном.""" token = generate_api_token(length) clamped = max(24, min(length, 128)) assert len(token) >= clamped # token_urlsafe расширяет строку, поэтому добавляем запас по длине. assert len(token) <= clamped * 2 def test_generate_api_token_produces_random_values() -> None: """Два последовательных вызова должны выдавать разные токены.""" first = generate_api_token(48) second = generate_api_token(48) assert first != second