a digital entity named phi that roams bsky
1"""Unit tests for response generation"""
2
3from unittest.mock import AsyncMock, Mock, patch
4
5import pytest
6
7from bot.response_generator import PLACEHOLDER_RESPONSES, ResponseGenerator
8
9
10@pytest.mark.asyncio
11async def test_placeholder_response_generator():
12 """Test placeholder responses when no AI is configured"""
13 with patch("bot.response_generator.settings") as mock_settings:
14 mock_settings.anthropic_api_key = None
15
16 generator = ResponseGenerator()
17 response = await generator.generate("Hello bot!", "test.user", "")
18
19 # Should return one of the placeholder responses
20 assert response in PLACEHOLDER_RESPONSES
21 assert len(response) <= 300
22
23
24@pytest.mark.asyncio
25async def test_ai_response_generator():
26 """Test AI responses when Anthropic is configured"""
27 with patch("bot.response_generator.settings") as mock_settings:
28 mock_settings.anthropic_api_key = "test-key"
29
30 # Mock the agent
31 mock_agent = Mock()
32 mock_agent.generate_response = AsyncMock(
33 return_value="Hello! Nice to meet you!"
34 )
35
36 with patch(
37 "bot.agents.anthropic_agent.AnthropicAgent", return_value=mock_agent
38 ):
39 generator = ResponseGenerator()
40
41 # Verify AI was enabled
42 assert generator.agent is not None
43 assert hasattr(generator.agent, "generate_response")
44
45 # Test response
46 response = await generator.generate("Hello!", "test.user", "")
47 assert response == "Hello! Nice to meet you!"
48
49 # Verify the agent was called correctly
50 mock_agent.generate_response.assert_called_once_with(
51 "Hello!", "test.user", ""
52 )
53
54
55@pytest.mark.asyncio
56async def test_ai_initialization_failure():
57 """Test fallback to placeholder when AI initialization fails"""
58 with patch("bot.response_generator.settings") as mock_settings:
59 mock_settings.anthropic_api_key = "test-key"
60
61 # Make the import fail
62 with patch(
63 "bot.agents.anthropic_agent.AnthropicAgent",
64 side_effect=ImportError("API error"),
65 ):
66 generator = ResponseGenerator()
67
68 # Should fall back to placeholder
69 assert generator.agent is None
70
71 response = await generator.generate("Hello!", "test.user", "")
72 assert response in PLACEHOLDER_RESPONSES
73
74
75@pytest.mark.asyncio
76async def test_response_length_limit():
77 """Test that responses are always within Bluesky's 300 char limit"""
78 with patch("bot.response_generator.settings") as mock_settings:
79 mock_settings.anthropic_api_key = "test-key"
80
81 # Mock agent that returns a properly truncated response
82 # (In real implementation, truncation happens in AnthropicAgent)
83 mock_agent = Mock()
84 mock_agent.generate_response = AsyncMock(
85 return_value="x" * 300 # Already truncated by agent
86 )
87
88 with patch(
89 "bot.agents.anthropic_agent.AnthropicAgent", return_value=mock_agent
90 ):
91 generator = ResponseGenerator()
92 response = await generator.generate("Hello!", "test.user", "")
93
94 # The anthropic agent should handle truncation, but let's verify
95 assert len(response) <= 300
96
97
98def test_placeholder_responses_length():
99 """Verify all placeholder responses fit within limit"""
100 for response in PLACEHOLDER_RESPONSES:
101 assert len(response) <= 300, f"Placeholder too long: {response}"