from __future__ import annotations from unittest.mock import AsyncMock, MagicMock import pytest from yuxi.channels.models import DeliveryResult class TestWeChatGroupAdmin: @pytest.fixture def admin(self): from yuxi.channels.adapters.wechat.group_admin import WeChatGroupAdmin return WeChatGroupAdmin() @pytest.fixture def mock_client(self): client = MagicMock() client.get_access_token = AsyncMock(return_value="test_token") return client @pytest.fixture def mock_http(self): return AsyncMock() @pytest.mark.asyncio async def test_get_channel_info_success(self, admin, mock_client, mock_http): mock_resp = MagicMock() mock_resp.json.return_value = { "errcode": 0, "chat_info": {"chatid": "chat123", "name": "Test Group", "userlist": ["user1", "user2"]}, } mock_http.get = AsyncMock(return_value=mock_resp) info = await admin.get_channel_info(mock_client, mock_http, "chat123") assert info["chatid"] == "chat123" assert info["name"] == "Test Group" @pytest.mark.asyncio async def test_get_channel_info_error(self, admin, mock_client, mock_http): mock_resp = MagicMock() mock_resp.json.return_value = {"errcode": 60011, "errmsg": "Invalid userid list"} mock_http.get = AsyncMock(return_value=mock_resp) info = await admin.get_channel_info(mock_client, mock_http, "chat_nonexist") assert info == {} @pytest.mark.asyncio async def test_rename_group_success(self, admin, mock_client, mock_http): mock_resp = MagicMock() mock_resp.json.return_value = {"errcode": 0, "errmsg": "ok"} mock_http.post = AsyncMock(return_value=mock_resp) result = await admin.rename_group(mock_client, mock_http, "chat123", "New Name") assert result.success is True @pytest.mark.asyncio async def test_rename_group_error(self, admin, mock_client, mock_http): mock_resp = MagicMock() mock_resp.json.return_value = {"errcode": 60011, "errmsg": "Invalid chatid"} mock_http.post = AsyncMock(return_value=mock_resp) result = await admin.rename_group(mock_client, mock_http, "chat123", "New Name") assert result.success is False assert "Invalid chatid" in result.error @pytest.mark.asyncio async def test_add_participant_success(self, admin, mock_client, mock_http): get_resp = MagicMock() get_resp.json.return_value = { "errcode": 0, "chat_info": {"chatid": "chat123", "userlist": ["user1"]}, } mock_http.get = AsyncMock(return_value=get_resp) post_resp = MagicMock() post_resp.json.return_value = {"errcode": 0, "errmsg": "ok"} mock_http.post = AsyncMock(return_value=post_resp) result = await admin.add_participant(mock_client, mock_http, "chat123", "user2") assert result.success is True @pytest.mark.asyncio async def test_remove_participant_success(self, admin, mock_client, mock_http): post_resp = MagicMock() post_resp.json.return_value = {"errcode": 0, "errmsg": "ok"} mock_http.post = AsyncMock(return_value=post_resp) result = await admin.remove_participant(mock_client, mock_http, "chat123", "user2") assert result.success is True @pytest.mark.asyncio async def test_set_group_icon_unsupported(self, admin, mock_client, mock_http): result = await admin.set_group_icon(mock_client, mock_http, "chat123", b"icon_data") assert result.success is False assert "not support" in result.error.lower() @pytest.mark.asyncio async def test_leave_group_unsupported(self, admin, mock_client, mock_http): result = await admin.leave_group(mock_client, mock_http, "chat123") assert result.success is False @pytest.mark.asyncio async def test_list_members_success(self, admin, mock_client, mock_http): get_resp = MagicMock() get_resp.json.return_value = { "errcode": 0, "chat_info": {"chatid": "chat123", "userlist": ["user1", "user2", "user3"]}, } mock_http.get = AsyncMock(return_value=get_resp) members = await admin.list_members(mock_client, mock_http, "chat123") assert len(members) == 3 assert members[0] == {"user_id": "user1"} class TestGroupAdminCapabilities: def test_group_admin_actions_are_registered(self): from yuxi.channels.adapters.wechat.message_actions import WECHAT_MESSAGE_ACTIONS, WeChatMessageActionAdapter adapter = WeChatMessageActionAdapter() all_actions = adapter.list_all_actions() assert "renameGroup" in all_actions assert all_actions["renameGroup"]["status"] == "implemented" assert "addParticipant" in all_actions assert all_actions["addParticipant"]["status"] == "implemented" assert "removeParticipant" in all_actions assert all_actions["removeParticipant"]["status"] == "implemented" supported = adapter.list_supported_actions() assert "renameGroup" in supported assert "addParticipant" in supported assert "removeParticipant" in supported