File size: 7,090 Bytes
1fed057
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import unittest
from unittest.mock import patch, MagicMock, mock_open
from io import BytesIO
from PIL import Image
from src.image.processor import ImageProcessor
from src.utils.constants import Constants

class TestImageProcessor(unittest.TestCase):
    """
    Test cases for the ImageProcessor class.
    """
    
    @patch('src.image.processor.load_dotenv')
    @patch('src.image.processor.os.getenv')
    @patch('src.image.processor.OpenAI')
    def test_init_success(self, mock_openai, mock_getenv, mock_load_dotenv):
        """
        Test successful initialization of ImageProcessor.
        """
        # Setup mocks
        mock_getenv.return_value = "test_key"
        mock_client = MagicMock()
        mock_openai.return_value = mock_client
        
        # Create instance
        processor = ImageProcessor()
        
        # Assertions
        mock_load_dotenv.assert_called_once()
        mock_getenv.assert_called_once_with("OPENAI_API_KEY")
        mock_openai.assert_called_once_with(api_key="test_key")
        self.assertEqual(processor.client, mock_client)
    
    @patch('src.image.processor.load_dotenv')
    @patch('src.image.processor.os.getenv')
    def test_init_missing_api_key(self, mock_getenv, mock_load_dotenv):
        """
        Test initialization with missing OpenAI API key.
        """
        # Setup mocks
        mock_getenv.return_value = None
        
        # Assert that ValueError is raised
        with self.assertRaises(ValueError) as context:
            ImageProcessor()
        
        self.assertEqual(str(context.exception), "OPENAI_API_KEY environment variable is not set")
    
    @patch('src.image.processor.load_dotenv')
    @patch('src.image.processor.os.getenv')
    @patch('src.image.processor.OpenAI')
    @patch('src.image.processor.Image.open')
    @patch('builtins.open', new_callable=mock_open, read_data=b'test_image_data')
    def test_describe_image_file_path(self, mock_file_open, mock_image_open, mock_openai, 
                                      mock_getenv, mock_load_dotenv):
        """
        Test describe_image method with a file path.
        """
        # Setup mocks
        mock_getenv.return_value = "test_key"
        mock_client = MagicMock()
        mock_openai.return_value = mock_client
        
        mock_pil_image = MagicMock()
        mock_image_open.return_value = mock_pil_image
        
        mock_response = MagicMock()
        mock_choice = MagicMock()
        mock_message = MagicMock()
        mock_message.content = "This is a description of the image."
        mock_choice.message = mock_message
        mock_response.choices = [mock_choice]
        mock_client.chat.completions.create.return_value = mock_response
        
        # Create instance and call method
        processor = ImageProcessor()
        result = processor.describe_image("test_image.jpg")
        
        # Assertions
        mock_file_open.assert_called_once_with("test_image.jpg", "rb")
        mock_image_open.assert_called_once()
        mock_pil_image.thumbnail.assert_called_once()
        mock_client.chat.completions.create.assert_called_once()
        self.assertEqual(result, "This is a description of the image.")
    
    @patch('src.image.processor.load_dotenv')
    @patch('src.image.processor.os.getenv')
    @patch('src.image.processor.OpenAI')
    @patch('src.image.processor.Image.open')
    def test_describe_image_bytes(self, mock_image_open, mock_openai, mock_getenv, mock_load_dotenv):
        """
        Test describe_image method with image bytes.
        """
        # Setup mocks
        mock_getenv.return_value = "test_key"
        mock_client = MagicMock()
        mock_openai.return_value = mock_client
        
        mock_pil_image = MagicMock()
        mock_image_open.return_value = mock_pil_image
        
        mock_response = MagicMock()
        mock_choice = MagicMock()
        mock_message = MagicMock()
        mock_message.content = "This is a description of the image."
        mock_choice.message = mock_message
        mock_response.choices = [mock_choice]
        mock_client.chat.completions.create.return_value = mock_response
        
        # Create instance and call method
        processor = ImageProcessor()
        result = processor.describe_image(b'test_image_data')
        
        # Assertions
        mock_image_open.assert_called_once()
        mock_pil_image.thumbnail.assert_called_once()
        mock_client.chat.completions.create.assert_called_once()
        self.assertEqual(result, "This is a description of the image.")
    
    @patch('src.image.processor.load_dotenv')
    @patch('src.image.processor.os.getenv')
    @patch('src.image.processor.OpenAI')
    def test_describe_image_none(self, mock_openai, mock_getenv, mock_load_dotenv):
        """
        Test describe_image method with None input.
        """
        # Setup mocks
        mock_getenv.return_value = "test_key"
        
        # Create instance and call method
        processor = ImageProcessor()
        result = processor.describe_image(None)
        
        # Assertions
        self.assertEqual(result, "")
    
    @patch('src.image.processor.load_dotenv')
    @patch('src.image.processor.os.getenv')
    @patch('src.image.processor.OpenAI')
    @patch('src.image.processor.Image.open')
    def test_resize_image(self, mock_image_open, mock_openai, mock_getenv, mock_load_dotenv):
        """
        Test resize_image method.
        """
        # Setup mocks
        mock_getenv.return_value = "test_key"
        
        # Create a test image
        test_image = Image.new('RGB', (500, 500), color='red')
        mock_image_open.return_value = test_image
        
        # Create a BytesIO object to capture the saved image
        output = BytesIO()
        
        # Mock the save method to write to our BytesIO object
        original_save = test_image.save
        test_image.save = lambda *args, **kwargs: original_save(output, format='JPEG')
        
        # Create instance and call method
        processor = ImageProcessor()
        result = processor.resize_image(b'test_image_data', 200, 200)
        
        # Assertions
        mock_image_open.assert_called_once()
        self.assertIsNotNone(result)
        
        # Verify the image was resized
        resized_image = Image.open(BytesIO(result))
        self.assertLessEqual(resized_image.width, 200)
        self.assertLessEqual(resized_image.height, 200)
    
    @patch('src.image.processor.load_dotenv')
    @patch('src.image.processor.os.getenv')
    @patch('src.image.processor.OpenAI')
    def test_resize_image_none(self, mock_openai, mock_getenv, mock_load_dotenv):
        """
        Test resize_image method with None input.
        """
        # Setup mocks
        mock_getenv.return_value = "test_key"
        
        # Create instance and call method
        processor = ImageProcessor()
        result = processor.resize_image(None)
        
        # Assertions
        self.assertIsNone(result)

if __name__ == '__main__':
    unittest.main()