semblance_backup/backend/tests/test_focus_group_response_service.py
2025-12-19 19:26:16 +00:00

166 lines
No EOL
6.5 KiB
Python
Executable file

"""
Tests for the Focus Group Response Service
"""
import unittest
from unittest.mock import patch, MagicMock
from app.services.focus_group_response_service import (
generate_persona_response,
FocusGroupResponseError,
_format_persona_details,
_format_previous_messages
)
from app.services.llm_service import LLMServiceError
class TestFocusGroupResponseService(unittest.TestCase):
"""Test cases for the Focus Group Response Service"""
def test_format_previous_messages(self):
"""Test formatting previous messages"""
# No messages
self.assertEqual(_format_previous_messages([]), "No previous messages.")
# With messages
messages = [
{"senderId": "moderator", "text": "Welcome everyone!", "type": "question"},
{"senderId": "system", "text": "New participant joined", "type": "system"},
{"senderId": "persona-123", "text": "Hello, I'm excited to be here", "type": "response"}
]
formatted = _format_previous_messages(messages)
self.assertIn("MODERATOR (moderator): Welcome everyone!", formatted)
self.assertIn("SYSTEM: New participant joined", formatted)
self.assertIn("persona-123: Hello, I'm excited to be here", formatted)
# Many messages (should be limited to 50)
many_messages = [{"senderId": f"person-{i}", "text": f"Message {i}"} for i in range(60)]
formatted = _format_previous_messages(many_messages)
# Should only contain the 50 most recent messages
self.assertEqual(formatted.count("\n") + 1, 50)
def test_format_persona_details(self):
"""Test formatting persona details"""
# Basic persona
basic_persona = {
"name": "John Doe",
"age": "30-35",
"gender": "Male",
"occupation": "Software Engineer",
"education": "Bachelor's Degree",
"location": "San Francisco, USA",
"personality": "Analytical and introverted"
}
formatted = _format_persona_details(basic_persona)
for key, value in basic_persona.items():
self.assertIn(f"{key.title()}: {value}", formatted)
# Complex persona with OCEAN traits
complex_persona = {
**basic_persona,
"oceanTraits": {
"openness": 80,
"conscientiousness": 70,
"extraversion": 30,
"agreeableness": 60,
"neuroticism": 40
},
"goals": ["Learn new skills", "Get promoted"],
"frustrations": ["Bureaucracy", "Meetings"],
"motivations": ["Technical excellence", "Impact"],
"thinkFeelDo": {
"thinks": ["How can I optimize this?", "What's the underlying pattern?"],
"feels": ["Excited by technical challenges", "Frustrated by inefficiency"],
"does": ["Researches solutions thoroughly", "Creates detailed plans"]
}
}
formatted = _format_persona_details(complex_persona)
# Check OCEAN traits
self.assertIn("OCEAN Traits:", formatted)
self.assertIn("- Openness: 80/100", formatted)
# Check goals
self.assertIn("Goals:", formatted)
for goal in complex_persona["goals"]:
self.assertIn(f"- {goal}", formatted)
# Check think/feel/do
self.assertIn("Thinks:", formatted)
self.assertIn("Feels:", formatted)
self.assertIn("Does:", formatted)
@patch('app.services.focus_group_response_service.LLMService.generate_content')
def test_generate_persona_response(self, mock_generate_content):
"""Test generating a persona response"""
# Setup test data
persona = {
"name": "Jane Doe",
"age": "30-35",
"gender": "Female",
"occupation": "Product Manager",
"education": "Master's Degree",
"location": "Boston, USA",
"personality": "Confident and analytical"
}
discussion_guide = "This focus group is about product features"
current_topic = "What do you think about the new dashboard?"
previous_messages = [
{"senderId": "moderator", "text": "Welcome everyone", "type": "system"},
{"senderId": "moderator", "text": "Let's discuss the dashboard", "type": "question"}
]
# Mock response
mock_generate_content.return_value = "I find the dashboard intuitive and well-organized."
# Test function
response = generate_persona_response(
persona=persona,
current_topic=current_topic,
previous_messages=previous_messages,
temperature=0.5
)
# Assertions
self.assertEqual(response, "I find the dashboard intuitive and well-organized.")
mock_generate_content.assert_called_once()
# Check prompt content
call_args = mock_generate_content.call_args[1]
self.assertEqual(call_args["temperature"], 0.5)
prompt = call_args["prompt"]
# Prompt should contain persona details
self.assertIn("Name: Jane Doe", prompt)
self.assertIn("Gender: Female", prompt)
# Prompt should contain discussion guide
self.assertIn("This focus group is about product features", prompt)
# Prompt should contain current topic
self.assertIn("What do you think about the new dashboard?", prompt)
# Prompt should contain previous messages
self.assertIn("MODERATOR (moderator): Let's discuss the dashboard", prompt)
@patch('app.services.focus_group_response_service.LLMService.generate_content')
def test_generate_persona_response_error(self, mock_generate_content):
"""Test error handling in persona response generation"""
# Setup mock to raise an exception
mock_generate_content.side_effect = LLMServiceError("LLM service unavailable")
# Test error propagation
with self.assertRaises(FocusGroupResponseError) as context:
generate_persona_response(
persona={"name": "Test Persona"},
current_topic="Test topic",
previous_messages=[]
)
self.assertIn("Error generating persona response", str(context.exception))
if __name__ == '__main__':
unittest.main()