Files
OpenJarvis/tests/tools/test_image_tool.py
T
Jon Saad-FalconandClaude Opus 4.6 a4c4081ff4 Add desktop distribution pipeline: rolling releases, auto-updates, code signing
- Rewrite .github/workflows/desktop.yml: 2-job pipeline (validate + build-and-release)
  with rolling desktop-latest pre-release on push to main and stable desktop-v* releases
- Add UpdateChecker component: checks for updates on startup + every 30 min,
  background download with progress bar, one-click relaunch
- Configure Tauri updater: endpoints pointing to desktop-latest release, pubkey placeholder
- Add tauri-plugin-process for relaunch support (Cargo.toml, lib.rs, package.json)
- Add macOS Entitlements.plist for notarization (network + file access, no sandbox)
- Add scripts/bump-desktop-version.sh for atomic version bumps across 3 config files
- Add desktop/README.md with dev setup, auto-update architecture, signing docs
- Update .gitignore for desktop/node_modules, dist, target
- Configure macOS minimumSystemVersion, Windows timestampUrl
- Include all Phase 14-21 work: agent hardening, RBAC, taint tracking, workflows,
  skills, knowledge graph, sessions, A2A, MCP templates, WASM sandbox, TUI dashboard,
  production tools, CLI expansion, API expansion, learning productionization,
  Tauri desktop app, and 10 new channels

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 19:14:05 +00:00

151 lines
5.3 KiB
Python

"""Tests for the image_generate tool."""
from __future__ import annotations
import builtins
import sys
from unittest.mock import MagicMock
from openjarvis.tools.image_tool import ImageGenerateTool
class TestImageGenerateTool:
def test_spec(self):
tool = ImageGenerateTool()
assert tool.spec.name == "image_generate"
assert tool.spec.category == "media"
assert "prompt" in tool.spec.parameters["properties"]
assert "prompt" in tool.spec.parameters["required"]
assert tool.spec.required_capabilities == ["network:fetch"]
def test_tool_id(self):
tool = ImageGenerateTool()
assert tool.tool_id == "image_generate"
def test_no_prompt(self):
tool = ImageGenerateTool()
result = tool.execute(prompt="")
assert result.success is False
assert "No prompt" in result.content
def test_no_prompt_param(self):
tool = ImageGenerateTool()
result = tool.execute()
assert result.success is False
assert "No prompt" in result.content
def test_invalid_size(self):
tool = ImageGenerateTool()
result = tool.execute(prompt="a cat", size="999x999")
assert result.success is False
assert "Invalid size" in result.content
def test_unsupported_provider(self):
tool = ImageGenerateTool()
result = tool.execute(prompt="a cat", provider="midjourney")
assert result.success is False
assert "Unsupported provider" in result.content
def test_openai_not_installed(self, monkeypatch):
"""Simulate openai package not being installed."""
monkeypatch.delitem(sys.modules, "openai", raising=False)
original_import = builtins.__import__
def _mock_import(name, *args, **kwargs):
if name == "openai":
raise ImportError("No module named 'openai'")
return original_import(name, *args, **kwargs)
monkeypatch.setattr(builtins, "__import__", _mock_import)
tool = ImageGenerateTool()
result = tool.execute(prompt="a cat")
assert result.success is False
assert "openai package not installed" in result.content
def test_no_api_key(self, monkeypatch):
monkeypatch.delenv("OPENAI_API_KEY", raising=False)
mock_openai = MagicMock()
monkeypatch.setitem(sys.modules, "openai", mock_openai)
tool = ImageGenerateTool()
result = tool.execute(prompt="a cat")
assert result.success is False
assert "No API key" in result.content
def test_successful_generation(self, monkeypatch):
monkeypatch.setenv("OPENAI_API_KEY", "test-key")
mock_image_data = MagicMock()
mock_image_data.url = "https://example.com/image.png"
mock_response = MagicMock()
mock_response.data = [mock_image_data]
mock_client = MagicMock()
mock_client.images.generate.return_value = mock_response
mock_openai = MagicMock()
mock_openai.OpenAI.return_value = mock_client
monkeypatch.setitem(sys.modules, "openai", mock_openai)
tool = ImageGenerateTool()
result = tool.execute(prompt="a cat on a mat")
assert result.success is True
assert result.content == "https://example.com/image.png"
assert result.metadata["url"] == "https://example.com/image.png"
assert result.metadata["size"] == "1024x1024"
assert result.metadata["provider"] == "openai"
def test_save_to_file(self, monkeypatch, tmp_path):
monkeypatch.setenv("OPENAI_API_KEY", "test-key")
mock_image_data = MagicMock()
mock_image_data.url = "https://example.com/image.png"
mock_response = MagicMock()
mock_response.data = [mock_image_data]
mock_client = MagicMock()
mock_client.images.generate.return_value = mock_response
mock_openai = MagicMock()
mock_openai.OpenAI.return_value = mock_client
monkeypatch.setitem(sys.modules, "openai", mock_openai)
# Mock httpx for downloading
import httpx
mock_http_resp = MagicMock()
mock_http_resp.content = b"\x89PNG\r\n\x1a\nfake-image-data"
mock_http_resp.raise_for_status = MagicMock()
monkeypatch.setattr(httpx, "get", MagicMock(return_value=mock_http_resp))
output_file = tmp_path / "output.png"
tool = ImageGenerateTool()
result = tool.execute(
prompt="a cat",
output_path=str(output_file),
)
assert result.success is True
assert output_file.exists()
assert output_file.read_bytes() == b"\x89PNG\r\n\x1a\nfake-image-data"
def test_api_error(self, monkeypatch):
monkeypatch.setenv("OPENAI_API_KEY", "test-key")
mock_client = MagicMock()
mock_client.images.generate.side_effect = RuntimeError("Rate limit exceeded")
mock_openai = MagicMock()
mock_openai.OpenAI.return_value = mock_client
monkeypatch.setitem(sys.modules, "openai", mock_openai)
tool = ImageGenerateTool()
result = tool.execute(prompt="a cat")
assert result.success is False
assert "Image generation error" in result.content
def test_to_openai_function(self):
tool = ImageGenerateTool()
fn = tool.to_openai_function()
assert fn["type"] == "function"
assert fn["function"]["name"] == "image_generate"