#!/bin/bash # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Настройка логирования LOG_FILE="/tmp/api_test_output" rm -f "$LOG_FILE" 2>/dev/null exec > >(tee -a "$LOG_FILE") 2>&1 echo -e "${YELLOW}=======================================${NC}" echo -e "${YELLOW}🔍 Полное тестирование API приложения ${NC}" echo -e "${YELLOW}=======================================${NC}" # Функция для логирования тестовых результатов log_test_result() { local status=$1 local message=$2 if [[ $status == 0 ]]; then echo -e "${GREEN}✓ УСПЕШНО: ${message}${NC}" else echo -e "${RED}✗ ОШИБКА: ${message}${NC}" fi } # Функция для проверки ответа API check_api_response() { local response=$1 local expected_field=$2 if echo "$response" | jq -e ".$expected_field" > /dev/null; then return 0 else return 1 fi } # 1. Проверка доступности сервисов echo -e "\n${GREEN}1. Проверка доступности сервисов${NC}" services=( "http://192.168.0.103:8000" "http://192.168.0.103:8001" "http://192.168.0.103:8002" "http://192.168.0.103:8003" "http://192.168.0.103:8004" "http://192.168.0.103:8005" ) service_names=( "API Gateway" "User Service" "Emergency Service" "Location Service" "Calendar Service" "Notification Service" ) for i in "${!services[@]}"; do echo -n "Проверка ${service_names[$i]} (${services[$i]})... " if curl -s "${services[$i]}/health" | grep -q "status.*healthy" || curl -s "${services[$i]}/api/v1/health" | grep -q "status.*healthy"; then echo -e "${GREEN}OK${NC}" log_test_result 0 "Сервис ${service_names[$i]} доступен" else echo -e "${RED}НЕДОСТУПНО${NC}" log_test_result 1 "Сервис ${service_names[$i]} недоступен" echo "Продолжение тестирования может вызвать ошибки. Хотите продолжить? (y/n)" read -r continue_test if [[ $continue_test != "y" ]]; then exit 1 fi fi done # 2. Регистрация и авторизация echo -e "\n${GREEN}2. Регистрация и авторизация${NC}" echo "Регистрация тестового пользователя..." # Сначала удалим пользователя, если он уже существует echo -e "${YELLOW}Удаление существующего пользователя apitest, если он существует...${NC}" curl -s -X DELETE http://localhost:8001/api/v1/admin/users/by-username/apitest \ -H "Content-Type: application/json" \ -H "X-Admin-Key: super-secret-admin-key" > /dev/null REGISTER_RESPONSE=$(curl -s -X POST http://localhost:8001/api/v1/users/register \ -H "Content-Type: application/json" \ -d '{ "username": "apitest", "email": "apitest@example.com", "password": "ApiTest123!", "full_name": "API Test User", "phone_number": "+79997776655" }') echo "$REGISTER_RESPONSE" | jq if check_api_response "$REGISTER_RESPONSE" "id"; then log_test_result 0 "Регистрация пользователя" else log_test_result 1 "Регистрация пользователя" fi # Тест на ошибку при повторной регистрации с тем же именем пользователя echo -e "\n${YELLOW}Проверка дублирующейся регистрации...${NC}" DUPLICATE_RESPONSE=$(curl -s -X POST http://localhost:8001/api/v1/users/register \ -H "Content-Type: application/json" \ -d '{ "username": "apitest", "email": "another@example.com", "password": "ApiTest123!", "full_name": "Duplicate User", "phone_number": "+79997776655" }') echo "$DUPLICATE_RESPONSE" | jq if echo "$DUPLICATE_RESPONSE" | grep -q "error"; then log_test_result 0 "Проверка на дублирование пользователя" else log_test_result 1 "Проверка на дублирование пользователя (должна быть ошибка)" fi # Авторизация echo -e "\n${YELLOW}Авторизация тестового пользователя...${NC}" LOGIN_RESPONSE=$(curl -s -X POST http://localhost:8001/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{ "username": "apitest", "password": "ApiTest123!" }') echo "$LOGIN_RESPONSE" | jq TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.access_token') if [[ $TOKEN == "null" || -z $TOKEN ]]; then log_test_result 1 "Получение токена авторизации" echo -e "${RED}Не удалось получить токен авторизации. Тестирование будет остановлено.${NC}" exit 1 else log_test_result 0 "Получение токена авторизации" echo -e "${GREEN}Успешно получен токен авторизации${NC}" fi # Тест на авторизацию с неверным паролем echo -e "\n${YELLOW}Проверка авторизации с неверными данными...${NC}" FAILED_LOGIN=$(curl -s -X POST http://localhost:8001/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{ "username": "apitest", "password": "WrongPassword123!" }') echo "$FAILED_LOGIN" | jq if echo "$FAILED_LOGIN" | grep -q "error"; then log_test_result 0 "Проверка авторизации с неверным паролем" else log_test_result 1 "Проверка авторизации с неверным паролем (должна быть ошибка)" fi # 3. Получение текущего профиля через /me эндпоинт echo -e "\n${GREEN}3. Получение текущего профиля пользователя${NC}" PROFILE_RESPONSE=$(curl -s -X GET http://localhost:8001/api/v1/users/me \ -H "Authorization: Bearer $TOKEN") echo "$PROFILE_RESPONSE" | jq if check_api_response "$PROFILE_RESPONSE" "username"; then log_test_result 0 "Получение профиля пользователя" else log_test_result 1 "Получение профиля пользователя" fi # Тестирование получения профиля через альтернативные эндпоинты echo -e "\n${YELLOW}Тестирование альтернативного эндпоинта /api/v1/profile${NC}" PROFILE_ALT=$(curl -s -X GET http://localhost:8001/api/v1/profile \ -H "Authorization: Bearer $TOKEN") echo "$PROFILE_ALT" | jq if check_api_response "$PROFILE_ALT" "username"; then log_test_result 0 "Получение профиля через альтернативный эндпоинт" else log_test_result 1 "Получение профиля через альтернативный эндпоинт" fi # 4. Обновление профиля echo -e "\n${GREEN}4. Обновление профиля пользователя${NC}" UPDATE_RESPONSE=$(curl -s -X PATCH http://localhost:8001/api/v1/users/me \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "full_name": "Обновленное Имя", "phone_number": "+79997776655" }') echo "$UPDATE_RESPONSE" | jq if check_api_response "$UPDATE_RESPONSE" "full_name"; then log_test_result 0 "Обновление профиля пользователя" else log_test_result 1 "Обновление профиля пользователя" fi # Проверка обновления профиля echo -e "\n${YELLOW}Проверка применения изменений профиля${NC}" PROFILE_AFTER=$(curl -s -X GET http://localhost:8001/api/v1/users/me \ -H "Authorization: Bearer $TOKEN") if [[ $(echo "$PROFILE_AFTER" | jq -r '.full_name') == "Обновленное Имя" ]]; then log_test_result 0 "Проверка обновления имени в профиле" else log_test_result 1 "Проверка обновления имени в профиле" fi # 5. Добавление контактов экстренной связи echo -e "\n${GREEN}5. Добавление контакта для экстренной связи${NC}" CONTACT_RESPONSE=$(curl -s -X POST http://localhost:8001/api/v1/users/me/emergency-contacts \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "name": "Экстренный контакт", "phone_number": "+79991112233", "relationship": "Родственник" }') echo "$CONTACT_RESPONSE" | jq CONTACT_ID=$(echo "$CONTACT_RESPONSE" | jq -r '.id') if [[ $CONTACT_ID != "null" && -n $CONTACT_ID ]]; then log_test_result 0 "Добавление экстренного контакта" else log_test_result 1 "Добавление экстренного контакта" fi # 6. Получение списка контактов echo -e "\n${GREEN}6. Получение списка экстренных контактов${NC}" CONTACTS_RESPONSE=$(curl -s -X GET http://localhost:8001/api/v1/users/me/emergency-contacts \ -H "Authorization: Bearer $TOKEN") echo "$CONTACTS_RESPONSE" | jq CONTACTS_COUNT=$(echo "$CONTACTS_RESPONSE" | jq '. | length') if [[ $CONTACTS_COUNT -gt 0 ]]; then log_test_result 0 "Получение списка экстренных контактов (найдено: $CONTACTS_COUNT)" else log_test_result 1 "Получение списка экстренных контактов" fi # Обновление экстренного контакта if [[ $CONTACT_ID != "null" && -n $CONTACT_ID ]]; then echo -e "\n${YELLOW}Обновление экстренного контакта${NC}" UPDATE_CONTACT_RESPONSE=$(curl -s -X PATCH http://localhost:8001/api/v1/users/me/emergency-contacts/$CONTACT_ID \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "name": "Обновленный экстренный контакт", "relationship": "Друг" }') echo "$UPDATE_CONTACT_RESPONSE" | jq if [[ $(echo "$UPDATE_CONTACT_RESPONSE" | jq -r '.name') == "Обновленный экстренный контакт" ]]; then log_test_result 0 "Обновление экстренного контакта" else log_test_result 1 "Обновление экстренного контакта" fi fi # 7. Обновление местоположения пользователя echo -e "\n${GREEN}7. Обновление местоположения пользователя${NC}" LOCATION_UPDATE_RESPONSE=$(curl -s -X POST http://localhost:8003/api/v1/locations/update \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "latitude": 55.7558, "longitude": 37.6173, "accuracy": 10.0 }') echo "$LOCATION_UPDATE_RESPONSE" | jq if check_api_response "$LOCATION_UPDATE_RESPONSE" "id"; then log_test_result 0 "Обновление местоположения" else log_test_result 1 "Обновление местоположения" fi # 8. Получение последнего местоположения echo -e "\n${GREEN}8. Получение последнего местоположения${NC}" LAST_LOCATION=$(curl -s -X GET http://localhost:8003/api/v1/locations/last \ -H "Authorization: Bearer $TOKEN") echo "$LAST_LOCATION" | jq if check_api_response "$LAST_LOCATION" "latitude"; then log_test_result 0 "Получение последнего местоположения" else log_test_result 1 "Получение последнего местоположения" fi # Получение истории местоположений echo -e "\n${YELLOW}Получение истории местоположений${NC}" LOCATION_HISTORY=$(curl -s -X GET "http://localhost:8003/api/v1/locations/history?limit=5" \ -H "Authorization: Bearer $TOKEN") echo "$LOCATION_HISTORY" | jq if [[ $(echo "$LOCATION_HISTORY" | jq '. | length') -gt 0 ]]; then log_test_result 0 "Получение истории местоположений" else log_test_result 1 "Получение истории местоположений" fi # 9. Создание экстренного оповещения echo -e "\n${GREEN}9. Создание экстренного оповещения${NC}" ALERT_RESPONSE=$(curl -s -X POST http://localhost:8002/api/v1/emergency/alerts \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "latitude": 55.7558, "longitude": 37.6173, "alert_type": "SOS", "message": "Тестовое экстренное оповещение" }') echo "$ALERT_RESPONSE" | jq ALERT_ID=$(echo "$ALERT_RESPONSE" | jq -r '.id') if [[ $ALERT_ID != "null" && -n $ALERT_ID ]]; then log_test_result 0 "Создание экстренного оповещения" else log_test_result 1 "Создание экстренного оповещения" fi # 10. Получение активных оповещений echo -e "\n${GREEN}10. Получение активных оповещений пользователя${NC}" ACTIVE_ALERTS=$(curl -s -X GET http://localhost:8002/api/v1/emergency/alerts/my \ -H "Authorization: Bearer $TOKEN") echo "$ACTIVE_ALERTS" | jq ALERTS_COUNT=$(echo "$ACTIVE_ALERTS" | jq '. | length') if [[ $ALERTS_COUNT -gt 0 ]]; then log_test_result 0 "Получение активных оповещений (найдено: $ALERTS_COUNT)" else log_test_result 1 "Получение активных оповещений" fi # 11. Получение статистики по оповещениям echo -e "\n${YELLOW}Получение статистики по экстренным оповещениям${NC}" ALERTS_STATS=$(curl -s -X GET http://localhost:8002/api/v1/emergency/stats \ -H "Authorization: Bearer $TOKEN") echo "$ALERTS_STATS" | jq if check_api_response "$ALERTS_STATS" "total_alerts"; then log_test_result 0 "Получение статистики по оповещениям" else log_test_result 1 "Получение статистики по оповещениям" fi # 12. Отмена экстренного оповещения if [[ $ALERT_ID != "null" && -n $ALERT_ID ]]; then echo -e "\n${GREEN}12. Отмена экстренного оповещения${NC}" CANCEL_RESPONSE=$(curl -s -X PATCH http://localhost:8002/api/v1/emergency/alerts/$ALERT_ID/cancel \ -H "Authorization: Bearer $TOKEN") echo "$CANCEL_RESPONSE" | jq if [[ $(echo "$CANCEL_RESPONSE" | jq -r '.status') == "CANCELED" ]]; then log_test_result 0 "Отмена экстренного оповещения" else log_test_result 1 "Отмена экстренного оповещения" fi fi # 13. Создание записи в календаре echo -e "\n${GREEN}13. Создание записи в календаре${NC}" CALENDAR_RESPONSE=$(curl -s -X POST http://localhost:8004/api/v1/calendar/entries \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "entry_date": "2025-10-01", "cycle_day": 1, "symptoms": ["HEADACHE", "FATIGUE"], "mood": "NORMAL", "notes": "Тестовая запись в календаре" }') echo "$CALENDAR_RESPONSE" | jq CALENDAR_ENTRY_ID=$(echo "$CALENDAR_RESPONSE" | jq -r '.id') if [[ $CALENDAR_ENTRY_ID != "null" && -n $CALENDAR_ENTRY_ID ]]; then log_test_result 0 "Создание записи в календаре" else log_test_result 1 "Создание записи в календаре" fi # 14. Получение записей календаря echo -e "\n${GREEN}14. Получение записей календаря${NC}" CALENDAR_ENTRIES=$(curl -s -X GET "http://localhost:8004/api/v1/calendar/entries?start_date=2025-09-01&end_date=2025-10-31" \ -H "Authorization: Bearer $TOKEN") echo "$CALENDAR_ENTRIES" | jq ENTRIES_COUNT=$(echo "$CALENDAR_ENTRIES" | jq '. | length') if [[ $ENTRIES_COUNT -gt 0 ]]; then log_test_result 0 "Получение записей календаря (найдено: $ENTRIES_COUNT)" else log_test_result 1 "Получение записей календаря" fi # Обновление записи в календаре if [[ $CALENDAR_ENTRY_ID != "null" && -n $CALENDAR_ENTRY_ID ]]; then echo -e "\n${YELLOW}Обновление записи в календаре${NC}" UPDATE_ENTRY=$(curl -s -X PATCH "http://localhost:8004/api/v1/calendar/entries/$CALENDAR_ENTRY_ID" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "notes": "Обновленная запись в календаре", "mood": "GOOD" }') echo "$UPDATE_ENTRY" | jq if [[ $(echo "$UPDATE_ENTRY" | jq -r '.mood') == "GOOD" ]]; then log_test_result 0 "Обновление записи в календаре" else log_test_result 1 "Обновление записи в календаре" fi fi # 15. Получение прогноза цикла echo -e "\n${GREEN}15. Получение прогноза цикла${NC}" CYCLE_PREDICTION=$(curl -s -X GET http://localhost:8004/api/v1/calendar/prediction \ -H "Authorization: Bearer $TOKEN") echo "$CYCLE_PREDICTION" | jq if check_api_response "$CYCLE_PREDICTION" "next_period_date"; then log_test_result 0 "Получение прогноза цикла" else log_test_result 1 "Получение прогноза цикла" fi # 16. Регистрация устройства для уведомлений echo -e "\n${GREEN}16. Регистрация устройства для уведомлений${NC}" DEVICE_RESPONSE=$(curl -s -X POST http://localhost:8005/api/v1/notifications/devices \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "device_token": "fcm-test-token-123", "device_type": "ANDROID", "app_version": "1.0.0" }') echo "$DEVICE_RESPONSE" | jq DEVICE_ID=$(echo "$DEVICE_RESPONSE" | jq -r '.id') if [[ $DEVICE_ID != "null" && -n $DEVICE_ID ]]; then log_test_result 0 "Регистрация устройства для уведомлений" else log_test_result 1 "Регистрация устройства для уведомлений" fi # 17. Настройка предпочтений уведомлений echo -e "\n${GREEN}17. Настройка предпочтений уведомлений${NC}" PREFS_RESPONSE=$(curl -s -X POST http://localhost:8005/api/v1/notifications/preferences \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "emergency_alerts": true, "nearby_incidents": true, "calendar_reminders": true, "system_notifications": true }') echo "$PREFS_RESPONSE" | jq if check_api_response "$PREFS_RESPONSE" "emergency_alerts"; then log_test_result 0 "Настройка предпочтений уведомлений" else log_test_result 1 "Настройка предпочтений уведомлений" fi # 18. Получение текущих предпочтений уведомлений echo -e "\n${YELLOW}Получение текущих предпочтений уведомлений${NC}" CURRENT_PREFS=$(curl -s -X GET http://localhost:8005/api/v1/notifications/preferences \ -H "Authorization: Bearer $TOKEN") echo "$CURRENT_PREFS" | jq if check_api_response "$CURRENT_PREFS" "calendar_reminders"; then log_test_result 0 "Получение предпочтений уведомлений" else log_test_result 1 "Получение предпочтений уведомлений" fi # 19. Тестирование отправки тестового уведомления echo -e "\n${GREEN}19. Отправка тестового уведомления${NC}" TEST_NOTIFICATION=$(curl -s -X POST http://localhost:8005/api/v1/notifications/test \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TOKEN" \ -d '{ "title": "Тестовое уведомление", "body": "Это тестовое уведомление для проверки API" }') echo "$TEST_NOTIFICATION" | jq if check_api_response "$TEST_NOTIFICATION" "status"; then log_test_result 0 "Отправка тестового уведомления" else log_test_result 1 "Отправка тестового уведомления" fi # 20. Получение данных пользователя через Gateway echo -e "\n${GREEN}20. Получение данных пользователя через Gateway${NC}" DASHBOARD=$(curl -s -X GET http://localhost:8000/api/v1/users/dashboard \ -H "Authorization: Bearer $TOKEN") echo "$DASHBOARD" | jq if check_api_response "$DASHBOARD" "user"; then log_test_result 0 "Получение данных пользователя через API Gateway" else log_test_result 1 "Получение данных пользователя через API Gateway" fi # 21. Тестирование документации Swagger echo -e "\n${GREEN}21. Проверка документации Swagger${NC}" SWAGGER_RESPONSE=$(curl -s -X GET http://localhost:8000/openapi.json) echo "$SWAGGER_RESPONSE" | jq -C '.info' if check_api_response "$SWAGGER_RESPONSE" "paths"; then log_test_result 0 "Получение OpenAPI схемы" else log_test_result 1 "Получение OpenAPI схемы" fi # 22. Проверка наличия схем данных в Swagger echo -e "\n${YELLOW}Проверка наличия схем данных в Swagger${NC}" COMPONENTS_SCHEMAS=$(echo "$SWAGGER_RESPONSE" | jq '.components.schemas') SCHEMAS_COUNT=$(echo "$COMPONENTS_SCHEMAS" | jq 'length') if [[ $SCHEMAS_COUNT -gt 0 ]]; then log_test_result 0 "Проверка наличия схем данных (найдено: $SCHEMAS_COUNT)" echo -e "${GREEN}Доступные схемы:${NC}" echo "$COMPONENTS_SCHEMAS" | jq 'keys' else log_test_result 1 "Проверка наличия схем данных" fi # Очистка ресурсов echo -e "\n${GREEN}Очистка тестовых данных...${NC}" # Удаление созданных ресурсов if [[ $DEVICE_ID != "null" && -n $DEVICE_ID ]]; then curl -s -X DELETE http://localhost:8005/api/v1/notifications/devices/$DEVICE_ID \ -H "Authorization: Bearer $TOKEN" > /dev/null echo "Удалено устройство для уведомлений" fi if [[ $CONTACT_ID != "null" && -n $CONTACT_ID ]]; then curl -s -X DELETE http://localhost:8001/api/v1/users/me/emergency-contacts/$CONTACT_ID \ -H "Authorization: Bearer $TOKEN" > /dev/null echo "Удалены экстренные контакты" fi if [[ $CALENDAR_ENTRY_ID != "null" && -n $CALENDAR_ENTRY_ID ]]; then curl -s -X DELETE http://localhost:8004/api/v1/calendar/entries/$CALENDAR_ENTRY_ID \ -H "Authorization: Bearer $TOKEN" > /dev/null echo "Удалены записи в календаре" fi # Сбор статистики PASSED_TESTS=$(grep -c "✓ УСПЕШНО" /tmp/api_test_output 2>/dev/null || echo "0") FAILED_TESTS=$(grep -c "✗ ОШИБКА" /tmp/api_test_output 2>/dev/null || echo "0") TOTAL_TESTS=$((PASSED_TESTS + FAILED_TESTS)) echo -e "\n${YELLOW}=======================================${NC}" echo -e "${YELLOW}📊 Итоги тестирования API${NC}" echo -e "${YELLOW}=======================================${NC}" echo -e "Всего тестов: ${TOTAL_TESTS}" echo -e "${GREEN}✓ Успешно: ${PASSED_TESTS}${NC}" echo -e "${RED}✗ Ошибок: ${FAILED_TESTS}${NC}" if [[ $FAILED_TESTS -eq 0 ]]; then echo -e "\n${GREEN}✅ Тестирование API завершено успешно!${NC}" else echo -e "\n${YELLOW}⚠️ Тестирование API завершено с ошибками!${NC}" fi echo -e "${YELLOW}=======================================${NC}" # Сохранение результатов в файл { echo "# Результаты тестирования API" echo "Дата: $(date '+%Y-%m-%d %H:%M:%S')" echo "## Итоги" echo "- Всего тестов: ${TOTAL_TESTS}" echo "- Успешно: ${PASSED_TESTS}" echo "- Ошибок: ${FAILED_TESTS}" echo "" echo "## Подробности" grep -E "✓ УСПЕШНО|✗ ОШИБКА" /tmp/api_test_output 2>/dev/null || echo "Нет деталей" } > api_test_results.md echo "Подробные результаты сохранены в файле api_test_results.md"