"""Тесты для функций безопасности из 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