This commit is contained in:
347
tests/test_nutrition_api.py
Executable file
347
tests/test_nutrition_api.py
Executable file
@@ -0,0 +1,347 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Скрипт для тестирования API сервиса питания (Nutrition Service)
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import requests
|
||||
from datetime import datetime
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Загружаем .env файл
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
env_path = os.path.join(current_dir, ".env")
|
||||
load_dotenv(env_path)
|
||||
print(f"✅ Загружен .env из: {env_path}")
|
||||
|
||||
# Базовый URL API
|
||||
BASE_URL = os.environ.get("NUTRITION_API_URL", "http://localhost:8006/api/v1/nutrition")
|
||||
AUTH_URL = os.environ.get("AUTH_API_URL", "http://localhost:8001/api/v1/auth")
|
||||
|
||||
# Настройки для тестовых данных
|
||||
TEST_USER = {
|
||||
"username": "test_nutrition_user",
|
||||
"password": "Test123!",
|
||||
"email": "test_nutrition@example.com",
|
||||
"first_name": "Test",
|
||||
"last_name": "Nutrition",
|
||||
"phone": "+79991234999"
|
||||
}
|
||||
|
||||
def get_auth_token():
|
||||
"""Получение токена авторизации"""
|
||||
print("\n🔑 Получаем токен авторизации...")
|
||||
|
||||
# Пытаемся сначала войти
|
||||
try:
|
||||
login_data = {
|
||||
"username": TEST_USER["username"],
|
||||
"password": TEST_USER["password"]
|
||||
}
|
||||
|
||||
login_response = requests.post(
|
||||
f"{AUTH_URL}/login",
|
||||
json=login_data
|
||||
)
|
||||
|
||||
if login_response.status_code == 200:
|
||||
token = login_response.json().get("access_token")
|
||||
print("✅ Успешный вход в систему!")
|
||||
return token
|
||||
except Exception as e:
|
||||
print(f"⚠️ Ошибка при попытке входа: {e}")
|
||||
|
||||
# Если вход не удался, пробуем регистрацию
|
||||
try:
|
||||
register_response = requests.post(
|
||||
f"{AUTH_URL}/register",
|
||||
json=TEST_USER
|
||||
)
|
||||
|
||||
if register_response.status_code == 201:
|
||||
print("✅ Пользователь успешно зарегистрирован!")
|
||||
|
||||
# Теперь входим с новыми учетными данными
|
||||
login_data = {
|
||||
"username": TEST_USER["username"],
|
||||
"password": TEST_USER["password"]
|
||||
}
|
||||
|
||||
login_response = requests.post(
|
||||
f"{AUTH_URL}/login",
|
||||
json=login_data
|
||||
)
|
||||
|
||||
if login_response.status_code == 200:
|
||||
token = login_response.json().get("access_token")
|
||||
print("✅ Успешный вход в систему!")
|
||||
return token
|
||||
except Exception as e:
|
||||
print(f"❌ Ошибка при регистрации: {e}")
|
||||
|
||||
print("❌ Не удалось получить токен авторизации")
|
||||
return None
|
||||
|
||||
def search_food(token, query="apple", max_results=5):
|
||||
"""Поиск продуктов питания"""
|
||||
print(f"\n🔍 Поиск продуктов по запросу '{query}'...")
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
data = {
|
||||
"query": query,
|
||||
"max_results": max_results
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/search",
|
||||
json=data,
|
||||
headers=headers
|
||||
)
|
||||
|
||||
print(f"📥 Код ответа: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
results = response.json()
|
||||
print(f"✅ Найдено продуктов: {len(results)}")
|
||||
|
||||
# Выводим первые 3 результата
|
||||
for i, food in enumerate(results[:3]):
|
||||
print(f" {i+1}. [{food.get('id')}] {food.get('name')}")
|
||||
print(f" {food.get('description')}")
|
||||
print(f" Калории: {food.get('calories')} ккал/100г")
|
||||
|
||||
return results
|
||||
else:
|
||||
print(f"❌ Ошибка при поиске: {response.status_code}")
|
||||
print(response.text)
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Исключение при поиске: {e}")
|
||||
return None
|
||||
|
||||
def add_diary_entry(token, food_id=1):
|
||||
"""Добавление записи в дневник питания"""
|
||||
print(f"\n📝 Добавление записи в дневник питания (продукт ID: {food_id})...")
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
data = {
|
||||
"food_item_id": food_id,
|
||||
"entry_date": today,
|
||||
"meal_type": "breakfast",
|
||||
"quantity": 1.0,
|
||||
"unit": "piece",
|
||||
"notes": "Тестовая запись"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/diary",
|
||||
json=data,
|
||||
headers=headers
|
||||
)
|
||||
|
||||
print(f"📥 Код ответа: {response.status_code}")
|
||||
|
||||
if response.status_code in [200, 201]:
|
||||
result = response.json()
|
||||
print("✅ Запись успешно добавлена в дневник питания!")
|
||||
print(f" ID записи: {result.get('id')}")
|
||||
print(f" Калории: {result.get('calories')} ккал")
|
||||
return result
|
||||
else:
|
||||
print(f"❌ Ошибка при добавлении записи: {response.status_code}")
|
||||
print(response.text)
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Исключение при добавлении записи: {e}")
|
||||
return None
|
||||
|
||||
def get_diary_entries(token):
|
||||
"""Получение записей дневника за текущий день"""
|
||||
print("\n📋 Получение записей дневника питания...")
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{BASE_URL}/diary?date={today}",
|
||||
headers=headers
|
||||
)
|
||||
|
||||
print(f"📥 Код ответа: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
results = response.json()
|
||||
print(f"✅ Получено записей: {len(results)}")
|
||||
|
||||
# Выводим записи
|
||||
for i, entry in enumerate(results):
|
||||
print(f" {i+1}. Прием пищи: {entry.get('meal_type')}")
|
||||
print(f" Продукт ID: {entry.get('food_item_id')}")
|
||||
print(f" Калории: {entry.get('calories')} ккал")
|
||||
|
||||
return results
|
||||
else:
|
||||
print(f"❌ Ошибка при получении записей: {response.status_code}")
|
||||
print(response.text)
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Исключение при получении записей: {e}")
|
||||
return None
|
||||
|
||||
def add_water_entry(token, amount_ml=250):
|
||||
"""Добавление записи о потреблении воды"""
|
||||
print(f"\n💧 Добавление записи о потреблении воды ({amount_ml} мл)...")
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
data = {
|
||||
"amount_ml": amount_ml,
|
||||
"entry_date": today,
|
||||
"notes": "Тестовая запись"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/water",
|
||||
json=data,
|
||||
headers=headers
|
||||
)
|
||||
|
||||
print(f"📥 Код ответа: {response.status_code}")
|
||||
|
||||
if response.status_code in [200, 201]:
|
||||
result = response.json()
|
||||
print("✅ Запись о потреблении воды успешно добавлена!")
|
||||
print(f" ID записи: {result.get('id')}")
|
||||
print(f" Объем: {result.get('amount_ml')} мл")
|
||||
return result
|
||||
else:
|
||||
print(f"❌ Ошибка при добавлении записи о воде: {response.status_code}")
|
||||
print(response.text)
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Исключение при добавлении записи о воде: {e}")
|
||||
return None
|
||||
|
||||
def add_activity_entry(token):
|
||||
"""Добавление записи о физической активности"""
|
||||
print("\n🏃♀️ Добавление записи о физической активности...")
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
data = {
|
||||
"entry_date": today,
|
||||
"activity_type": "walking",
|
||||
"duration_minutes": 30,
|
||||
"distance_km": 2.5,
|
||||
"intensity": "medium",
|
||||
"notes": "Тестовая активность"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{BASE_URL}/activity",
|
||||
json=data,
|
||||
headers=headers
|
||||
)
|
||||
|
||||
print(f"📥 Код ответа: {response.status_code}")
|
||||
|
||||
if response.status_code in [200, 201]:
|
||||
result = response.json()
|
||||
print("✅ Запись о физической активности успешно добавлена!")
|
||||
print(f" ID записи: {result.get('id')}")
|
||||
print(f" Тип: {result.get('activity_type')}")
|
||||
print(f" Продолжительность: {result.get('duration_minutes')} мин")
|
||||
print(f" Потрачено калорий: {result.get('calories_burned')} ккал")
|
||||
return result
|
||||
else:
|
||||
print(f"❌ Ошибка при добавлении записи об активности: {response.status_code}")
|
||||
print(response.text)
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Исключение при добавлении записи об активности: {e}")
|
||||
return None
|
||||
|
||||
def get_daily_summary(token):
|
||||
"""Получение дневной сводки"""
|
||||
print("\n📊 Получение сводки за день...")
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
today = datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
f"{BASE_URL}/summary?date={today}",
|
||||
headers=headers
|
||||
)
|
||||
|
||||
print(f"📥 Код ответа: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
print("✅ Сводка за день успешно получена!")
|
||||
print(f" Всего калорий: {result.get('total_calories')} ккал")
|
||||
print(f" Всего белка: {result.get('total_protein')} г")
|
||||
print(f" Всего жиров: {result.get('total_fat')} г")
|
||||
print(f" Всего углеводов: {result.get('total_carbs')} г")
|
||||
print(f" Потреблено воды: {result.get('water_consumed_ml')} мл")
|
||||
print(f" Активность: {result.get('activity_minutes')} мин")
|
||||
print(f" Сожжено калорий: {result.get('calories_burned')} ккал")
|
||||
return result
|
||||
else:
|
||||
print(f"❌ Ошибка при получении сводки: {response.status_code}")
|
||||
print(response.text)
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Исключение при получении сводки: {e}")
|
||||
return None
|
||||
|
||||
def main():
|
||||
"""Основная функция для тестирования API сервиса питания"""
|
||||
print("\n🚀 Запуск тестирования API сервиса питания...\n")
|
||||
|
||||
# Получаем токен авторизации
|
||||
token = get_auth_token()
|
||||
if not token:
|
||||
print("❌ Невозможно продолжить тестирование без авторизации")
|
||||
sys.exit(1)
|
||||
|
||||
# Выполняем поиск продуктов
|
||||
search_results = search_food(token, "apple")
|
||||
|
||||
if search_results and len(search_results) > 0:
|
||||
# Используем первый найденный продукт для дальнейшего тестирования
|
||||
food_id = search_results[0].get("id")
|
||||
|
||||
# Добавляем запись в дневник питания
|
||||
add_diary_entry(token, food_id)
|
||||
|
||||
# Получаем записи дневника
|
||||
get_diary_entries(token)
|
||||
else:
|
||||
# Если поиск не дал результатов, продолжаем тестирование с предполагаемым ID продукта
|
||||
print("⚠️ Используем предполагаемый ID продукта для дальнейших тестов")
|
||||
add_diary_entry(token, 1)
|
||||
|
||||
# Добавляем записи о воде и активности
|
||||
add_water_entry(token)
|
||||
add_activity_entry(token)
|
||||
|
||||
# Получаем дневную сводку
|
||||
get_daily_summary(token)
|
||||
|
||||
print("\n✅ Тестирование API сервиса питания завершено!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user