parent
37007e6caf
commit
5b806651e3
@ -1,3 +1,55 @@
|
||||
from django.test import TestCase
|
||||
from unittest.mock import patch, MagicMock
|
||||
from max_bot.max_api import maxbot_set_commands
|
||||
|
||||
# Create your tests here.
|
||||
|
||||
class MaxApiCommandsTest(TestCase):
|
||||
"""Тесты для функции maxbot_set_commands."""
|
||||
|
||||
@patch('max_bot.max_api.requests.patch')
|
||||
def test_maxbot_set_commands_success(self, mock_patch):
|
||||
"""Проверка успешного создания команд."""
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {'success': True}
|
||||
mock_patch.return_value = mock_response
|
||||
|
||||
max_token = 'test_token'
|
||||
commands = [
|
||||
{'name': 'start', 'description': 'Начать'},
|
||||
{'name': 'menu', 'description': 'Меню'}
|
||||
]
|
||||
response = maxbot_set_commands(max_token, commands)
|
||||
|
||||
mock_patch.assert_called_once_with(
|
||||
'https://platform-api2.max.ru/me/commands',
|
||||
headers={
|
||||
'Authorization': 'test_token',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
json={'commands': commands},
|
||||
verify=mock_patch.call_args[1].get('verify')
|
||||
)
|
||||
self.assertEqual(response, mock_response)
|
||||
|
||||
@patch('max_bot.max_api.requests.patch')
|
||||
def test_maxbot_set_commands_empty_list(self, mock_patch):
|
||||
"""Проверка передачи пустого списка команд."""
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_patch.return_value = mock_response
|
||||
|
||||
response = maxbot_set_commands('token', [])
|
||||
mock_patch.assert_called_once()
|
||||
self.assertEqual(response, mock_response)
|
||||
|
||||
@patch('max_bot.max_api.requests.patch')
|
||||
def test_maxbot_set_commands_error_response(self, mock_patch):
|
||||
"""Проверка обработки ошибки API."""
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 400
|
||||
mock_response.json.return_value = {'error': 'Bad Request'}
|
||||
mock_patch.return_value = mock_response
|
||||
|
||||
response = maxbot_set_commands('token', [{'name': 'test', 'description': 'test'}])
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
# user_logger.py
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
from threading import Lock
|
||||
from max_bot.models import Client
|
||||
|
||||
# Папка для логов активности пользователей
|
||||
LOG_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'log', 'user_activity')
|
||||
os.makedirs(LOG_DIR, exist_ok=True)
|
||||
|
||||
_lock = Lock()
|
||||
|
||||
def log_user_action(
|
||||
client: Client,
|
||||
chat_id: str,
|
||||
action_type: str,
|
||||
details: dict = None,
|
||||
user_query: str = None,
|
||||
intent: str = None,
|
||||
entities: dict = None,
|
||||
response: str = None,
|
||||
command: str = None
|
||||
) -> None:
|
||||
"""
|
||||
Логирует действие пользователя в структурированном JSON-формате.
|
||||
Запись добавляется в файл user_activity_YYYY-MM-DD.log.
|
||||
"""
|
||||
timestamp = datetime.now().isoformat()
|
||||
log_entry = {
|
||||
"timestamp": timestamp,
|
||||
"client_id": client.id,
|
||||
"chat_id": chat_id,
|
||||
"action_type": action_type,
|
||||
"details": details or {},
|
||||
}
|
||||
if user_query is not None:
|
||||
log_entry["user_query"] = user_query
|
||||
if intent is not None:
|
||||
log_entry["intent"] = intent
|
||||
if entities is not None:
|
||||
log_entry["entities"] = entities
|
||||
if response is not None:
|
||||
log_entry["response"] = response
|
||||
if command is not None:
|
||||
log_entry["command"] = command
|
||||
|
||||
# Определяем имя файла по дате
|
||||
date_str = datetime.now().strftime("%Y-%m-%d")
|
||||
log_file = os.path.join(LOG_DIR, f"user_activity_{date_str}.log")
|
||||
|
||||
# Потокобезопасная запись
|
||||
with _lock:
|
||||
with open(log_file, 'a', encoding='utf-8') as f:
|
||||
f.write(json.dumps(log_entry, ensure_ascii=False) + '\n')
|
||||
Loading…
Reference in new issue