|
|
""" |
|
|
Tests for file management functionality (Task 9) |
|
|
Tests Requirements 3.2, 3.3, 3.4 |
|
|
""" |
|
|
import os |
|
|
import base64 |
|
|
import tempfile |
|
|
import shutil |
|
|
from unittest.mock import Mock, patch, MagicMock |
|
|
from PIL import Image |
|
|
from io import BytesIO |
|
|
|
|
|
from agent import VisualizationAgent |
|
|
|
|
|
|
|
|
def test_save_image_creates_png_file(): |
|
|
"""Test that _save_image creates a valid PNG file""" |
|
|
|
|
|
test_image = Image.new('RGB', (100, 100), color='red') |
|
|
|
|
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir: |
|
|
agent = VisualizationAgent(api_key="test_key", output_dir=temp_dir) |
|
|
|
|
|
|
|
|
filename = "test_image.png" |
|
|
filepath = agent._save_image(test_image, filename) |
|
|
|
|
|
|
|
|
assert os.path.exists(filepath) |
|
|
|
|
|
|
|
|
assert filepath.endswith('.png') |
|
|
|
|
|
|
|
|
loaded_image = Image.open(filepath) |
|
|
assert loaded_image.size == (100, 100) |
|
|
|
|
|
|
|
|
def test_save_image_validates_directory_writable(): |
|
|
"""Test that _save_image checks if directory is writable""" |
|
|
test_image = Image.new('RGB', (100, 100), color='blue') |
|
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir: |
|
|
|
|
|
readonly_dir = os.path.join(temp_dir, "readonly") |
|
|
os.makedirs(readonly_dir) |
|
|
os.chmod(readonly_dir, 0o444) |
|
|
|
|
|
try: |
|
|
agent = VisualizationAgent(api_key="test_key", output_dir=readonly_dir) |
|
|
|
|
|
|
|
|
try: |
|
|
agent._save_image(test_image, "test.png") |
|
|
assert False, "Should have raised an exception for read-only directory" |
|
|
except Exception as e: |
|
|
assert "Permission denied" in str(e) or "not writable" in str(e) |
|
|
finally: |
|
|
|
|
|
os.chmod(readonly_dir, 0o755) |
|
|
|
|
|
|
|
|
def test_unique_filename_generation(): |
|
|
"""Test that filenames are unique using timestamp and UUID""" |
|
|
with tempfile.TemporaryDirectory() as temp_dir: |
|
|
agent = VisualizationAgent(api_key="test_key", output_dir=temp_dir) |
|
|
|
|
|
|
|
|
mock_response = Mock() |
|
|
mock_part = Mock() |
|
|
mock_image = Image.new('RGB', (100, 100), color='green') |
|
|
mock_part.inline_data = True |
|
|
mock_part.as_image.return_value = mock_image |
|
|
mock_response.parts = [mock_part] |
|
|
|
|
|
with patch.object(agent.client.models, 'generate_content', return_value=mock_response): |
|
|
|
|
|
result1 = agent.generate_image("test prompt 1") |
|
|
result2 = agent.generate_image("test prompt 2") |
|
|
|
|
|
|
|
|
assert result1['success'] |
|
|
assert result2['success'] |
|
|
|
|
|
|
|
|
path1 = result1.get('image_path') |
|
|
path2 = result2.get('image_path') |
|
|
|
|
|
if path1 and path2: |
|
|
assert path1 != path2 |
|
|
assert os.path.basename(path1) != os.path.basename(path2) |
|
|
|
|
|
|
|
|
def test_image_to_base64_encoding(): |
|
|
"""Test that _image_to_base64 correctly encodes images""" |
|
|
test_image = Image.new('RGB', (50, 50), color='yellow') |
|
|
|
|
|
agent = VisualizationAgent(api_key="test_key") |
|
|
|
|
|
|
|
|
base64_str = agent._image_to_base64(test_image) |
|
|
|
|
|
|
|
|
assert isinstance(base64_str, str) |
|
|
assert len(base64_str) > 0 |
|
|
|
|
|
|
|
|
image_bytes = base64.b64decode(base64_str) |
|
|
decoded_image = Image.open(BytesIO(image_bytes)) |
|
|
|
|
|
assert decoded_image.size == (50, 50) |
|
|
assert decoded_image.mode == 'RGB' |
|
|
|
|
|
|
|
|
def test_generate_image_returns_base64(): |
|
|
"""Test that generate_image returns base64 encoded image for stateless deployment""" |
|
|
agent = VisualizationAgent(api_key="test_key") |
|
|
|
|
|
|
|
|
mock_response = Mock() |
|
|
mock_part = Mock() |
|
|
mock_image = Image.new('RGB', (100, 100), color='purple') |
|
|
mock_part.inline_data = True |
|
|
mock_part.as_image.return_value = mock_image |
|
|
mock_response.parts = [mock_part] |
|
|
|
|
|
with patch.object(agent.client.models, 'generate_content', return_value=mock_response): |
|
|
result = agent.generate_image("test prompt") |
|
|
|
|
|
|
|
|
assert result['success'] |
|
|
|
|
|
|
|
|
assert 'image_base64' in result |
|
|
assert result['image_base64'] is not None |
|
|
assert len(result['image_base64']) > 0 |
|
|
|
|
|
|
|
|
image_bytes = base64.b64decode(result['image_base64']) |
|
|
decoded_image = Image.open(BytesIO(image_bytes)) |
|
|
assert decoded_image.size == (100, 100) |
|
|
|
|
|
|
|
|
def test_generate_image_handles_save_failure_gracefully(): |
|
|
"""Test that generate_image continues even if file save fails (stateless mode)""" |
|
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir: |
|
|
readonly_dir = os.path.join(temp_dir, "readonly") |
|
|
os.makedirs(readonly_dir) |
|
|
|
|
|
agent = VisualizationAgent(api_key="test_key", output_dir=readonly_dir) |
|
|
|
|
|
|
|
|
os.chmod(readonly_dir, 0o444) |
|
|
|
|
|
try: |
|
|
|
|
|
mock_response = Mock() |
|
|
mock_part = Mock() |
|
|
mock_image = Image.new('RGB', (100, 100), color='orange') |
|
|
mock_part.inline_data = True |
|
|
mock_part.as_image.return_value = mock_image |
|
|
mock_response.parts = [mock_part] |
|
|
|
|
|
with patch.object(agent.client.models, 'generate_content', return_value=mock_response): |
|
|
result = agent.generate_image("test prompt") |
|
|
|
|
|
|
|
|
assert result['success'] |
|
|
|
|
|
|
|
|
assert result['image_base64'] is not None |
|
|
|
|
|
|
|
|
|
|
|
finally: |
|
|
|
|
|
os.chmod(readonly_dir, 0o755) |
|
|
|
|
|
|
|
|
def test_output_directory_creation(): |
|
|
"""Test that output directory is created if it doesn't exist""" |
|
|
with tempfile.TemporaryDirectory() as temp_dir: |
|
|
|
|
|
new_dir = os.path.join(temp_dir, "new_output_dir") |
|
|
assert not os.path.exists(new_dir) |
|
|
|
|
|
|
|
|
agent = VisualizationAgent(api_key="test_key", output_dir=new_dir) |
|
|
|
|
|
|
|
|
assert os.path.exists(new_dir) |
|
|
assert os.path.isdir(new_dir) |
|
|
|
|
|
|
|
|
def test_png_format_compliance(): |
|
|
"""Test that all saved images are in PNG format""" |
|
|
test_image = Image.new('RGB', (100, 100), color='cyan') |
|
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir: |
|
|
agent = VisualizationAgent(api_key="test_key", output_dir=temp_dir) |
|
|
|
|
|
|
|
|
filepath = agent._save_image(test_image, "test.png") |
|
|
|
|
|
|
|
|
loaded_image = Image.open(filepath) |
|
|
assert loaded_image.format == 'PNG' |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
import pytest |
|
|
pytest.main([__file__, "-v"]) |
|
|
|