parent
37007e6caf
commit
5b806651e3
@ -1,3 +1,55 @@
|
|||||||
from django.test import TestCase
|
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