""" Tests for the Focus Group AI API endpoints """ import unittest import json from unittest.mock import patch, MagicMock from flask import Flask from app import create_app from app.routes.focus_group_ai import focus_group_ai_bp from app.services.focus_group_response_service import FocusGroupResponseError class TestFocusGroupAIRoutes(unittest.TestCase): """Test cases for the Focus Group AI API endpoints""" def setUp(self): """Set up test Flask app and client""" self.app = create_app() self.app.config['TESTING'] = True self.app.config['JWT_REQUIRED'] = False # Disable JWT for testing self.client = self.app.test_client() @patch('app.routes.focus_group_ai.FocusGroup.find_by_id') @patch('app.routes.focus_group_ai.Persona.find_by_id') @patch('app.routes.focus_group_ai.FocusGroup.get_messages') @patch('app.routes.focus_group_ai.generate_persona_response') @patch('app.routes.focus_group_ai.FocusGroup.add_message') def test_generate_ai_response_success(self, mock_add_message, mock_generate_response, mock_get_messages, mock_find_persona, mock_find_focus_group): """Test successful AI response generation""" # Mock data focus_group_id = '123456789' persona_id = '987654321' current_topic = 'What do you think about our new product?' # Mock focus group with the persona as a participant mock_focus_group = { '_id': focus_group_id, 'name': 'Test Focus Group', 'discussionGuide': 'This is a test discussion guide', 'participants': [persona_id] } mock_find_focus_group.return_value = mock_focus_group # Mock persona data mock_persona = { '_id': persona_id, 'name': 'Jane Doe', 'age': '30-35', 'gender': 'Female' } mock_find_persona.return_value = mock_persona # Mock previous messages mock_get_messages.return_value = [ {'senderId': 'moderator', 'text': 'Welcome everyone!', 'type': 'system'}, {'senderId': 'moderator', 'text': 'Let\'s discuss our new product', 'type': 'question'} ] # Mock response generation mock_generate_response.return_value = "I think the new product looks promising. I like its features." # Mock message saving mock_add_message.return_value = 'new_message_id' # Test request response = self.client.post( '/api/focus-group-ai/generate-response', json={ 'focus_group_id': focus_group_id, 'persona_id': persona_id, 'current_topic': current_topic } ) # Assertions self.assertEqual(response.status_code, 200) data = json.loads(response.data) self.assertIn('message', data) self.assertIn('response', data) self.assertEqual(data['response'], "I think the new product looks promising. I like its features.") self.assertEqual(data['message_id'], 'new_message_id') # Verify function calls mock_find_focus_group.assert_called_once_with(focus_group_id) mock_find_persona.assert_called_once_with(persona_id) mock_get_messages.assert_called_once_with(focus_group_id) mock_generate_response.assert_called_once() mock_add_message.assert_called_once() @patch('app.routes.focus_group_ai.FocusGroup.find_by_id') def test_generate_ai_response_focus_group_not_found(self, mock_find_focus_group): """Test response when focus group is not found""" mock_find_focus_group.return_value = None response = self.client.post( '/api/focus-group-ai/generate-response', json={ 'focus_group_id': 'nonexistent_id', 'persona_id': '987654321', 'current_topic': 'Test topic' } ) self.assertEqual(response.status_code, 404) data = json.loads(response.data) self.assertIn('error', data) self.assertEqual(data['error'], 'Focus group not found') @patch('app.routes.focus_group_ai.FocusGroup.find_by_id') @patch('app.routes.focus_group_ai.Persona.find_by_id') def test_generate_ai_response_persona_not_found(self, mock_find_persona, mock_find_focus_group): """Test response when persona is not found""" # Mock focus group mock_find_focus_group.return_value = {'_id': '123', 'name': 'Test Focus Group'} # Mock persona not found mock_find_persona.return_value = None response = self.client.post( '/api/focus-group-ai/generate-response', json={ 'focus_group_id': '123', 'persona_id': 'nonexistent_id', 'current_topic': 'Test topic' } ) self.assertEqual(response.status_code, 404) data = json.loads(response.data) self.assertIn('error', data) self.assertEqual(data['error'], 'Persona not found') @patch('app.routes.focus_group_ai.FocusGroup.find_by_id') @patch('app.routes.focus_group_ai.Persona.find_by_id') def test_generate_ai_response_persona_not_in_focus_group(self, mock_find_persona, mock_find_focus_group): """Test response when persona is not in the focus group""" # Mock focus group with no participants mock_find_focus_group.return_value = { '_id': '123', 'name': 'Test Focus Group', 'participants': ['different_persona_id'] } # Mock persona mock_find_persona.return_value = {'_id': 'persona_id', 'name': 'Test Persona'} response = self.client.post( '/api/focus-group-ai/generate-response', json={ 'focus_group_id': '123', 'persona_id': 'persona_id', 'current_topic': 'Test topic' } ) self.assertEqual(response.status_code, 400) data = json.loads(response.data) self.assertIn('error', data) self.assertEqual(data['error'], 'Persona is not a participant in this focus group') @patch('app.routes.focus_group_ai.FocusGroup.find_by_id') @patch('app.routes.focus_group_ai.Persona.find_by_id') @patch('app.routes.focus_group_ai.FocusGroup.get_messages') @patch('app.routes.focus_group_ai.generate_persona_response') def test_generate_ai_response_llm_error(self, mock_generate_response, mock_get_messages, mock_find_persona, mock_find_focus_group): """Test handling of LLM service errors""" # Mock focus group with the persona as a participant mock_find_focus_group.return_value = { '_id': '123', 'name': 'Test Focus Group', 'participants': ['persona_id'] } # Mock persona mock_find_persona.return_value = {'_id': 'persona_id', 'name': 'Test Persona'} # Mock messages mock_get_messages.return_value = [] # Mock LLM error mock_generate_response.side_effect = FocusGroupResponseError("LLM service unavailable") response = self.client.post( '/api/focus-group-ai/generate-response', json={ 'focus_group_id': '123', 'persona_id': 'persona_id', 'current_topic': 'Test topic' } ) self.assertEqual(response.status_code, 500) data = json.loads(response.data) self.assertIn('error', data) self.assertEqual(data['error'], 'Failed to generate response') self.assertIn('message', data) if __name__ == '__main__': unittest.main()