/
gr.ev.vl
/
TestGen
Обзор
Документация
Войти
/
gr.ev.vl
/
TestGen
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/tests/integration/api/test_auth_api.py
186 строк
8 KB
gr.ev.vl
Initial commit
06 июн 2026, 02:41
06 июн 2026, 02:41
02fb1fb
Код
Авторство
О чём код?
""" Интеграционные тесты API аутентификации. Тестирует реальные HTTP-запросы с реальной БД. """ import logging import pytest from httpx import AsyncClient logger = logging.getLogger("test.integration.api.auth") class TestAuthAPI: """Интеграционные тесты аутентификации.""" @pytest.mark.asyncio async def test_login_success_returns_200_and_tokens(self, client: AsyncClient, db_session): """Успешный вход: 200 + токены.""" logger.info("Тест: POST /auth/login → 200 + токены") from src.testgen.domain.repositories.user import UserRepository from src.testgen.core.utils.hashing import hash_password user_repo = UserRepository(db_session) await user_repo.create( email="api_login@test.com", password_hash=hash_password("ApiPass123!"), full_name="API Login User", role="teacher", is_active=True, ) await db_session.flush() response = await client.post("/api/v1/auth/login", json={ "email": "api_login@test.com", "password": "ApiPass123!", }) logger.info(f"Response: status={response.status_code}, body={response.text[:200]}") assert response.status_code == 200, f"Ожидался 200, получен {response.status_code}" data = response.json() assert "access_token" in data, "access_token отсутствует в ответе" assert "refresh_token" in data, "refresh_token отсутствует в ответе" assert data["token_type"] == "bearer" logger.info("✓ Успешный вход подтверждён") @pytest.mark.asyncio async def test_login_wrong_password_returns_401(self, client: AsyncClient, db_session): """Неверный пароль: 401.""" logger.info("Тест: POST /auth/login с неверным паролем → 401") from src.testgen.domain.repositories.user import UserRepository from src.testgen.core.utils.hashing import hash_password user_repo = UserRepository(db_session) await user_repo.create( email="wrong@test.com", password_hash=hash_password("RightPass123!"), full_name="Wrong Pass", role="teacher", is_active=True, ) await db_session.flush() response = await client.post("/api/v1/auth/login", json={ "email": "wrong@test.com", "password": "WrongPass456!", }) logger.info(f"Response: status={response.status_code}") assert response.status_code == 401 data = response.json() assert data["error"]["code"] == "authentication_error" logger.info("✓ 401 получен") @pytest.mark.asyncio async def test_login_missing_fields_returns_422(self, client: AsyncClient): """Отсутствуют обязательные поля: 422.""" logger.info("Тест: POST /auth/login без полей → 422") response = await client.post("/api/v1/auth/login", json={}) logger.info(f"Response: status={response.status_code}") assert response.status_code == 422 logger.info("✓ 422 получен") @pytest.mark.asyncio async def test_get_me_returns_user_info(self, client: AsyncClient, auth_headers): """GET /auth/me возвращает информацию о пользователе.""" logger.info("Тест: GET /auth/me с токеном → 200 + user info") response = await client.get("/api/v1/auth/me", headers=auth_headers) logger.info(f"Response: status={response.status_code}, body={response.text}") assert response.status_code == 200 data = response.json() assert data["email"] == "teacher_test@example.com" assert data["role"] == "teacher" assert data["full_name"] == "Test Teacher" logger.info(f"✓ Информация получена: {data['email']}") @pytest.mark.asyncio async def test_get_me_without_token_returns_401(self, client: AsyncClient): """GET /auth/me без токена: 401.""" logger.info("Тест: GET /auth/me без токена → 401") response = await client.get("/api/v1/auth/me") logger.info(f"Response: status={response.status_code}") assert response.status_code == 401 logger.info("✓ 401 получен") @pytest.mark.asyncio async def test_refresh_token_returns_new_tokens(self, client: AsyncClient, db_session): """Обновление токенов через refresh_token.""" logger.info("Тест: POST /auth/refresh → новые токены") from src.testgen.domain.repositories.user import UserRepository from src.testgen.core.utils.hashing import hash_password user_repo = UserRepository(db_session) await user_repo.create( email="refresh_api@test.com", password_hash=hash_password("RefreshPass123!"), full_name="Refresh API User", role="teacher", is_active=True, ) await db_session.flush() # Вход login_resp = await client.post("/api/v1/auth/login", json={ "email": "refresh_api@test.com", "password": "RefreshPass123!", }) refresh_token = login_resp.json()["refresh_token"] logger.info(f"✓ Refresh-токен получен: {refresh_token[:20]}...") # Обновление response = await client.post("/api/v1/auth/refresh", json={ "refresh_token": refresh_token, }) logger.info(f"Response: status={response.status_code}") assert response.status_code == 200 data = response.json() assert "access_token" in data assert "refresh_token" in data # Токены должны отличаться assert data["access_token"] != login_resp.json()["access_token"] logger.info("✓ Токены обновлены") @pytest.mark.asyncio async def test_logout_invalidates_refresh_token(self, client: AsyncClient, db_session): """Выход из системы делает refresh-токен недействительным.""" logger.info("Тест: POST /auth/logout → отзыв токена") from src.testgen.domain.repositories.user import UserRepository from src.testgen.core.utils.hashing import hash_password user_repo = UserRepository(db_session) await user_repo.create( email="logout_api@test.com", password_hash=hash_password("LogoutPass123!"), full_name="Logout API User", role="teacher", is_active=True, ) await db_session.flush() # Вход login_resp = await client.post("/api/v1/auth/login", json={ "email": "logout_api@test.com", "password": "LogoutPass123!", }) refresh_token = login_resp.json()["refresh_token"] # Выход logout_resp = await client.post("/api/v1/auth/logout", json={ "refresh_token": refresh_token, }, headers={"Authorization": f"Bearer {login_resp.json()['access_token']}"}) assert logout_resp.status_code == 200 logger.info("✓ Выход выполнен") # Попытка обновить отозванный токен refresh_resp = await client.post("/api/v1/auth/refresh", json={ "refresh_token": refresh_token, }) assert refresh_resp.status_code == 401 logger.info("✓ Отозванный токен отклонён")