""" Unit tests for Language Context Manager Tests language switching, prompt template generation, and validation functionality for the multi-language chat agent. """ import unittest from unittest.mock import patch from datetime import datetime from chat_agent.services.language_context import LanguageContextManager class TestLanguageContextManager(unittest.TestCase): """Test cases for LanguageContextManager class.""" def setUp(self): """Set up test fixtures before each test method.""" self.manager = LanguageContextManager() self.test_session_id = "test-session-123" def test_initialization(self): """Test that LanguageContextManager initializes correctly.""" self.assertIsInstance(self.manager, LanguageContextManager) self.assertEqual(self.manager.DEFAULT_LANGUAGE, 'python') self.assertIsInstance(self.manager.SUPPORTED_LANGUAGES, set) self.assertIn('python', self.manager.SUPPORTED_LANGUAGES) self.assertIn('javascript', self.manager.SUPPORTED_LANGUAGES) self.assertIn('java', self.manager.SUPPORTED_LANGUAGES) def test_validate_language_valid_languages(self): """Test validation of supported programming languages.""" valid_languages = ['python', 'javascript', 'java', 'cpp', 'csharp', 'go', 'rust'] for language in valid_languages: with self.subTest(language=language): self.assertTrue(self.manager.validate_language(language)) # Test case insensitive validation self.assertTrue(self.manager.validate_language(language.upper())) self.assertTrue(self.manager.validate_language(language.title())) def test_validate_language_invalid_languages(self): """Test validation rejects invalid programming languages.""" invalid_languages = ['cobol', 'fortran', 'assembly', 'brainfuck', ''] for language in invalid_languages: with self.subTest(language=language): self.assertFalse(self.manager.validate_language(language)) def test_validate_language_edge_cases(self): """Test validation handles edge cases properly.""" # Test None self.assertFalse(self.manager.validate_language(None)) # Test empty string self.assertFalse(self.manager.validate_language('')) # Test whitespace self.assertFalse(self.manager.validate_language(' ')) # Test valid language with whitespace self.assertTrue(self.manager.validate_language(' python ')) def test_get_language_default(self): """Test getting language returns Python default for new sessions.""" language = self.manager.get_language(self.test_session_id) self.assertEqual(language, 'python') def test_set_language_valid(self): """Test setting valid programming languages.""" test_cases = [ ('python', 'python'), ('JavaScript', 'javascript'), ('JAVA', 'java'), (' cpp ', 'cpp') ] for input_lang, expected_lang in test_cases: with self.subTest(input_lang=input_lang): result = self.manager.set_language(self.test_session_id, input_lang) self.assertTrue(result) actual_lang = self.manager.get_language(self.test_session_id) self.assertEqual(actual_lang, expected_lang) def test_set_language_invalid(self): """Test setting invalid programming languages fails gracefully.""" invalid_languages = ['cobol', 'assembly', '', None] for language in invalid_languages: with self.subTest(language=language): result = self.manager.set_language(self.test_session_id, language) self.assertFalse(result) # Should still return default language actual_lang = self.manager.get_language(self.test_session_id) self.assertEqual(actual_lang, 'python') @patch('chat_agent.services.language_context.datetime') def test_set_language_updates_timestamp(self, mock_datetime): """Test that setting language updates the timestamp.""" mock_now = datetime(2023, 1, 1, 12, 0, 0) mock_datetime.now.return_value = mock_now self.manager.set_language(self.test_session_id, 'javascript') context = self.manager.get_session_context(self.test_session_id) self.assertEqual(context['updated_at'], mock_now) def test_get_language_prompt_template_by_language(self): """Test getting prompt templates by language.""" template = self.manager.get_language_prompt_template(language='python') self.assertIn('Python', template) self.assertIn('programming assistant', template) template = self.manager.get_language_prompt_template(language='javascript') self.assertIn('JavaScript', template) self.assertIn('programming assistant', template) def test_get_language_prompt_template_by_session(self): """Test getting prompt templates by session ID.""" # Set session language self.manager.set_language(self.test_session_id, 'java') template = self.manager.get_language_prompt_template(session_id=self.test_session_id) self.assertIn('Java', template) self.assertIn('programming assistant', template) def test_get_language_prompt_template_default(self): """Test getting default prompt template.""" template = self.manager.get_language_prompt_template() self.assertIn('Python', template) # Should default to Python self.assertIn('programming assistant', template) def test_get_language_prompt_template_invalid_language(self): """Test getting prompt template for invalid language returns default.""" template = self.manager.get_language_prompt_template(language='cobol') self.assertIn('Python', template) # Should default to Python def test_get_session_context_new_session(self): """Test getting context for new session initializes with defaults.""" context = self.manager.get_session_context(self.test_session_id) self.assertEqual(context['language'], 'python') self.assertIn('prompt_template', context) self.assertIn('updated_at', context) def test_get_session_context_existing_session(self): """Test getting context for existing session.""" # Set up session self.manager.set_language(self.test_session_id, 'javascript') context = self.manager.get_session_context(self.test_session_id) self.assertEqual(context['language'], 'javascript') self.assertIn('JavaScript', context['prompt_template']) def test_remove_session_context(self): """Test removing session context.""" # Set up session self.manager.set_language(self.test_session_id, 'java') # Verify session exists self.assertEqual(self.manager.get_language(self.test_session_id), 'java') # Remove session result = self.manager.remove_session_context(self.test_session_id) self.assertTrue(result) # Verify session is removed (should return default) self.assertEqual(self.manager.get_language(self.test_session_id), 'python') def test_remove_session_context_nonexistent(self): """Test removing non-existent session context.""" result = self.manager.remove_session_context("non-existent-session") self.assertFalse(result) def test_get_supported_languages(self): """Test getting supported languages returns correct set.""" languages = self.manager.get_supported_languages() self.assertIsInstance(languages, set) self.assertIn('python', languages) self.assertIn('javascript', languages) self.assertIn('java', languages) self.assertIn('cpp', languages) # Verify it's a copy (modifying shouldn't affect original) languages.add('fake-language') self.assertNotIn('fake-language', self.manager.SUPPORTED_LANGUAGES) def test_get_language_display_name(self): """Test getting display names for programming languages.""" test_cases = [ ('python', 'Python'), ('javascript', 'JavaScript'), ('cpp', 'C++'), ('csharp', 'C#'), ('typescript', 'TypeScript'), ('unknown', 'Unknown') # Should title-case unknown languages ] for language, expected_display in test_cases: with self.subTest(language=language): display_name = self.manager.get_language_display_name(language) self.assertEqual(display_name, expected_display) def test_language_switching_workflow(self): """Test complete language switching workflow.""" session_id = "workflow-test-session" # Start with default self.assertEqual(self.manager.get_language(session_id), 'python') # Switch to JavaScript result = self.manager.set_language(session_id, 'javascript') self.assertTrue(result) self.assertEqual(self.manager.get_language(session_id), 'javascript') # Get JavaScript template template = self.manager.get_language_prompt_template(session_id=session_id) self.assertIn('JavaScript', template) # Switch to Java result = self.manager.set_language(session_id, 'java') self.assertTrue(result) self.assertEqual(self.manager.get_language(session_id), 'java') # Verify context is updated context = self.manager.get_session_context(session_id) self.assertEqual(context['language'], 'java') self.assertIn('Java', context['prompt_template']) def test_multiple_sessions_isolation(self): """Test that multiple sessions maintain separate contexts.""" session1 = "session-1" session2 = "session-2" # Set different languages for each session self.manager.set_language(session1, 'python') self.manager.set_language(session2, 'javascript') # Verify isolation self.assertEqual(self.manager.get_language(session1), 'python') self.assertEqual(self.manager.get_language(session2), 'javascript') # Verify templates are different template1 = self.manager.get_language_prompt_template(session_id=session1) template2 = self.manager.get_language_prompt_template(session_id=session2) self.assertIn('Python', template1) self.assertIn('JavaScript', template2) if __name__ == '__main__': unittest.main()