163 lines
5.4 KiB
Python
163 lines
5.4 KiB
Python
# DRF Rack
|
|
# Библиотека классов расширений для Django REST Framework
|
|
#
|
|
# Автор: Николай В. Анохин <n.anokhin@xeaf.net>
|
|
# Все права защищены. Лицензия: MIT
|
|
|
|
"""
|
|
Описание класса CryptoTests
|
|
"""
|
|
from django.db import models
|
|
from django.test import SimpleTestCase
|
|
|
|
from net.xeaf.rack.managers import CryptoManager
|
|
from net.xeaf.rack.models import SessionModel
|
|
|
|
|
|
class CryptoManagerTests(SimpleTestCase):
|
|
"""
|
|
Тесты для класса CryptoManager
|
|
"""
|
|
|
|
def test_gen_token(self):
|
|
"""
|
|
Тест генерации токена
|
|
"""
|
|
|
|
token = CryptoManager.gen_token()
|
|
self.assertEqual(len(token), CryptoManager.DEFAULT_TOKEN_LENGTH)
|
|
self._assert_lower_hex(token)
|
|
|
|
def test_gen_token_length(self):
|
|
"""
|
|
Тест генерации токена с указанием длины
|
|
"""
|
|
|
|
token = CryptoManager.gen_token(length=15)
|
|
self.assertEqual(len(token), 15)
|
|
|
|
def test_gen_token_different(self):
|
|
"""
|
|
Тест генерации разных токенов
|
|
"""
|
|
|
|
token1 = CryptoManager.gen_token()
|
|
token2 = CryptoManager.gen_token()
|
|
self.assertNotEqual(token1, token2)
|
|
|
|
def test_gen_pin_code(self):
|
|
"""
|
|
Тест генерации PIN-кода
|
|
"""
|
|
|
|
pin_code = CryptoManager.gen_pin_code()
|
|
self.assertEqual(len(pin_code), CryptoManager.DEFAULT_PIN_CODE_LENGTH)
|
|
self.assertTrue(all(c in CryptoManager.DEFAULT_PIN_CODE_ALPHABET for c in pin_code))
|
|
|
|
def test_gen_pin_code_length(self):
|
|
"""
|
|
Тест генерации PIN-кода с указанием длины
|
|
"""
|
|
|
|
pin_code = CryptoManager.gen_pin_code(length=8)
|
|
self.assertEqual(len(pin_code), 8)
|
|
self.assertTrue(all(c in CryptoManager.DEFAULT_PIN_CODE_ALPHABET for c in pin_code))
|
|
|
|
def test_gen_pin_code_alphabet(self):
|
|
"""
|
|
Тест генерации PIN-кода с указанием алфавита
|
|
"""
|
|
|
|
letters = 'ABCD'
|
|
pin_code = CryptoManager.gen_pin_code(alphabet=letters)
|
|
self.assertEqual(len(pin_code), CryptoManager.DEFAULT_PIN_CODE_LENGTH)
|
|
self.assertTrue(all(c in letters for c in pin_code))
|
|
|
|
def test_gen_pin_code_different(self):
|
|
"""
|
|
Тест генерации разных PIN-кодов
|
|
"""
|
|
|
|
pin_code_1 = CryptoManager.gen_pin_code()
|
|
pin_code_2 = CryptoManager.gen_pin_code()
|
|
self.assertNotEqual(pin_code_1, pin_code_2)
|
|
|
|
def test_gen_slug(self):
|
|
"""
|
|
Тест генерации slug
|
|
"""
|
|
|
|
pfx = 'test'
|
|
slug = CryptoManager.gen_slug(pfx)
|
|
self.assertEqual(len(slug), CryptoManager.DEFAULT_SLUG_LENGTH)
|
|
self.assertEqual(slug[:len(pfx)], pfx)
|
|
self._assert_lower_hex(slug[len(pfx):])
|
|
|
|
def test_gen_slug_length(self):
|
|
"""
|
|
Тест генерации slug с указанием длины
|
|
"""
|
|
|
|
pfx = 'test'
|
|
slug = CryptoManager.gen_slug(pfx, length=16)
|
|
self.assertEqual(len(slug), 16)
|
|
|
|
def test_gen_slug_prefix(self):
|
|
"""
|
|
Тест генерации slug с длинным префиксом
|
|
"""
|
|
|
|
pfx = 'test_test_test'
|
|
slug = CryptoManager.gen_slug(pfx)
|
|
self.assertEqual(slug, pfx)
|
|
|
|
def test_slug_different(self):
|
|
"""
|
|
Тест генерации разных slug
|
|
"""
|
|
|
|
slug_1 = CryptoManager.gen_slug('test')
|
|
slug_2 = CryptoManager.gen_slug('test')
|
|
self.assertNotEqual(slug_1, slug_2)
|
|
|
|
def _assert_lower_hex(self, value: str):
|
|
"""
|
|
Проверяет, что строка состоит из символов в нижнем регистре и шестнадцатеричных цифр
|
|
|
|
:param value: Проверяемая строка
|
|
"""
|
|
|
|
self.assertRegex(value, r'^[0-9a-f]+$')
|
|
|
|
def test_crypto_manager_should_generate_default_length_by_default(self) -> None:
|
|
"""
|
|
Гарантируем, что генератор без параметров использует базовую длину
|
|
"""
|
|
|
|
generated_token = CryptoManager.gen_token()
|
|
self.assertEqual(len(generated_token), CryptoManager.DEFAULT_TOKEN_LENGTH)
|
|
|
|
def test_session_model_field_must_match_max_token_length_constant(self) -> None:
|
|
"""
|
|
Защита схемы БД: max_length в миграциях равен MAX_TOKEN_LENGTH
|
|
"""
|
|
|
|
field = SessionModel._meta.get_field("token")
|
|
self.assertIsInstance(field, models.CharField)
|
|
db_max_length = field.max_length
|
|
self.assertIsInstance(db_max_length, int)
|
|
self.assertEqual(db_max_length, SessionModel.MAX_TOKEN_LENGTH)
|
|
|
|
def test_crypto_manager_should_raise_value_error_if_length_exceeds_max(self) -> None:
|
|
"""
|
|
Проверка Fail-Fast контракта: при превышении лимита СУБД выбрасывается ValueError
|
|
"""
|
|
|
|
excessive_length = SessionModel.MAX_TOKEN_LENGTH + 1
|
|
|
|
# Система обязана громко упасть с ValueError
|
|
with self.assertRaises(ValueError) as context:
|
|
CryptoManager.gen_token(length=excessive_length)
|
|
|
|
self.assertIn(f"Token length must be less than {SessionModel.MAX_TOKEN_LENGTH}", str(context.exception))
|