main functions commit
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-10-19 19:50:00 +09:00
parent ce72785184
commit 3050e084fa
39 changed files with 7149 additions and 186 deletions

193
tests/test_notifications.py Normal file
View File

@@ -0,0 +1,193 @@
#!/usr/bin/env python3
"""
🔔 ТЕСТ СИСТЕМЫ УВЕДОМЛЕНИЙ
Проверяем работу уведомлений всем пользователям в радиусе при экстренных событиях
"""
import requests
import json
import asyncio
import websockets
import threading
import time
from datetime import datetime
# Конфигурация
BASE_URL = "http://localhost:8002"
WS_URL = "ws://localhost:8002/api/v1/emergency/ws"
# Тестовые пользователи (нужно использовать реальные токены)
TEST_USERS = [
{
"name": "User1 (shadow85)",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyIiwiZW1haWwiOiJzaGFkb3c4NUBsaXN0LnJ1IiwiZXhwIjoxNzYwNzgxNzk5fQ.cAG66Xqpxs_-NNkL6Sz82HuFV_-bNv3dEhYAntgbVRg",
"user_id": 2
},
{
"name": "User2 (Raisa)",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzIiwiZW1haWwiOiJSYWlzYUBtYWlsLnJ1IiwiZXhwIjoxNzYwNzgxOTM3fQ.8gZeMsOmnqOMfiz8azGVJ_SxweaaLH6UIRImi9aCK4U",
"user_id": 3
}
]
# Координаты для тестирования (близко друг к другу)
TEST_COORDINATES = {
"emergency_location": {"latitude": 35.1815, "longitude": 126.8108},
"nearby_user1": {"latitude": 35.1820, "longitude": 126.8110}, # ~500m away
"nearby_user2": {"latitude": 35.1825, "longitude": 126.8115} # ~1km away
}
class WebSocketListener:
def __init__(self, user_name, token, user_id):
self.user_name = user_name
self.token = token
self.user_id = user_id
self.notifications_received = []
self.connected = False
async def listen(self):
"""Подключение к WebSocket и прослушивание уведомлений"""
uri = f"{WS_URL}/current_user_id?token={self.token}"
try:
print(f"🔌 {self.user_name}: Подключение к WebSocket...")
async with websockets.connect(uri) as websocket:
self.connected = True
print(f"{self.user_name}: WebSocket подключен")
# Слушаем уведомления в течение 30 секунд
try:
await asyncio.wait_for(self._listen_messages(websocket), timeout=30.0)
except asyncio.TimeoutError:
print(f"{self.user_name}: Таймаут WebSocket соединения")
except Exception as e:
print(f"{self.user_name}: Ошибка WebSocket: {e}")
finally:
self.connected = False
print(f"🔌 {self.user_name}: WebSocket отключен")
async def _listen_messages(self, websocket):
"""Прослушивание входящих сообщений"""
async for message in websocket:
try:
data = json.loads(message)
if data.get("type") == "emergency_alert":
self.notifications_received.append({
"timestamp": datetime.now(),
"data": data
})
distance = data.get("distance_km", "unknown")
print(f"🔔 {self.user_name}: Получено экстренное уведомление! Расстояние: {distance}км")
print(f" 📍 Alert ID: {data.get('alert_id')}")
print(f" 🚨 Type: {data.get('alert_type')}")
print(f" 💬 Message: {data.get('message')}")
else:
print(f"📨 {self.user_name}: Получено сообщение: {data}")
except Exception as e:
print(f"{self.user_name}: Ошибка парсинга сообщения: {e}")
def test_notification_system():
"""Основная функция тестирования системы уведомлений"""
print("🔔 ТЕСТИРОВАНИЕ СИСТЕМЫ УВЕДОМЛЕНИЙ")
print("=" * 60)
# Шаг 1: Создать WebSocket подключения для тестовых пользователей
listeners = []
for user in TEST_USERS:
listener = WebSocketListener(user["name"], user["token"], user["user_id"])
listeners.append(listener)
# Шаг 2: Запустить WebSocket соединения в отдельных потоках
async def run_all_listeners():
tasks = [listener.listen() for listener in listeners]
await asyncio.gather(*tasks, return_exceptions=True)
# Запуск WebSocket в отдельном потоке
ws_thread = threading.Thread(target=lambda: asyncio.run(run_all_listeners()))
ws_thread.daemon = True
ws_thread.start()
# Подождем подключения
print("⏳ Ожидание подключения WebSocket...")
time.sleep(3)
# Проверим статус подключений
connected_users = [l for l in listeners if l.connected]
print(f"📊 Подключено пользователей: {len(connected_users)}/{len(listeners)}")
# Шаг 3: Создать экстренное событие
print(f"\n🚨 Создание экстренного события...")
emergency_data = {
"latitude": TEST_COORDINATES["emergency_location"]["latitude"],
"longitude": TEST_COORDINATES["emergency_location"]["longitude"],
"alert_type": "general",
"message": "Тестирование системы уведомлений - это учебное событие",
"address": "Тестовая локация"
}
try:
# Используем токен первого пользователя для создания события
headers = {"Authorization": f"Bearer {TEST_USERS[0]['token']}"}
response = requests.post(
f"{BASE_URL}/api/v1/emergency/events",
json=emergency_data,
headers=headers,
timeout=10
)
if response.status_code == 200:
alert_data = response.json()
alert_id = alert_data.get("id")
print(f"✅ Экстренное событие создано! ID: {alert_id}")
print(f"📍 Координаты: {emergency_data['latitude']}, {emergency_data['longitude']}")
else:
print(f"Не удалось создать событие: {response.status_code}")
print(f"📄 Ответ: {response.text}")
return
except Exception as e:
print(f"❌ Ошибка создания события: {e}")
return
# Шаг 4: Ждем уведомления
print(f"\n⏳ Ожидание уведомлений... (15 секунд)")
time.sleep(15)
# Шаг 5: Анализ результатов
print(f"\n📊 РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ")
print("=" * 60)
total_notifications = 0
for listener in listeners:
count = len(listener.notifications_received)
total_notifications += count
status = "✅ Получил" if count > 0 else "Не получил"
print(f"{status} {listener.user_name}: {count} уведомлений")
# Показать детали уведомлений
for i, notification in enumerate(listener.notifications_received, 1):
data = notification["data"]
timestamp = notification["timestamp"].strftime("%H:%M:%S")
distance = data.get("distance_km", "unknown")
print(f" {i}. [{timestamp}] Alert ID {data.get('alert_id')} ({distance}км)")
# Итоговый отчет
print(f"\n🎯 ИТОГИ:")
print(f"📊 Всего уведомлений получено: {total_notifications}")
print(f"👥 Подключенных пользователей: {len(connected_users)}")
print(f"🎯 Ожидаемо уведомлений: {len(connected_users)}")
if total_notifications >= len(connected_users):
print(f"✅ УСПЕХ: Система уведомлений работает правильно!")
else:
print(f"⚠️ ПРЕДУПРЕЖДЕНИЕ: Не все пользователи получили уведомления")
print(f"\n💡 Примечание: Уведомления отправляются пользователям в радиусе 5км от события")
print(f"📱 Также отправляются push-уведомления через Notification Service")
if __name__ == "__main__":
test_notification_system()