CodeReviewAgent / tests /test_ai_review.py
c1r3x's picture
Review Agent: first commit
88d205f
raw
history blame
6.31 kB
#!/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()