import json import pytest class TestWebhook: @pytest.mark.asyncio async def test_health_endpoint(self, client): response = await client.get("/health") assert response.status_code == 200 data = response.json() assert data["status"] == "ok" assert data["bot"] == "София" @pytest.mark.asyncio async def test_webhook_missing_secret(self, client): payload = {"update_type": "bot_started", "user": {"user_id": 123}} response = await client.post( "/webhook", content=json.dumps(payload), headers={"Content-Type": "application/json"}, ) assert response.status_code == 403 @pytest.mark.asyncio async def test_webhook_with_secret(self, client): payload = {"update_type": "bot_started", "user": {"user_id": 12345}} response = await client.post( "/webhook", content=json.dumps(payload), headers={ "Content-Type": "application/json", "X-Max-Bot-Api-Secret": "test-secret", }, ) assert response.status_code == 200 data = response.json() assert data["ok"] is True @pytest.mark.asyncio async def test_webhook_message_created(self, client): payload = { "update_type": "message_created", "user": {"user_id": 99999, "first_name": "Тест"}, "message": {"body": {"text": "Привет"}}, } response = await client.post( "/webhook", content=json.dumps(payload), headers={ "Content-Type": "application/json", "X-Max-Bot-Api-Secret": "test-secret", }, ) assert response.status_code == 200 data = response.json() assert data["ok"] is True @pytest.mark.asyncio async def test_webhook_invalid_json(self, client): response = await client.post( "/webhook", content="not json", headers={ "Content-Type": "application/json", "X-Max-Bot-Api-Secret": "test-secret", }, ) assert response.status_code == 200 data = response.json() assert data["ok"] is False @pytest.mark.asyncio async def test_webhook_message_callback(self, client): payload = { "update_type": "message_callback", "user": {"user_id": 88888}, "callback": {"payload": "cancel", "id": "cb_001"}, } response = await client.post( "/webhook", content=json.dumps(payload), headers={ "Content-Type": "application/json", "X-Max-Bot-Api-Secret": "test-secret", }, ) assert response.status_code == 200 data = response.json() assert data["ok"] is True class TestAPI: @pytest.mark.asyncio async def test_api_settings(self, client): response = await client.get("/api/bot/settings") assert response.status_code == 200 @pytest.mark.asyncio async def test_api_features(self, client): response = await client.get("/api/bot/features") assert response.status_code == 200 data = response.json() assert isinstance(data, list) @pytest.mark.asyncio async def test_api_categories(self, client): response = await client.get("/api/bot/categories") assert response.status_code == 200 @pytest.mark.asyncio async def test_api_templates(self, client): response = await client.get("/api/bot/templates") assert response.status_code == 200 @pytest.mark.asyncio async def test_api_users(self, client): response = await client.get("/api/bot/users") assert response.status_code == 200 data = response.json() assert "total" in data assert "users" in data @pytest.mark.asyncio async def test_api_conversations(self, client): response = await client.get("/api/bot/conversations") assert response.status_code == 200 data = response.json() assert isinstance(data, list) @pytest.mark.asyncio async def test_api_analytics(self, client): response = await client.get("/api/bot/analytics") assert response.status_code == 200 data = response.json() assert "total_users" in data @pytest.mark.asyncio async def test_api_test_run(self, client): response = await client.post( "/api/bot/test-run", content=json.dumps({"scenario": "new_dialog", "messages": []}), headers={"Content-Type": "application/json"}, ) assert response.status_code == 200 data = response.json() assert data["scenario"] == "new_dialog" @pytest.mark.asyncio async def test_api_test_run_out_of_hours(self, client): response = await client.post( "/api/bot/test-run", content=json.dumps({"scenario": "out_of_hours", "messages": []}), headers={"Content-Type": "application/json"}, ) assert response.status_code == 200 data = response.json() assert data["scenario"] == "out_of_hours" # Should have at least a bot response and mention out_of_hours template assert len(data.get("conversation", [])) >= 1 @pytest.mark.asyncio async def test_api_broadcast_recipients(self, client): response = await client.get("/api/bot/broadcast/recipients") assert response.status_code == 200 data = response.json() assert "total" in data assert "users" in data @pytest.mark.asyncio async def test_api_broadcast_history(self, client): response = await client.get("/api/bot/broadcast/history") assert response.status_code == 200 data = response.json() assert "total" in data assert "broadcasts" in data @pytest.mark.asyncio async def test_api_kb(self, client): response = await client.get("/api/bot/kb") assert response.status_code == 200 data = response.json() assert isinstance(data, list)