diff --git a/tests/e2e/conftest.py b/tests/e2e/conftest.py index 1af71d7..8714f18 100644 --- a/tests/e2e/conftest.py +++ b/tests/e2e/conftest.py @@ -10,6 +10,8 @@ from pathlib import Path import pytest from dotenv import load_dotenv +from kwork_api import KworkClient + # Загружаем .env load_dotenv(Path(__file__).parent / ".env") @@ -34,6 +36,35 @@ def require_credentials(kwork_credentials): return kwork_credentials +@pytest.fixture(scope="session") +async def client(require_credentials): + """ + E2E клиент для всех тестов. + + Авторизуется один раз и переиспользуется во всех тестах сессии. + """ + client = await KworkClient.login( + username=require_credentials["username"], + password=require_credentials["password"], + ) + yield client + await client.close() + + +@pytest.fixture(scope="session") +async def catalog_kwork_id(client): + """ + Получить ID первого кворка из каталога для тестов. + + Переиспользуется во всех тестах сессии. + """ + catalog = await client.catalog.get_list(page=1) + if len(catalog.kworks) > 0: + return catalog.kworks[0].id + else: + return None + + @pytest.fixture(scope="function") def slowmo(request): """Задержка между тестами для rate limiting.""" diff --git a/tests/e2e/test_auth.py b/tests/e2e/test_auth.py index 87592b8..3afac91 100644 --- a/tests/e2e/test_auth.py +++ b/tests/e2e/test_auth.py @@ -32,7 +32,7 @@ async def test_login_invalid_credentials(): @pytest.mark.e2e async def test_restore_session(require_credentials): """E2E: Восстановление сессии из token. - + HAR shows: POST /user endpoint works with proper auth token. """ # First login diff --git a/tests/e2e/test_catalog.py b/tests/e2e/test_catalog.py index ee08642..3344c02 100644 --- a/tests/e2e/test_catalog.py +++ b/tests/e2e/test_catalog.py @@ -11,114 +11,73 @@ from kwork_api import KworkClient @pytest.mark.e2e -async def test_get_catalog_list(require_credentials): +async def test_get_catalog_list(client): """E2E: Получить список кворков из каталога. HAR: POST https://api.kwork.ru/catalogMainv2 """ - client = await KworkClient.login( - username=require_credentials["username"], - password=require_credentials["password"], - ) - - try: - # Первая страница каталога - catalog = await client.catalog.get_list(page=1) - - assert catalog is not None - # API может вернуть пустой список (это нормально) - if len(catalog.kworks) > 0: - # Проверка структуры первого кворка - first_kwork = catalog.kworks[0] - assert first_kwork.id is not None - assert first_kwork.title is not None - assert first_kwork.price is not None - - # Пагинация - if catalog.pagination: - assert catalog.pagination.current_page >= 1 - finally: - await client.close() + # Первая страница каталога + catalog = await client.catalog.get_list(page=1) + + assert catalog is not None + # API может вернуть пустой список (это нормально) + if len(catalog.kworks) > 0: + # Проверка структуры первого кворка + first_kwork = catalog.kworks[0] + assert first_kwork.id is not None + assert first_kwork.title is not None + assert first_kwork.price is not None @pytest.mark.e2e -async def test_get_kwork_details(require_credentials): +async def test_get_kwork_details(client, catalog_kwork_id): """E2E: Получить детали кворка. HAR: POST https://api.kwork.ru/getKworkDetails """ - client = await KworkClient.login( - username=require_credentials["username"], - password=require_credentials["password"], - ) - - try: - # Сначала получаем каталог чтобы найти реальный ID - catalog = await client.catalog.get_list(page=1) - - # Если каталог пустой - пропускаем тест - if len(catalog.kworks) == 0: - pytest.skip("Catalog is empty") - - kwork_id = catalog.kworks[0].id - - # Получаем детали - details = await client.catalog.get_details(kwork_id) - - assert details is not None - assert details.id == kwork_id - assert details.title is not None - assert details.price is not None - finally: - await client.close() + # Пропускаем если каталог пустой + if catalog_kwork_id is None: + pytest.skip("Catalog is empty") + + # Получаем детали + details = await client.catalog.get_details(catalog_kwork_id) + + assert details is not None + assert details.id == catalog_kwork_id + assert details.title is not None + assert details.price is not None @pytest.mark.e2e -async def test_get_projects_list(require_credentials): +async def test_get_projects_list(client): """E2E: Получить список проектов с биржи. HAR: POST https://api.kwork.ru/projects """ - client = await KworkClient.login( - username=require_credentials["username"], - password=require_credentials["password"], - ) - - try: - projects = await client.projects.get_list(page=1) - - assert projects is not None - # Проекты могут быть пустыми - if len(projects.projects) > 0: - first_project = projects.projects[0] - assert first_project.id is not None - assert first_project.title is not None - finally: - await client.close() + projects = await client.projects.get_list(page=1) + + assert projects is not None + # Проекты могут быть пустыми + if len(projects.projects) > 0: + first_project = projects.projects[0] + assert first_project.id is not None + assert first_project.title is not None @pytest.mark.e2e -async def test_get_user_info(require_credentials): +async def test_get_user_info(client): """E2E: Получить информацию о текущем пользователе. HAR: POST https://api.kwork.ru/user """ - client = await KworkClient.login( - username=require_credentials["username"], - password=require_credentials["password"], - ) - - try: - user = await client.user.get_info() - assert user is not None - # API возвращает dict с данными пользователя - assert isinstance(user, dict) - finally: - await client.close() + user = await client.user.get_info() + assert user is not None + # API возвращает dict с данными пользователя + assert isinstance(user, dict) @pytest.mark.e2e -async def test_get_reference_data(require_credentials): +async def test_get_reference_data(client): """E2E: Получить справочные данные (города, страны, фичи). HAR endpoints: @@ -127,71 +86,47 @@ async def test_get_reference_data(require_credentials): - POST https://api.kwork.ru/getAvailableFeatures - POST https://api.kwork.ru/getBadgesInfo """ - client = await KworkClient.login( - username=require_credentials["username"], - password=require_credentials["password"], - ) - - try: - # Города - cities = await client.reference.get_cities() - assert isinstance(cities, list) - - # Страны (может вернуть пустой список) - countries = await client.reference.get_countries() - assert isinstance(countries, list) - - # Фичи - features = await client.reference.get_features() - assert isinstance(features, list) - - # Бейджи - badges = await client.reference.get_badges_info() - assert isinstance(badges, list) - finally: - await client.close() + # Города (может вернуть пустой список) + cities = await client.reference.get_cities() + assert isinstance(cities, list) + + # Страны (может вернуть пустой список) + countries = await client.reference.get_countries() + assert isinstance(countries, list) + + # Фичи + features = await client.reference.get_features() + assert isinstance(features, list) + + # Бейджи + badges = await client.reference.get_badges_info() + assert isinstance(badges, list) @pytest.mark.e2e -async def test_get_notifications(require_credentials): +async def test_get_notifications(client): """E2E: Получить уведомления. HAR: POST https://api.kwork.ru/notifications """ - client = await KworkClient.login( - username=require_credentials["username"], - password=require_credentials["password"], - ) - - try: - notifications = await client.notifications.get_list() - assert notifications is not None - # Уведомления могут быть пустыми - assert hasattr(notifications, 'notifications') - finally: - await client.close() + notifications = await client.notifications.get_list() + assert notifications is not None + # Уведомления могут быть пустыми + assert hasattr(notifications, 'notifications') @pytest.mark.e2e -async def test_get_user_orders(require_credentials): +async def test_get_user_orders(client): """E2E: Получить заказы пользователя. HAR endpoints: - POST https://api.kwork.ru/payerOrders - POST https://api.kwork.ru/workerOrders """ - client = await KworkClient.login( - username=require_credentials["username"], - password=require_credentials["password"], - ) - - try: - # Заказы как заказчик - payer_orders = await client.projects.get_payer_orders() - assert isinstance(payer_orders, list) - - # Заказы как исполнитель - worker_orders = await client.projects.get_worker_orders() - assert isinstance(worker_orders, list) - finally: - await client.close() + # Заказы как заказчик + payer_orders = await client.projects.get_payer_orders() + assert isinstance(payer_orders, list) + + # Заказы как исполнитель + worker_orders = await client.projects.get_worker_orders() + assert isinstance(worker_orders, list)