166 lines
No EOL
6.5 KiB
Python
Executable file
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() |