| import type { PluginAuthMethods } from '@librechat/data-schemas'; | |
| import type { GenericTool } from '@librechat/agents'; | |
| import { getPluginAuthMap } from '~/agents/auth'; | |
| import { getUserMCPAuthMap } from '../auth'; | |
| jest.mock('~/agents/auth', () => ({ | |
| getPluginAuthMap: jest.fn(), | |
| })); | |
| const mockGetPluginAuthMap = getPluginAuthMap as jest.MockedFunction<typeof getPluginAuthMap>; | |
| const createMockTool = ( | |
| name: string, | |
| mcpRawServerName?: string, | |
| mcp = true, | |
| ): GenericTool & { mcpRawServerName?: string; mcp?: boolean } => | |
| ({ | |
| name, | |
| mcpRawServerName, | |
| mcp, | |
| description: 'Mock tool', | |
| }) as GenericTool & { mcpRawServerName?: string; mcp?: boolean }; | |
| const mockFindPluginAuthsByKeys: PluginAuthMethods['findPluginAuthsByKeys'] = jest.fn(); | |
| describe('getUserMCPAuthMap', () => { | |
| beforeEach(() => { | |
| jest.clearAllMocks(); | |
| }); | |
| describe('Core Functionality', () => { | |
| it('should handle server names with various special characters and spaces', async () => { | |
| const testCases = [ | |
| { | |
| originalName: 'Connector: Company', | |
| normalizedToolName: 'tool_mcp_Connector__Company', | |
| }, | |
| { | |
| originalName: 'Server (Production) @ Company.com', | |
| normalizedToolName: 'tool_mcp_Server__Production____Company.com', | |
| }, | |
| { | |
| originalName: '🌟 Testing Server™ (α-β) 测试服务器', | |
| normalizedToolName: 'tool_mcp_____Testing_Server_________', | |
| }, | |
| ]; | |
| const toolInstances = testCases.map((testCase) => | |
| createMockTool(testCase.normalizedToolName, testCase.originalName), | |
| ); | |
| const expectedKeys = testCases.map((tc) => `mcp_${tc.originalName}`); | |
| mockGetPluginAuthMap.mockResolvedValue({}); | |
| await getUserMCPAuthMap({ | |
| userId: 'user123', | |
| toolInstances, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(mockGetPluginAuthMap).toHaveBeenCalledWith({ | |
| userId: 'user123', | |
| pluginKeys: expectedKeys, | |
| throwError: false, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| }); | |
| }); | |
| describe('Edge Cases', () => { | |
| it('should return empty object when no tools have mcpRawServerName', async () => { | |
| const toolInstances = [ | |
| createMockTool('regular_tool', undefined, false), | |
| createMockTool('another_tool', undefined, false), | |
| createMockTool('test_mcp_Server_no_raw_name', undefined), | |
| ]; | |
| const result = await getUserMCPAuthMap({ | |
| userId: 'user123', | |
| toolInstances, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(result).toEqual({}); | |
| expect(mockGetPluginAuthMap).not.toHaveBeenCalled(); | |
| }); | |
| it('should handle empty or undefined tools array', async () => { | |
| let result = await getUserMCPAuthMap({ | |
| userId: 'user123', | |
| tools: [], | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(result).toEqual({}); | |
| expect(mockGetPluginAuthMap).not.toHaveBeenCalled(); | |
| result = await getUserMCPAuthMap({ | |
| userId: 'user123', | |
| tools: undefined, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(result).toEqual({}); | |
| expect(mockGetPluginAuthMap).not.toHaveBeenCalled(); | |
| }); | |
| it('should handle database errors gracefully', async () => { | |
| const toolInstances = [createMockTool('test_mcp_Server1', 'Server1')]; | |
| const dbError = new Error('Database connection failed'); | |
| mockGetPluginAuthMap.mockRejectedValue(dbError); | |
| const result = await getUserMCPAuthMap({ | |
| userId: 'user123', | |
| toolInstances, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(result).toEqual({}); | |
| }); | |
| it('should handle non-Error exceptions gracefully', async () => { | |
| const toolInstances = [createMockTool('test_mcp_Server1', 'Server1')]; | |
| mockGetPluginAuthMap.mockRejectedValue('String error'); | |
| const result = await getUserMCPAuthMap({ | |
| userId: 'user123', | |
| toolInstances, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(result).toEqual({}); | |
| }); | |
| it('should handle mixed null/undefined values in tools array', async () => { | |
| const tools = [ | |
| 'test_mcp_Server1', | |
| null, | |
| 'test_mcp_Server2', | |
| undefined, | |
| 'regular_tool', | |
| 'test_mcp_Server3', | |
| ]; | |
| mockGetPluginAuthMap.mockResolvedValue({ | |
| mcp_Server1: { API_KEY: 'key1' }, | |
| mcp_Server2: { API_KEY: 'key2' }, | |
| mcp_Server3: { API_KEY: 'key3' }, | |
| }); | |
| const result = await getUserMCPAuthMap({ | |
| userId: 'user123', | |
| tools: tools as (string | undefined)[], | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(mockGetPluginAuthMap).toHaveBeenCalledWith({ | |
| userId: 'user123', | |
| pluginKeys: ['mcp_Server1', 'mcp_Server2', 'mcp_Server3'], | |
| throwError: false, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(result).toEqual({ | |
| mcp_Server1: { API_KEY: 'key1' }, | |
| mcp_Server2: { API_KEY: 'key2' }, | |
| mcp_Server3: { API_KEY: 'key3' }, | |
| }); | |
| }); | |
| it('should handle mixed null/undefined values in servers array', async () => { | |
| const servers = ['Server1', null, 'Server2', undefined, 'Server3']; | |
| mockGetPluginAuthMap.mockResolvedValue({ | |
| mcp_Server1: { API_KEY: 'key1' }, | |
| mcp_Server2: { API_KEY: 'key2' }, | |
| mcp_Server3: { API_KEY: 'key3' }, | |
| }); | |
| const result = await getUserMCPAuthMap({ | |
| userId: 'user123', | |
| servers: servers as (string | undefined)[], | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(mockGetPluginAuthMap).toHaveBeenCalledWith({ | |
| userId: 'user123', | |
| pluginKeys: ['mcp_Server1', 'mcp_Server2', 'mcp_Server3'], | |
| throwError: false, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(result).toEqual({ | |
| mcp_Server1: { API_KEY: 'key1' }, | |
| mcp_Server2: { API_KEY: 'key2' }, | |
| mcp_Server3: { API_KEY: 'key3' }, | |
| }); | |
| }); | |
| it('should handle mixed null/undefined values in toolInstances array', async () => { | |
| const toolInstances = [ | |
| createMockTool('test_mcp_Server1', 'Server1'), | |
| null, | |
| createMockTool('test_mcp_Server2', 'Server2'), | |
| undefined, | |
| createMockTool('regular_tool', undefined, false), | |
| createMockTool('test_mcp_Server3', 'Server3'), | |
| ]; | |
| mockGetPluginAuthMap.mockResolvedValue({ | |
| mcp_Server1: { API_KEY: 'key1' }, | |
| mcp_Server2: { API_KEY: 'key2' }, | |
| mcp_Server3: { API_KEY: 'key3' }, | |
| }); | |
| const result = await getUserMCPAuthMap({ | |
| userId: 'user123', | |
| toolInstances: toolInstances as (GenericTool | null)[], | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(mockGetPluginAuthMap).toHaveBeenCalledWith({ | |
| userId: 'user123', | |
| pluginKeys: ['mcp_Server1', 'mcp_Server2', 'mcp_Server3'], | |
| throwError: false, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(result).toEqual({ | |
| mcp_Server1: { API_KEY: 'key1' }, | |
| mcp_Server2: { API_KEY: 'key2' }, | |
| mcp_Server3: { API_KEY: 'key3' }, | |
| }); | |
| }); | |
| }); | |
| describe('Integration', () => { | |
| it('should handle complete workflow with normalized tool names and original server names', async () => { | |
| const originalServerName = 'Connector: Company'; | |
| const toolName = 'test_auth_mcp_Connector__Company'; | |
| const toolInstances = [createMockTool(toolName, originalServerName)]; | |
| const mockCustomUserVars = { | |
| 'mcp_Connector: Company': { | |
| API_KEY: 'test123', | |
| SECRET_TOKEN: 'secret456', | |
| }, | |
| }; | |
| mockGetPluginAuthMap.mockResolvedValue(mockCustomUserVars); | |
| const result = await getUserMCPAuthMap({ | |
| userId: 'user123', | |
| toolInstances, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(mockGetPluginAuthMap).toHaveBeenCalledWith({ | |
| userId: 'user123', | |
| pluginKeys: ['mcp_Connector: Company'], | |
| throwError: false, | |
| findPluginAuthsByKeys: mockFindPluginAuthsByKeys, | |
| }); | |
| expect(result).toEqual(mockCustomUserVars); | |
| }); | |
| }); | |
| }); | |