package com.vincent.rsf.server.ai.service.impl.mcp; import com.fasterxml.jackson.databind.ObjectMapper; import com.vincent.rsf.server.ai.config.AiDefaults; import com.vincent.rsf.server.ai.dto.AiMcpToolPreviewDto; import com.vincent.rsf.server.ai.entity.AiMcpMount; import com.vincent.rsf.server.ai.mapper.AiMcpMountMapper; import com.vincent.rsf.server.ai.service.BuiltinMcpToolRegistry; import com.vincent.rsf.server.ai.service.McpMountRuntimeFactory; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.definition.ToolDefinition; import org.springframework.ai.tool.metadata.ToolMetadata; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class AiMcpAdminServiceTest { @Mock private AiMcpMountMapper aiMcpMountMapper; @Mock private BuiltinMcpToolRegistry builtinMcpToolRegistry; @Mock private McpMountRuntimeFactory mcpMountRuntimeFactory; @Test void shouldMergeGovernedCatalogIntoPreviewResult() { AiMcpAdminService aiMcpAdminService = new AiMcpAdminService( aiMcpMountMapper, builtinMcpToolRegistry, mcpMountRuntimeFactory, new ObjectMapper() ); AiMcpMount mount = new AiMcpMount() .setTransportType(AiDefaults.MCP_TRANSPORT_BUILTIN) .setBuiltinCode(AiDefaults.MCP_BUILTIN_RSF_WMS) .setName("builtin"); ToolCallback callback = mock(ToolCallback.class); ToolDefinition toolDefinition = mock(ToolDefinition.class); ToolMetadata toolMetadata = mock(ToolMetadata.class); McpMountRuntimeFactory.McpMountRuntime runtime = mock(McpMountRuntimeFactory.McpMountRuntime.class); when(toolDefinition.name()).thenReturn("rsf_query_task"); when(toolDefinition.description()).thenReturn("desc"); when(toolDefinition.inputSchema()).thenReturn("{schema}"); when(toolMetadata.returnDirect()).thenReturn(Boolean.FALSE); when(callback.getToolDefinition()).thenReturn(toolDefinition); when(callback.getToolMetadata()).thenReturn(toolMetadata); when(runtime.getToolCallbacks()).thenReturn(new ToolCallback[]{callback}); when(runtime.getErrors()).thenReturn(List.of()); when(mcpMountRuntimeFactory.create(List.of(mount), 1L)).thenReturn(runtime); when(builtinMcpToolRegistry.listBuiltinToolCatalog(AiDefaults.MCP_BUILTIN_RSF_WMS)).thenReturn(List.of( AiMcpToolPreviewDto.builder() .name("rsf_query_task") .toolGroup("任务查询") .toolPurpose("purpose") .queryBoundary("boundary") .exampleQuestions(List.of("q1")) .build() )); List result = aiMcpAdminService.previewTools(mount, 1L); assertEquals(1, result.size()); assertEquals("任务查询", result.get(0).getToolGroup()); assertEquals("purpose", result.get(0).getToolPurpose()); assertEquals("{schema}", result.get(0).getInputSchema()); } }