feat: тесты
This commit is contained in:
107
tests/test_auth.py
Normal file
107
tests/test_auth.py
Normal file
@@ -0,0 +1,107 @@
|
||||
"""Тесты авторизации через Telegram."""
|
||||
|
||||
import datetime
|
||||
|
||||
import pytest
|
||||
from fastapi import HTTPException
|
||||
|
||||
from src import domain, dto, usecase
|
||||
from tests.conftest import MockDatabase, MockTelegramWriter
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_new_user_registration(usecases: usecase.Usecase, mock_telegram: MockTelegramWriter) -> None:
|
||||
"""Новый пользователь регистрируется через Telegram."""
|
||||
input_data = dto.TelegramLoginInput(telegram_id=123456, username='testuser', chat_id=123456)
|
||||
|
||||
await usecases.telegram_login(input_data)
|
||||
|
||||
# Проверяем, что пользователь создан
|
||||
user = await usecases.database.get_user(telegram_id=123456)
|
||||
assert user is not None
|
||||
assert user.telegram_id == 123456
|
||||
assert user.username == 'testuser'
|
||||
|
||||
# Проверяем, что бот отправил сообщение с кнопкой
|
||||
assert len(mock_telegram.sent_messages) == 1
|
||||
msg = mock_telegram.sent_messages[0]
|
||||
assert msg['button'] is not None
|
||||
assert 'token=' in msg['button']['url']
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_existing_user_login(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||||
"""Существующий пользователь получает токен для входа."""
|
||||
# Создаём пользователя
|
||||
user = domain.User(telegram_id=123456, username='testuser')
|
||||
await mock_database.create_user(user)
|
||||
|
||||
input_data = dto.TelegramLoginInput(telegram_id=123456, username='testuser', chat_id=123456)
|
||||
await usecases.telegram_login(input_data)
|
||||
|
||||
# Проверяем, что не создался второй пользователь
|
||||
users_count = len(mock_database.users)
|
||||
assert users_count == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_login_token_success(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||||
"""Валидный токен обменивается на JWT."""
|
||||
user = domain.User(telegram_id=123456, username='testuser')
|
||||
await mock_database.create_user(user)
|
||||
|
||||
token = 'test_token_123'
|
||||
expires_at = datetime.datetime.now(datetime.UTC) + datetime.timedelta(minutes=10)
|
||||
await mock_database.create_login_token(user.id, token, expires_at)
|
||||
|
||||
result = await usecases.validate_login_token(dto.ValidateLoginTokenInput(token=token))
|
||||
|
||||
assert result.access_token.startswith('jwt_token_')
|
||||
assert str(user.id) in result.access_token
|
||||
|
||||
# Проверяем, что токен помечен как использованный
|
||||
login_token = await mock_database.get_login_token(token)
|
||||
assert login_token is not None
|
||||
assert login_token.used_at is not None
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_login_token_not_found(usecases: usecase.Usecase) -> None:
|
||||
"""Несуществующий токен вызывает ошибку."""
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
await usecases.validate_login_token(dto.ValidateLoginTokenInput(token='nonexistent'))
|
||||
assert exc_info.value.status_code == 404
|
||||
assert 'Login token not found' in str(exc_info.value.detail)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_login_token_already_used(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||||
"""Использованный токен вызывает ошибку."""
|
||||
user = domain.User(telegram_id=123456, username='testuser')
|
||||
await mock_database.create_user(user)
|
||||
|
||||
token = 'test_token_123'
|
||||
expires_at = datetime.datetime.now(datetime.UTC) + datetime.timedelta(minutes=10)
|
||||
await mock_database.create_login_token(user.id, token, expires_at)
|
||||
await mock_database.mark_token_as_used(token)
|
||||
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
await usecases.validate_login_token(dto.ValidateLoginTokenInput(token=token))
|
||||
assert exc_info.value.status_code == 400
|
||||
assert 'already been used' in str(exc_info.value.detail)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_validate_login_token_expired(usecases: usecase.Usecase, mock_database: MockDatabase) -> None:
|
||||
"""Истекший токен вызывает ошибку."""
|
||||
user = domain.User(telegram_id=123456, username='testuser')
|
||||
await mock_database.create_user(user)
|
||||
|
||||
token = 'test_token_123'
|
||||
expires_at = datetime.datetime.now(datetime.UTC) - datetime.timedelta(minutes=1)
|
||||
await mock_database.create_login_token(user.id, token, expires_at)
|
||||
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
await usecases.validate_login_token(dto.ValidateLoginTokenInput(token=token))
|
||||
assert exc_info.value.status_code == 400
|
||||
assert 'expired' in str(exc_info.value.detail)
|
||||
Reference in New Issue
Block a user