mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-16 01:40:15 +08:00
shutdown() now clears pending requests directly instead of calling cancel() on asyncio.Future instances.
110 lines
3.9 KiB
Python
110 lines
3.9 KiB
Python
"""
|
|
Tests for ABP (AstrBot Protocol) client implementation.
|
|
|
|
ABP is the built-in plugin protocol for in-process star communication.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
import pytest
|
|
|
|
|
|
class TestAstrbotAbpClient:
|
|
"""Test suite for AstrbotAbpClient."""
|
|
|
|
@pytest.fixture
|
|
def abp_client(self):
|
|
"""Create an ABP client instance."""
|
|
from astrbot._internal.protocols.abp.client import AstrbotAbpClient
|
|
|
|
return AstrbotAbpClient()
|
|
|
|
@pytest.fixture
|
|
def mock_star(self):
|
|
"""Create a mock star with a call_tool method."""
|
|
star = AsyncMock()
|
|
star.call_tool = AsyncMock(return_value={"result": "success"})
|
|
return star
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_connected_property_false_initially(self, abp_client):
|
|
"""ABP client should not be connected on initialization."""
|
|
assert abp_client.connected is False
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_connect_sets_connected_true(self, abp_client):
|
|
"""Calling connect() should set connected to True."""
|
|
await abp_client.connect()
|
|
assert abp_client.connected is True
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_register_star(self, abp_client, mock_star):
|
|
"""register_star should add star to internal registry."""
|
|
abp_client.register_star("test-star", mock_star)
|
|
assert "test-star" in abp_client._stars
|
|
assert abp_client._stars["test-star"] is mock_star
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_unregister_star(self, abp_client, mock_star):
|
|
"""unregister_star should remove star from registry."""
|
|
abp_client.register_star("test-star", mock_star)
|
|
abp_client.unregister_star("test-star")
|
|
assert "test-star" not in abp_client._stars
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_unregister_star_idempotent(self, abp_client):
|
|
"""unregister_star should not raise if star doesn't exist."""
|
|
abp_client.unregister_star("non-existent-star") # Should not raise
|
|
assert True
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_call_star_tool_success(self, abp_client, mock_star):
|
|
"""call_star_tool should delegate to star.call_tool."""
|
|
await abp_client.connect()
|
|
abp_client.register_star("test-star", mock_star)
|
|
|
|
result = await abp_client.call_star_tool(
|
|
"test-star", "test-tool", {"arg": "value"}
|
|
)
|
|
|
|
mock_star.call_tool.assert_called_once_with("test-tool", {"arg": "value"})
|
|
assert result == {"result": "success"}
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_call_star_tool_not_connected(self, abp_client, mock_star):
|
|
"""call_star_tool should raise if not connected."""
|
|
abp_client.register_star("test-star", mock_star)
|
|
|
|
with pytest.raises(RuntimeError, match="not connected"):
|
|
await abp_client.call_star_tool("test-star", "test-tool", {})
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_call_star_tool_star_not_found(self, abp_client):
|
|
"""call_star_tool should raise if star not found."""
|
|
await abp_client.connect()
|
|
|
|
with pytest.raises(ValueError, match="Star 'non-existent' not found"):
|
|
await abp_client.call_star_tool("non-existent", "test-tool", {})
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shutdown_sets_connected_false(self, abp_client):
|
|
"""shutdown should set connected to False."""
|
|
await abp_client.connect()
|
|
await abp_client.shutdown()
|
|
assert abp_client.connected is False
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_shutdown_cancels_pending_requests(self, abp_client):
|
|
"""shutdown should clear any pending requests."""
|
|
await abp_client.connect()
|
|
|
|
# Add a pending request entry
|
|
abp_client._pending_requests["req-1"] = {"status": "pending"}
|
|
|
|
await abp_client.shutdown()
|
|
|
|
assert len(abp_client._pending_requests) == 0
|