File size: 6,309 Bytes
88d205f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Unit tests for the AI Review Service
"""
import unittest
from unittest.mock import patch, MagicMock
import os
import sys
from pathlib import Path
# Add the project root directory to the Python path
project_root = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(project_root))
from src.mcp.ai_review import AIReviewService
class TestAIReviewService(unittest.TestCase):
"""Test cases for the AIReviewService class"""
def setUp(self):
"""Set up test fixtures"""
# Mock environment variables
self.env_patcher = patch.dict('os.environ', {'ANTHROPIC_API_KEY': 'test_api_key'})
self.env_patcher.start()
# Create the service
self.service = AIReviewService()
def tearDown(self):
"""Tear down test fixtures"""
self.env_patcher.stop()
def test_init(self):
"""Test initialization of the service"""
self.assertIsNotNone(self.service)
self.assertEqual(self.service.api_key, 'test_api_key')
self.assertTrue(self.service.is_available())
def test_is_available(self):
"""Test is_available method"""
# With API key
self.assertTrue(self.service.is_available())
# Without API key
with patch.dict('os.environ', {}, clear=True):
service = AIReviewService()
self.assertFalse(service.is_available())
@patch('anthropic.Anthropic')
def test_review_code(self, mock_anthropic):
"""Test review_code method"""
# Mock the Anthropic client
mock_client = MagicMock()
mock_anthropic.return_value = mock_client
# Mock the response
mock_response = MagicMock()
mock_content = MagicMock()
mock_content.text = "# Code Review\n\n## Code Quality\nThe code is well-structured.\n\n## Potential Issues\nLine 10: Variable 'x' is not used."
mock_response.content = [mock_content]
mock_client.messages.create.return_value = mock_response
# Test the method
result = self.service.review_code(
file_path="test.py",
file_content="def test():\n x = 1\n return 2",
language="Python"
)
# Verify the result
self.assertEqual(result['status'], 'success')
self.assertEqual(result['review_text'], mock_content.text)
self.assertIn('suggestions', result)
@patch('anthropic.Anthropic')
def test_review_code_error(self, mock_anthropic):
"""Test review_code method with error"""
# Mock the Anthropic client
mock_client = MagicMock()
mock_anthropic.return_value = mock_client
# Mock an error
mock_client.messages.create.side_effect = Exception("API error")
# Test the method
result = self.service.review_code(
file_path="test.py",
file_content="def test():\n return 1",
language="Python"
)
# Verify the result
self.assertEqual(result['status'], 'error')
self.assertEqual(result['error'], 'API error')
self.assertEqual(result['suggestions'], [])
def test_review_code_unavailable(self):
"""Test review_code method when service is unavailable"""
# Create a service without API key
with patch.dict('os.environ', {}, clear=True):
service = AIReviewService()
# Test the method
result = service.review_code(
file_path="test.py",
file_content="def test():\n return 1",
language="Python"
)
# Verify the result
self.assertEqual(result['status'], 'error')
self.assertIn('AI review service is not available', result['error'])
self.assertEqual(result['suggestions'], [])
@patch('anthropic.Anthropic')
@patch('builtins.open', new_callable=unittest.mock.mock_open, read_data="def test():\n return 1")
def test_review_repository(self, mock_open, mock_anthropic):
"""Test review_repository method"""
# Mock the Anthropic client
mock_client = MagicMock()
mock_anthropic.return_value = mock_client
# Mock the response for file review
mock_file_response = MagicMock()
mock_file_content = MagicMock()
mock_file_content.text = "# Code Review\n\n## Code Quality\nThe code is well-structured."
mock_file_response.content = [mock_file_content]
# Mock the response for repository summary
mock_summary_response = MagicMock()
mock_summary_content = MagicMock()
mock_summary_content.text = "# Repository Review\n\nOverall, the code quality is good."
mock_summary_response.content = [mock_summary_content]
# Set up the mock to return different responses
mock_client.messages.create.side_effect = [mock_file_response, mock_summary_response]
# Test the method
result = self.service.review_repository(
repo_path="/test/repo",
files=["test.py"],
languages=["Python"]
)
# Verify the result
self.assertEqual(result['status'], 'success')
self.assertIn('reviews', result)
self.assertIn('test.py', result['reviews'])
self.assertEqual(result['summary'], mock_summary_content.text)
def test_get_language_from_extension(self):
"""Test _get_language_from_extension method"""
self.assertEqual(self.service._get_language_from_extension(".py"), "Python")
self.assertEqual(self.service._get_language_from_extension(".js"), "JavaScript")
self.assertEqual(self.service._get_language_from_extension(".ts"), "TypeScript")
self.assertEqual(self.service._get_language_from_extension(".java"), "Java")
self.assertEqual(self.service._get_language_from_extension(".go"), "Go")
self.assertEqual(self.service._get_language_from_extension(".rs"), "Rust")
self.assertIsNone(self.service._get_language_from_extension(".unknown"))
if __name__ == "__main__":
unittest.main() |