Files
chat/tests/test_all_endpoints_main_service.py
Andrew K. Choi 64171196b6
All checks were successful
continuous-integration/drone/push Build is passing
calendar features
2025-09-26 14:45:00 +09:00

218 lines
8.2 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
import requests
import json
import sys
import logging
from datetime import datetime, date, timedelta
from enum import Enum
# Настройка логирования
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Порт основного сервиса календаря
CALENDAR_SERVICE_PORT = 8004
# Валидный токен аутентификации
TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyOSIsImVtYWlsIjoidGVzdDJAZXhhbXBsZS5jb20iLCJleHAiOjE3NTg4NjQwMzV9.Ap4ZD5EtwhLXRtm6KjuFvXMlk6XA-3HtMbaGEu9jX6M"
# Мобильные типы записей и данных
class MobileEntryType(str, Enum):
MENSTRUATION = "MENSTRUATION"
OVULATION = "OVULATION"
SPOTTING = "SPOTTING"
DISCHARGE = "DISCHARGE"
PAIN = "PAIN"
MOOD = "MOOD"
class MobileMood(str, Enum):
HAPPY = "HAPPY"
SAD = "SAD"
ANXIOUS = "ANXIOUS"
IRRITABLE = "IRRITABLE"
ENERGETIC = "ENERGETIC"
TIRED = "TIRED"
NORMAL = "NORMAL"
class MobileSymptom(str, Enum):
CRAMPS = "CRAMPS"
HEADACHE = "HEADACHE"
BLOATING = "BLOATING"
FATIGUE = "FATIGUE"
NAUSEA = "NAUSEA"
BREAST_TENDERNESS = "BREAST_TENDERNESS"
ACNE = "ACNE"
BACKACHE = "BACKACHE"
def test_calendar_apis():
"""Тестирование всех API эндпоинтов календарного сервиса"""
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {TOKEN}"
}
base_url = f"http://localhost:{CALENDAR_SERVICE_PORT}"
logger.info(f"Тестирование основного сервиса календаря на порту {CALENDAR_SERVICE_PORT}")
# Проверяем доступность сервиса
if not check_service_available(base_url):
logger.error(f"Сервис календаря на порту {CALENDAR_SERVICE_PORT} недоступен!")
return 1
# 1. Тест стандартного формата на /api/v1/calendar/entries
standard_entry = {
"entry_date": (date.today() + timedelta(days=1)).isoformat(),
"entry_type": "period",
"flow_intensity": "medium",
"period_symptoms": "cramps",
"energy_level": 3,
"sleep_hours": 7,
"medications": "",
"symptoms": "headache",
"notes": f"Стандартный тест {datetime.now().isoformat()}"
}
standard_response = test_endpoint(
url=f"{base_url}/api/v1/calendar/entries",
method="POST",
data=standard_entry,
headers=headers,
description="Стандартный формат - /api/v1/calendar/entries"
)
# 2. Тест мобильного формата на /api/v1/calendar/entry
mobile_entry = {
"entry_date": date.today().isoformat(),
"entry_type": "MENSTRUATION",
"flow_intensity": 4,
"mood": "HAPPY",
"symptoms": "FATIGUE,HEADACHE",
"notes": f"Мобильный тест {datetime.now().isoformat()}"
}
mobile_response = test_endpoint(
url=f"{base_url}/api/v1/calendar/entry",
method="POST",
data=mobile_entry,
headers=headers,
description="Мобильный формат - /api/v1/calendar/entry"
)
# 3. Тест стандартного формата на /api/v1/entries (legacy)
legacy_entry = {
"entry_date": (date.today() + timedelta(days=2)).isoformat(),
"entry_type": "symptoms",
"flow_intensity": None,
"period_symptoms": "",
"energy_level": 4,
"sleep_hours": 8,
"medications": "vitamin",
"symptoms": "fatigue",
"notes": f"Тест legacy endpoint {datetime.now().isoformat()}"
}
legacy_response = test_endpoint(
url=f"{base_url}/api/v1/entries",
method="POST",
data=legacy_entry,
headers=headers,
description="Стандартный формат - /api/v1/entries (legacy)"
)
# 4. Тест стандартного формата на /api/v1/entry (без префикса /calendar)
entry_endpoint_entry = {
"entry_date": (date.today() + timedelta(days=3)).isoformat(),
"entry_type": "mood",
"mood": "happy",
"energy_level": 5,
"sleep_hours": 9,
"symptoms": "",
"medications": "",
"period_symptoms": "",
"notes": f"Тест /entry endpoint {datetime.now().isoformat()}"
}
entry_response = test_endpoint(
url=f"{base_url}/api/v1/entry",
method="POST",
data=entry_endpoint_entry,
headers=headers,
description="Стандартный формат - /api/v1/entry (без префикса)"
)
# 5. Проверка списка записей
get_entries_response = test_endpoint(
url=f"{base_url}/api/v1/calendar/entries",
method="GET",
headers=headers,
description="Получение списка записей"
)
if get_entries_response and get_entries_response.status_code == 200:
entries = get_entries_response.json()
logger.info(f"Всего записей в календаре: {len(entries)}")
if entries:
for i, entry in enumerate(entries[:5]): # Показываем первые 5 записей
logger.info(f"Запись {i+1}: ID={entry.get('id')}, Дата={entry.get('entry_date')}, Тип={entry.get('entry_type')}")
# Подсчитываем успешные тесты
tests = [standard_response, mobile_response, legacy_response, entry_response, get_entries_response]
success_count = sum(1 for test in tests if test and test.status_code in [200, 201])
expected_success = 5
if success_count >= expected_success:
logger.info(f"✅ Успешно пройдено {success_count}/{expected_success} тестов!")
return 0
else:
logger.error(f"❌ Пройдено только {success_count}/{expected_success} тестов")
return 1
def check_service_available(base_url):
"""Проверяет доступность сервиса"""
try:
response = requests.get(f"{base_url}/health", timeout=5)
return response.status_code == 200
except requests.exceptions.RequestException:
return False
def test_endpoint(url, method, headers, description, data=None):
"""Выполняет тест для конкретного эндпоинта"""
logger.info(f"\nТестирование: {description}")
logger.info(f"URL: {url}, Метод: {method}")
if data:
logger.info(f"Данные: {json.dumps(data, indent=2)}")
try:
if method.upper() == "GET":
response = requests.get(url, headers=headers, timeout=10)
elif method.upper() == "POST":
response = requests.post(url, headers=headers, json=data, timeout=10)
else:
logger.error(f"Неподдерживаемый метод: {method}")
return None
logger.info(f"Статус ответа: {response.status_code}")
# Для успешных ответов логируем детали
if response.status_code in [200, 201]:
logger.info("✅ Тест успешно пройден!")
try:
response_data = response.json()
if isinstance(response_data, dict):
logger.info(f"Ответ: ID={response_data.get('id')}, Тип={response_data.get('entry_type')}")
except ValueError:
logger.info(f"Ответ не в формате JSON: {response.text[:100]}...")
else:
logger.warning(f"❌ Тест не пройден. Статус: {response.status_code}")
logger.warning(f"Ответ: {response.text}")
return response
except requests.exceptions.RequestException as e:
logger.error(f"❌ Ошибка при выполнении запроса: {str(e)}")
return None
if __name__ == "__main__":
sys.exit(test_calendar_apis())