2a6863cf70
* test: add tests for star base class and config management - Add Star base class safety helper tests - Expand config management unit tests - Update cron manager tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test: fix plugin_manager test isolation issues - Use local mock plugin instead of real network requests - Clear sys.modules cache for entire data module tree - Clear star_map and star_registry in teardown - Use pytest_asyncio.fixture for async fixture support Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: fix test isolation and compatibility issues - test_main.py: fix version comparison and path assertions for Windows - test_smoke.py: add missing apscheduler.triggers mock modules - test_tool_loop_agent_runner.py: update assertion for new interrupt behavior - test_api_key_open_api.py: use unique session IDs to avoid test conflicts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add unit tests for _version_info comparisons * test: enhance plugin manager tests with mock implementations and improved assertions * test: add mock plugin builder and updater for plugin management tests * fix: resolve pipeline and star import cycles (#5353) * fix: resolve pipeline and star import cycles - Add bootstrap.py and stage_order.py to break circular dependencies - Export Context, PluginManager, StarTools from star module - Update pipeline __init__ to defer imports - Split pipeline initialization into separate bootstrap module Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: add logging for get_config() failure in Star class * fix: reorder logger initialization in base.py --------- Co-authored-by: whatevertogo <whatevertogo@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * test: update cron job scheduling tests and refactor star base tests for clarity * test: expand star base tests for comprehensive coverage - Add tests for Star class initialization and context handling - Add tests for text_to_image with/without config - Add tests for html_render method - Add tests for initialize/terminate lifecycle methods - Add type hint validation tests for Context - Add circular import prevention tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address PR review feedback - use TYPE_CHECKING instead of Any - pipeline/context.py: Use TYPE_CHECKING to import PluginManager instead of Any - pipeline/__init__.py: Add TYPE_CHECKING imports for __all__ exports to satisfy static analyzers - star/register/star_handler.py: Use TYPE_CHECKING to import AstrAgentContext instead of Any - tests: Remove invalid type hint tests that tested incorrect assumptions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: improve TYPE_CHECKING pattern for circular import resolution - star/register/star_handler.py: Use AstrAgentContext instead of Any in generic types - star/context.py: Remove unnecessary else branch with CronJobManager = Any (with __future__ annotations, TYPE_CHECKING imports are sufficient) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: whatevertogo <whatevertogo@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Soulter <37870767+Soulter@users.noreply.github.com>
137 lines
4.8 KiB
Python
137 lines
4.8 KiB
Python
import os
|
|
import sys
|
|
|
|
# 将项目根目录添加到 sys.path
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
|
|
from main import check_dashboard_files, check_env
|
|
|
|
|
|
class _version_info:
|
|
def __init__(self, major, minor):
|
|
self.major = major
|
|
self.minor = minor
|
|
|
|
def __eq__(self, other):
|
|
if isinstance(other, tuple):
|
|
return (self.major, self.minor) == other[:2]
|
|
return (self.major, self.minor) == (other.major, other.minor)
|
|
|
|
def __ge__(self, other):
|
|
if isinstance(other, tuple):
|
|
return (self.major, self.minor) >= other[:2]
|
|
return (self.major, self.minor) >= (other.major, other.minor)
|
|
|
|
|
|
def test_check_env(monkeypatch):
|
|
version_info_correct = _version_info(3, 10)
|
|
version_info_wrong = _version_info(3, 9)
|
|
monkeypatch.setattr(sys, "version_info", version_info_correct)
|
|
with mock.patch("os.makedirs") as mock_makedirs:
|
|
check_env()
|
|
# Check that makedirs was called with paths containing expected dirs
|
|
called_paths = [call[0][0] for call in mock_makedirs.call_args_list]
|
|
# Use os.path.join for cross-platform path matching
|
|
assert any(p.rstrip(os.sep).endswith(os.path.join("data", "config")) for p in called_paths)
|
|
assert any(p.rstrip(os.sep).endswith(os.path.join("data", "plugins")) for p in called_paths)
|
|
assert any(p.rstrip(os.sep).endswith(os.path.join("data", "temp")) for p in called_paths)
|
|
|
|
monkeypatch.setattr(sys, "version_info", version_info_wrong)
|
|
with pytest.raises(SystemExit):
|
|
check_env()
|
|
|
|
|
|
def test_version_info_comparisons():
|
|
"""Test _version_info comparison operators with tuples and other instances."""
|
|
v3_10 = _version_info(3, 10)
|
|
v3_9 = _version_info(3, 9)
|
|
v3_11 = _version_info(3, 11)
|
|
|
|
# Test __eq__ with tuples
|
|
assert v3_10 == (3, 10)
|
|
assert v3_10 != (3, 9)
|
|
assert v3_9 == (3, 9)
|
|
|
|
# Test __ge__ with tuples
|
|
assert v3_10 >= (3, 10)
|
|
assert v3_10 >= (3, 9)
|
|
assert not (v3_9 >= (3, 10))
|
|
assert v3_11 >= (3, 10)
|
|
|
|
# Test __eq__ with other _version_info instances
|
|
assert v3_10 == _version_info(3, 10)
|
|
assert v3_10 != v3_9
|
|
assert v3_10 == v3_10 # Same instance
|
|
|
|
assert v3_10 != v3_11
|
|
|
|
# Test __ge__ with other _version_info instances
|
|
assert v3_10 >= v3_10
|
|
assert v3_10 >= v3_9
|
|
assert not (v3_9 >= v3_10)
|
|
assert v3_11 >= v3_10
|
|
|
|
assert v3_11 >= v3_11 # Same instance
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_check_dashboard_files_not_exists(monkeypatch):
|
|
"""Tests dashboard download when files do not exist."""
|
|
monkeypatch.setattr(os.path, "exists", lambda x: False)
|
|
|
|
with mock.patch("main.download_dashboard") as mock_download:
|
|
await check_dashboard_files()
|
|
mock_download.assert_called_once()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_check_dashboard_files_exists_and_version_match(monkeypatch):
|
|
"""Tests that dashboard is not downloaded when it exists and version matches."""
|
|
# Mock os.path.exists to return True
|
|
monkeypatch.setattr(os.path, "exists", lambda x: True)
|
|
|
|
# Mock get_dashboard_version to return the current version
|
|
with mock.patch("main.get_dashboard_version") as mock_get_version:
|
|
# We need to import VERSION from main's context
|
|
from main import VERSION
|
|
|
|
mock_get_version.return_value = f"v{VERSION}"
|
|
|
|
with mock.patch("main.download_dashboard") as mock_download:
|
|
await check_dashboard_files()
|
|
# Assert that download_dashboard was NOT called
|
|
mock_download.assert_not_called()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_check_dashboard_files_exists_but_version_mismatch(monkeypatch):
|
|
"""Tests that a warning is logged when dashboard version mismatches."""
|
|
monkeypatch.setattr(os.path, "exists", lambda x: True)
|
|
|
|
with mock.patch("main.get_dashboard_version") as mock_get_version:
|
|
mock_get_version.return_value = "v0.0.1" # A different version
|
|
|
|
with mock.patch("main.logger.warning") as mock_logger_warning:
|
|
await check_dashboard_files()
|
|
mock_logger_warning.assert_called_once()
|
|
call_args, _ = mock_logger_warning.call_args
|
|
assert "不符" in call_args[0]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_check_dashboard_files_with_webui_dir_arg(monkeypatch):
|
|
"""Tests that providing a valid webui_dir skips all checks."""
|
|
valid_dir = "/tmp/my-custom-webui"
|
|
monkeypatch.setattr(os.path, "exists", lambda path: path == valid_dir)
|
|
|
|
with mock.patch("main.download_dashboard") as mock_download:
|
|
with mock.patch("main.get_dashboard_version") as mock_get_version:
|
|
result = await check_dashboard_files(webui_dir=valid_dir)
|
|
assert result == valid_dir
|
|
mock_download.assert_not_called()
|
|
mock_get_version.assert_not_called()
|