mateclaw/mateclaw-server/src/test/java/vip/mate/channel/ChannelMessageRouterApprovalDenyTest.java

69 lines
3.6 KiB
Java

package vip.mate.channel;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import vip.mate.agent.AgentService;
import vip.mate.approval.ApprovalWorkflowService;
import vip.mate.approval.PendingApproval;
import vip.mate.approval.ResolveOutcome;
import vip.mate.channel.model.ChannelEntity;
import vip.mate.channel.notification.ApprovalNotificationService;
import vip.mate.channel.service.ChannelService;
import vip.mate.channel.web.ChatStreamTracker;
import vip.mate.memory.event.ConversationCompletionPublisher;
import vip.mate.tts.TtsService;
import vip.mate.workspace.conversation.ConversationService;
import java.lang.reflect.Method;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
class ChannelMessageRouterApprovalDenyTest {
@Test
void denyAlreadyResolvedDoesNotRewriteConversationOrBroadcastDeniedHint() throws Exception {
AgentService agentService = mock(AgentService.class);
ConversationService conversationService = mock(ConversationService.class);
ChannelService channelService = mock(ChannelService.class);
ChannelSessionStore channelSessionStore = mock(ChannelSessionStore.class);
ApprovalWorkflowService approvalService = mock(ApprovalWorkflowService.class);
ApprovalNotificationService approvalNotificationService = mock(ApprovalNotificationService.class);
ConversationCompletionPublisher completionPublisher = mock(ConversationCompletionPublisher.class);
TtsService ttsService = mock(TtsService.class);
ChatStreamTracker streamTracker = mock(ChatStreamTracker.class);
ChannelChatOriginFactory chatOriginFactory = mock(ChannelChatOriginFactory.class);
ChannelErrorClassifier errorClassifier = mock(ChannelErrorClassifier.class);
ChannelMessageRouter router = new ChannelMessageRouter(agentService, conversationService,
channelService, channelSessionStore, approvalService, approvalNotificationService,
completionPublisher, ttsService, new ObjectMapper(), streamTracker,
chatOriginFactory, errorClassifier,
new InboundMessageDeduplicator(new ChannelDedupProperties()));
PendingApproval pending = new PendingApproval("abcdef123", "conv-1", "alice",
"dangerous_tool", "{}", "needs approval");
when(approvalService.findPendingByConversation("conv-1")).thenReturn(pending);
when(approvalService.resolve("abcdef123", "alice", "denied"))
.thenReturn(ResolveOutcome.alreadyResolved("abcdef123"));
ChannelAdapter adapter = mock(ChannelAdapter.class);
when(adapter.getChannelType()).thenReturn("test");
ChannelEntity channel = new ChannelEntity();
channel.setAgentId(100L);
ChannelMessage message = ChannelMessage.builder()
.senderId("alice")
.replyToken("reply-1")
.content("/deny abcdef")
.build();
Method process = ChannelMessageRouter.class.getDeclaredMethod(
"processMessage", ChannelMessage.class, ChannelAdapter.class, ChannelEntity.class, String.class);
process.setAccessible(true);
process.invoke(router, message, adapter, channel, "conv-1");
verify(conversationService, never()).removeApprovalPlaceholders(anyString());
verify(conversationService, never()).saveMessage(anyString(), anyString(), anyString(), any(), anyString());
verify(adapter).sendMessage("reply-1", "⚠️ 审批记录已过期或已被处理。");
verify(adapter, never()).sendMessage(eq("reply-1"), startsWith("⛔ 已拒绝执行工具"));
}
}