Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR adds comprehensive test coverage for multiple packages in the Agent365-nodejs repository, including tooling services, notification models, and various framework extensions.
Key Changes:
- Added test suites for MCP (Model Context Protocol) tool server configuration and registration services across OpenAI, LangChain, and Claude extensions
- Added test coverage for notification models and handlers including email references, WPX comments, and agent lifecycle events
- Added utility and contract tests for the agents-a365-tooling package
Reviewed Changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/agents-a365-tooling/src/mcp-tool-server-configuration-service.test.ts | Tests for the MCP tool server configuration service with method signature validation |
| tests/agents-a365-tooling/src/contracts.test.ts | Contract tests for MCPServerConfig, InputSchema, and McpClientTool interfaces |
| tests/agents-a365-tooling/src/Utility.test.ts | Tests for utility methods including tools mode, MCP base URLs, and environment configurations |
| tests/agents-a365-tooling-extensions-openai/src/mcp-tool-registration-service.test.ts | Tests for OpenAI-specific MCP tool registration with Agent integration |
| tests/agents-a365-tooling-extensions-langchain/src/mcp-tool-registration-service.test.ts | Tests for LangChain-specific MCP tool registration with MultiServerMCPClient |
| tests/agents-a365-tooling-extensions-claude/src/mcp-tool-registration-service.test.ts | Tests for Claude-specific MCP tool registration with agent options configuration |
| tests/agents-a365-notifications/models/wpx-comment.test.ts | Tests for WPX comment model including factory functions and type guards |
| tests/agents-a365-notifications/models/notification-type.test.ts | Tests for NotificationType enum values and reverse lookups |
| tests/agents-a365-notifications/models/email-reference.test.ts | Tests for email reference model with HTML content handling |
| tests/agents-a365-notifications/models/agent-notification-activity.test.ts | Tests for agent notification activity creation and property mapping |
| tests/agents-a365-notifications/extensions/email-response.test.ts | Tests for email response entity with HTML body handling |
| tests/agents-a365-notifications/extensions/agent-notification.test.ts | Tests for agent notification extension methods on AgentApplication |
| tests/agents-a365-notifications/extensions/agent-notification-utilities.test.ts | Tests for notification utility functions including channel and lifecycle validation |
| tests/agents-a365-notifications/extensions/agent-notification-handler.test.ts | Tests for AgentNotificationHandler type and implementation patterns |
| tests/agents-a365-notifications/constants.test.ts | Tests for notification channel and lifecycle event constants |
| // Assert | ||
| expect(AgenticAuthenticationService.GetAgenticUserToken).toHaveBeenCalledWith(mockAuthorization, mockTurnContext); | ||
| expect(Utility.ValidateAuthToken).toHaveBeenCalledWith(serviceToken); | ||
| expect(mockConfigService.listToolServers).toHaveBeenCalledWith('agent-123', serviceToken); |
There was a problem hiding this comment.
The test calls listToolServers with only 2 parameters ('agent-123', serviceToken), but according to line 35 of the test file in agents-a365-tooling package, the method signature expects 3 parameters (agentUserId, environmentId, authToken). This test appears to be missing the environmentId parameter.
| // Assert | ||
| expect(Utility.ValidateAuthToken).toHaveBeenCalledWith(authToken); | ||
| expect(AgenticAuthenticationService.GetAgenticUserToken).not.toHaveBeenCalled(); | ||
| expect(mockConfigService.listToolServers).toHaveBeenCalledWith('agent-123', authToken); |
There was a problem hiding this comment.
The test calls listToolServers with only 2 parameters ('agent-123', authToken), but according to line 35, the method signature expects 3 parameters (agentUserId, environmentId, authToken). This test appears to be missing the environmentId parameter.
| // Assert | ||
| expect(AgenticAuthenticationService.GetAgenticUserToken).toHaveBeenCalledWith(mockAuthorization, mockTurnContext); | ||
| expect(Utility.ValidateAuthToken).toHaveBeenCalledWith(serviceToken); | ||
| expect(mockConfigService.listToolServers).toHaveBeenCalledWith('agent-123', serviceToken); |
There was a problem hiding this comment.
The test calls listToolServers with only 2 parameters ('agent-123', serviceToken), but according to line 35 of the test file in this package, the method signature expects 3 parameters (agentUserId, environmentId, authToken). This test appears to be missing the environmentId parameter.
| // Assert | ||
| expect(Utility.ValidateAuthToken).toHaveBeenCalledWith(authToken); | ||
| expect(AgenticAuthenticationService.GetAgenticUserToken).not.toHaveBeenCalled(); | ||
| expect(mockConfigService.listToolServers).toHaveBeenCalledWith('agent-123', authToken); |
There was a problem hiding this comment.
The test calls listToolServers with only 2 parameters ('agent-123', authToken), but according to line 35 of the test file in this package, the method signature expects 3 parameters (agentUserId, environmentId, authToken). This test appears to be missing the environmentId parameter.
| // Assert | ||
| expect(AgenticAuthenticationService.GetAgenticUserToken).toHaveBeenCalledWith(mockAuthorization, mockTurnContext); | ||
| expect(Utility.ValidateAuthToken).toHaveBeenCalledWith(serviceToken); | ||
| expect(mockConfigService.listToolServers).toHaveBeenCalledWith('agent-123', serviceToken); |
There was a problem hiding this comment.
The test calls listToolServers with only 2 parameters ('agent-123', serviceToken), but according to line 35 of the test file in agents-a365-tooling, the method signature expects 3 parameters (agentUserId, environmentId, authToken). This test appears to be missing the environmentId parameter.
| // Assert | ||
| expect(Utility.ValidateAuthToken).toHaveBeenCalledWith(authToken); | ||
| expect(AgenticAuthenticationService.GetAgenticUserToken).not.toHaveBeenCalled(); | ||
| expect(mockConfigService.listToolServers).toHaveBeenCalledWith('agent-123', authToken); |
There was a problem hiding this comment.
The test calls listToolServers with only 2 parameters ('agent-123', authToken), but according to line 35 of the test file in agents-a365-tooling package, the method signature expects 3 parameters (agentUserId, environmentId, authToken). This test appears to be missing the environmentId parameter.
| createEmailReference, | ||
| createWpxComment | ||
| } from '@microsoft/agents-a365-notifications'; | ||
| import { Activity, ConversationAccount, ChannelAccount } from '@microsoft/agents-activity'; |
There was a problem hiding this comment.
Unused import ChannelAccount.
| import { Activity, ConversationAccount, ChannelAccount } from '@microsoft/agents-activity'; | |
| import { Activity, ConversationAccount } from '@microsoft/agents-activity'; |
| // Licensed under the MIT License. | ||
|
|
||
| import { McpToolRegistrationService } from '@microsoft/agents-a365-tooling-extensions-claude'; | ||
| import { McpToolServerConfigurationService, McpClientTool, Utility, MCPServerConfig } from '@microsoft/agents-a365-tooling'; |
There was a problem hiding this comment.
Unused import MCPServerConfig.
| import { McpToolServerConfigurationService, McpClientTool, Utility, MCPServerConfig } from '@microsoft/agents-a365-tooling'; | |
| import { McpToolServerConfigurationService, McpClientTool, Utility } from '@microsoft/agents-a365-tooling'; |
| import { AgenticAuthenticationService } from '@microsoft/agents-a365-runtime'; | ||
| import { TurnContext, Authorization } from '@microsoft/agents-hosting'; | ||
| import { createAgent, ReactAgent } from 'langchain'; | ||
| import { ClientConfig, Connection, MultiServerMCPClient } from '@langchain/mcp-adapters'; |
There was a problem hiding this comment.
Unused imports ClientConfig, Connection.
| import { ClientConfig, Connection, MultiServerMCPClient } from '@langchain/mcp-adapters'; | |
| import { MultiServerMCPClient } from '@langchain/mcp-adapters'; |
| @@ -84,7 +84,7 @@ describe('OpenAIAgentsTraceInstrumentor', () => { | |||
| expect((instrumentor as any)._config.enabled).toBe(false); | |||
| }); | |||
|
|
|||
There was a problem hiding this comment.
This test has been skipped using it.skip(). Consider adding a comment explaining why this test is being skipped and when it should be re-enabled. If the test is no longer needed, it should be removed entirely rather than skipped.
| // Skipped due to flakiness in CI environment; see issue #1234. Re-enable when OpenAI Agents SDK mocking is stable. |
|
Please update at least the title of the PR so that it's clear what these changes are for |
|
|
||
| // Mock utility methods | ||
| (Utility.ValidateAuthToken as jest.Mock) = jest.fn(); | ||
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); |
There was a problem hiding this comment.
The mock assignment (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn() uses assignment instead of proper mock setup. Consider using jest.spyOn(AgenticAuthenticationService, 'GetAgenticUserToken') instead, which is the recommended approach and provides better type safety and test reliability.
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); | |
| jest.spyOn(AgenticAuthenticationService, 'GetAgenticUserToken').mockImplementation(jest.fn()); |
| expect(() => { | ||
| (WPX_COMMENT_TYPE as any) = 'modified'; | ||
| }).toThrow(); |
There was a problem hiding this comment.
This test attempts to verify immutability by reassigning a constant, which will throw in strict mode but may not work as expected in all contexts. A better approach would be to use Object.isFrozen() or check Object.getOwnPropertyDescriptor() to verify the property is not writable: expect(Object.getOwnPropertyDescriptor(module, 'WPX_COMMENT_TYPE')?.writable).toBe(false).
| expect(() => { | |
| (WPX_COMMENT_TYPE as any) = 'modified'; | |
| }).toThrow(); | |
| // Check that the property is not writable | |
| const descriptor = Object.getOwnPropertyDescriptor( | |
| require('@microsoft/agents-a365-notifications'), | |
| 'WPX_COMMENT_TYPE' | |
| ); | |
| expect(descriptor?.writable).toBe(false); |
| }); | ||
|
|
||
| it('should auto-enable when enabled: true is passed', () => { | ||
| it.skip('should auto-enable when enabled: true is passed', () => { |
There was a problem hiding this comment.
This test is being skipped with it.skip. Consider either removing the test if it's no longer needed, or fixing the underlying issue so the test can run. Skipped tests can accumulate technical debt and may indicate unresolved problems in the code.
|
|
||
| // Mock utility methods | ||
| (Utility.ValidateAuthToken as jest.Mock) = jest.fn(); | ||
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); |
There was a problem hiding this comment.
The mock assignment (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn() uses assignment instead of proper mock setup. Consider using jest.spyOn(AgenticAuthenticationService, 'GetAgenticUserToken') instead, which is the recommended approach and provides better type safety and test reliability.
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); | |
| jest.spyOn(AgenticAuthenticationService, 'GetAgenticUserToken').mockImplementation(jest.fn()); |
|
|
||
| // Mock utility methods | ||
| (Utility.ValidateAuthToken as jest.Mock) = jest.fn(); | ||
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); |
There was a problem hiding this comment.
The mock assignment (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn() uses assignment instead of proper mock setup. Consider using jest.spyOn(AgenticAuthenticationService, 'GetAgenticUserToken') instead, which is the recommended approach and provides better type safety and test reliability.
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); | |
| jest.spyOn(AgenticAuthenticationService, 'GetAgenticUserToken').mockImplementation(jest.fn()); |
| expect(() => { | ||
| (EMAIL_NOTIFICATION_TYPE as any) = 'modified'; | ||
| }).toThrow(); |
There was a problem hiding this comment.
This test attempts to verify immutability by reassigning a constant, which will throw in strict mode but may not work as expected in all contexts. A better approach would be to use Object.isFrozen() or check Object.getOwnPropertyDescriptor() to verify the property is not writable: expect(Object.getOwnPropertyDescriptor(module, 'EMAIL_NOTIFICATION_TYPE')?.writable).toBe(false).
| expect(() => { | |
| (EMAIL_NOTIFICATION_TYPE as any) = 'modified'; | |
| }).toThrow(); | |
| // Check that the EMAIL_NOTIFICATION_TYPE export is not writable | |
| const moduleDescriptor = Object.getOwnPropertyDescriptor( | |
| require('@microsoft/agents-a365-notifications'), | |
| 'EMAIL_NOTIFICATION_TYPE' | |
| ); | |
| expect(moduleDescriptor?.writable).toBe(false); |
| jest.mock('@microsoft/agents-a365-notifications'); | ||
|
|
There was a problem hiding this comment.
The mocking pattern jest.mock('@microsoft/agents-a365-notifications') at line 10 mocks the entire module, but then the test imports and uses actual implementations from the same module (lines 5-7). This creates a conflict where the module is both mocked and used for real types/functions. Consider either removing the mock or being more specific about what needs to be mocked using jest.mock with a factory function, or use jest.spyOn for specific functions instead.
| jest.mock('@microsoft/agents-a365-notifications'); |
|
|
||
| // Mock utility methods | ||
| (Utility.ValidateAuthToken as jest.Mock) = jest.fn(); | ||
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); |
There was a problem hiding this comment.
The mock assignment (Utility.ValidateAuthToken as jest.Mock) = jest.fn() uses a non-standard pattern. This should be jest.spyOn(Utility, 'ValidateAuthToken').mockImplementation(...) or properly configured through the mock definition. The current pattern may not work as expected and could cause test failures.
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); | |
| jest.spyOn(AgenticAuthenticationService, 'GetAgenticUserToken').mockImplementation(jest.fn()); |
| (Utility.ValidateAuthToken as jest.Mock) = jest.fn(); | ||
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); |
There was a problem hiding this comment.
The mock assignment (Utility.ValidateAuthToken as jest.Mock) = jest.fn() uses a non-standard pattern. This should be jest.spyOn(Utility, 'ValidateAuthToken').mockImplementation(...) or properly configured through the mock definition. The current pattern may not work as expected and could cause test failures.
| (Utility.ValidateAuthToken as jest.Mock) = jest.fn(); | |
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); | |
| jest.spyOn(Utility, 'ValidateAuthToken').mockImplementation(jest.fn()); | |
| jest.spyOn(AgenticAuthenticationService, 'GetAgenticUserToken').mockImplementation(jest.fn()); |
|
|
||
| // Mock utility methods | ||
| (Utility.ValidateAuthToken as jest.Mock) = jest.fn(); | ||
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); |
There was a problem hiding this comment.
The mock assignment (Utility.ValidateAuthToken as jest.Mock) = jest.fn() uses a non-standard pattern. This should be jest.spyOn(Utility, 'ValidateAuthToken').mockImplementation(...) or properly configured through the mock definition. The current pattern may not work as expected and could cause test failures.
| (AgenticAuthenticationService.GetAgenticUserToken as jest.Mock) = jest.fn(); | |
| jest.spyOn(AgenticAuthenticationService, 'GetAgenticUserToken').mockImplementation(jest.fn()); |
No description provided.