@app-connect/core 1.7.10 → 1.7.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/connector/developerPortal.js +43 -0
- package/connector/proxy/index.js +10 -3
- package/connector/registry.js +8 -6
- package/handlers/admin.js +135 -22
- package/handlers/auth.js +89 -67
- package/handlers/calldown.js +10 -4
- package/handlers/contact.js +4 -104
- package/handlers/disposition.js +7 -145
- package/handlers/log.js +174 -258
- package/handlers/user.js +19 -6
- package/index.js +280 -47
- package/lib/analytics.js +3 -1
- package/lib/authSession.js +68 -0
- package/lib/callLogComposer.js +498 -420
- package/lib/errorHandler.js +206 -0
- package/lib/jwt.js +2 -0
- package/lib/logger.js +190 -0
- package/lib/oauth.js +21 -10
- package/lib/ringcentral.js +2 -10
- package/lib/sharedSMSComposer.js +471 -0
- package/mcp/SupportedPlatforms.md +12 -0
- package/mcp/lib/validator.js +91 -0
- package/mcp/mcpHandler.js +166 -0
- package/mcp/tools/checkAuthStatus.js +110 -0
- package/mcp/tools/collectAuthInfo.js +91 -0
- package/mcp/tools/createCallLog.js +308 -0
- package/mcp/tools/createContact.js +117 -0
- package/mcp/tools/createMessageLog.js +283 -0
- package/mcp/tools/doAuth.js +190 -0
- package/mcp/tools/findContactByName.js +92 -0
- package/mcp/tools/findContactByPhone.js +101 -0
- package/mcp/tools/getCallLog.js +98 -0
- package/mcp/tools/getGoogleFilePicker.js +103 -0
- package/mcp/tools/getHelp.js +44 -0
- package/mcp/tools/getPublicConnectors.js +53 -0
- package/mcp/tools/index.js +64 -0
- package/mcp/tools/logout.js +68 -0
- package/mcp/tools/rcGetCallLogs.js +78 -0
- package/mcp/tools/setConnector.js +69 -0
- package/mcp/tools/updateCallLog.js +122 -0
- package/models/cacheModel.js +3 -0
- package/package.json +71 -70
- package/releaseNotes.json +24 -0
- package/test/handlers/log.test.js +11 -4
- package/test/lib/logger.test.js +206 -0
- package/test/lib/ringcentral.test.js +0 -6
- package/test/lib/sharedSMSComposer.test.js +1084 -0
- package/test/mcp/tools/collectAuthInfo.test.js +234 -0
- package/test/mcp/tools/createCallLog.test.js +425 -0
- package/test/mcp/tools/createMessageLog.test.js +580 -0
- package/test/mcp/tools/doAuth.test.js +376 -0
- package/test/mcp/tools/findContactByName.test.js +263 -0
- package/test/mcp/tools/findContactByPhone.test.js +284 -0
- package/test/mcp/tools/getCallLog.test.js +286 -0
- package/test/mcp/tools/getGoogleFilePicker.test.js +281 -0
- package/test/mcp/tools/getPublicConnectors.test.js +128 -0
- package/test/mcp/tools/logout.test.js +169 -0
- package/test/mcp/tools/setConnector.test.js +177 -0
- package/test/mcp/tools/updateCallLog.test.js +346 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
const findContactByPhone = require('../../../mcp/tools/findContactByPhone');
|
|
2
|
+
const jwt = require('../../../lib/jwt');
|
|
3
|
+
const connectorRegistry = require('../../../connector/registry');
|
|
4
|
+
const contactCore = require('../../../handlers/contact');
|
|
5
|
+
|
|
6
|
+
// Mock dependencies
|
|
7
|
+
jest.mock('../../../lib/jwt');
|
|
8
|
+
jest.mock('../../../connector/registry');
|
|
9
|
+
jest.mock('../../../handlers/contact');
|
|
10
|
+
|
|
11
|
+
describe('MCP Tool: findContactByPhone', () => {
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
jest.clearAllMocks();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('tool definition', () => {
|
|
17
|
+
test('should have correct tool definition', () => {
|
|
18
|
+
expect(findContactByPhone.definition).toBeDefined();
|
|
19
|
+
expect(findContactByPhone.definition.name).toBe('findContactByPhone');
|
|
20
|
+
expect(findContactByPhone.definition.description).toContain('REQUIRES AUTHENTICATION');
|
|
21
|
+
expect(findContactByPhone.definition.inputSchema).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('should require jwtToken and phoneNumber parameters', () => {
|
|
25
|
+
expect(findContactByPhone.definition.inputSchema.required).toContain('jwtToken');
|
|
26
|
+
expect(findContactByPhone.definition.inputSchema.required).toContain('phoneNumber');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('should have optional parameters', () => {
|
|
30
|
+
expect(findContactByPhone.definition.inputSchema.properties).toHaveProperty('overridingFormat');
|
|
31
|
+
expect(findContactByPhone.definition.inputSchema.properties).toHaveProperty('isExtension');
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('execute', () => {
|
|
36
|
+
test('should find contact by phone successfully', async () => {
|
|
37
|
+
// Arrange
|
|
38
|
+
const mockContact = {
|
|
39
|
+
id: 'contact-123',
|
|
40
|
+
name: 'John Doe',
|
|
41
|
+
phone: '+1234567890',
|
|
42
|
+
type: 'Contact'
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
jwt.decodeJwt.mockReturnValue({
|
|
46
|
+
id: 'user-123',
|
|
47
|
+
platform: 'testCRM'
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const mockConnector = {
|
|
51
|
+
findContact: jest.fn()
|
|
52
|
+
};
|
|
53
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
54
|
+
|
|
55
|
+
contactCore.findContact.mockResolvedValue({
|
|
56
|
+
successful: true,
|
|
57
|
+
contact: mockContact,
|
|
58
|
+
returnMessage: { message: 'Contact found' }
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Act
|
|
62
|
+
const result = await findContactByPhone.execute({
|
|
63
|
+
jwtToken: 'mock-jwt-token',
|
|
64
|
+
phoneNumber: '+1234567890'
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Assert
|
|
68
|
+
expect(result).toEqual({
|
|
69
|
+
success: true,
|
|
70
|
+
data: mockContact
|
|
71
|
+
});
|
|
72
|
+
expect(jwt.decodeJwt).toHaveBeenCalledWith('mock-jwt-token');
|
|
73
|
+
expect(connectorRegistry.getConnector).toHaveBeenCalledWith('testCRM');
|
|
74
|
+
expect(contactCore.findContact).toHaveBeenCalledWith({
|
|
75
|
+
platform: 'testCRM',
|
|
76
|
+
userId: 'user-123',
|
|
77
|
+
phoneNumber: '+1234567890',
|
|
78
|
+
overridingFormat: '',
|
|
79
|
+
isExtension: false
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('should handle overriding format parameter', async () => {
|
|
84
|
+
// Arrange
|
|
85
|
+
const mockContact = {
|
|
86
|
+
id: 'contact-456',
|
|
87
|
+
name: 'Jane Smith',
|
|
88
|
+
phone: '1234567890'
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
jwt.decodeJwt.mockReturnValue({
|
|
92
|
+
id: 'user-123',
|
|
93
|
+
platform: 'testCRM'
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const mockConnector = {
|
|
97
|
+
findContact: jest.fn()
|
|
98
|
+
};
|
|
99
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
100
|
+
|
|
101
|
+
contactCore.findContact.mockResolvedValue({
|
|
102
|
+
successful: true,
|
|
103
|
+
contact: mockContact
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Act
|
|
107
|
+
const result = await findContactByPhone.execute({
|
|
108
|
+
jwtToken: 'mock-jwt-token',
|
|
109
|
+
phoneNumber: '+1234567890',
|
|
110
|
+
overridingFormat: '1234567890'
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Assert
|
|
114
|
+
expect(result.success).toBe(true);
|
|
115
|
+
expect(contactCore.findContact).toHaveBeenCalledWith({
|
|
116
|
+
platform: 'testCRM',
|
|
117
|
+
userId: 'user-123',
|
|
118
|
+
phoneNumber: '+1234567890',
|
|
119
|
+
overridingFormat: '1234567890',
|
|
120
|
+
isExtension: false
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('should handle isExtension parameter', async () => {
|
|
125
|
+
// Arrange
|
|
126
|
+
const mockContact = {
|
|
127
|
+
id: 'contact-789',
|
|
128
|
+
name: 'Bob Johnson',
|
|
129
|
+
phone: '101'
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
jwt.decodeJwt.mockReturnValue({
|
|
133
|
+
id: 'user-123',
|
|
134
|
+
platform: 'testCRM'
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const mockConnector = {
|
|
138
|
+
findContact: jest.fn()
|
|
139
|
+
};
|
|
140
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
141
|
+
|
|
142
|
+
contactCore.findContact.mockResolvedValue({
|
|
143
|
+
successful: true,
|
|
144
|
+
contact: mockContact
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Act
|
|
148
|
+
const result = await findContactByPhone.execute({
|
|
149
|
+
jwtToken: 'mock-jwt-token',
|
|
150
|
+
phoneNumber: '101',
|
|
151
|
+
isExtension: true
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Assert
|
|
155
|
+
expect(result.success).toBe(true);
|
|
156
|
+
expect(contactCore.findContact).toHaveBeenCalledWith({
|
|
157
|
+
platform: 'testCRM',
|
|
158
|
+
userId: 'user-123',
|
|
159
|
+
phoneNumber: '101',
|
|
160
|
+
overridingFormat: '',
|
|
161
|
+
isExtension: true
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test('should return error when contact not found', async () => {
|
|
166
|
+
// Arrange
|
|
167
|
+
jwt.decodeJwt.mockReturnValue({
|
|
168
|
+
id: 'user-123',
|
|
169
|
+
platform: 'testCRM'
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const mockConnector = {
|
|
173
|
+
findContact: jest.fn()
|
|
174
|
+
};
|
|
175
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
176
|
+
|
|
177
|
+
contactCore.findContact.mockResolvedValue({
|
|
178
|
+
successful: false,
|
|
179
|
+
contact: null,
|
|
180
|
+
returnMessage: { message: 'Contact not found' }
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Act
|
|
184
|
+
const result = await findContactByPhone.execute({
|
|
185
|
+
jwtToken: 'mock-jwt-token',
|
|
186
|
+
phoneNumber: '+9999999999'
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Assert
|
|
190
|
+
expect(result).toEqual({
|
|
191
|
+
success: false,
|
|
192
|
+
error: 'Contact not found'
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test('should return error when JWT is invalid', async () => {
|
|
197
|
+
// Arrange
|
|
198
|
+
jwt.decodeJwt.mockReturnValue({
|
|
199
|
+
platform: 'testCRM'
|
|
200
|
+
// id is missing
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Act
|
|
204
|
+
const result = await findContactByPhone.execute({
|
|
205
|
+
jwtToken: 'invalid-token',
|
|
206
|
+
phoneNumber: '+1234567890'
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Assert
|
|
210
|
+
expect(result.success).toBe(false);
|
|
211
|
+
expect(result.error).toContain('Invalid JWT token');
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test('should return error when platform connector not found', async () => {
|
|
215
|
+
// Arrange
|
|
216
|
+
jwt.decodeJwt.mockReturnValue({
|
|
217
|
+
id: 'user-123',
|
|
218
|
+
platform: 'unknownCRM'
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
connectorRegistry.getConnector.mockReturnValue(null);
|
|
222
|
+
|
|
223
|
+
// Act
|
|
224
|
+
const result = await findContactByPhone.execute({
|
|
225
|
+
jwtToken: 'mock-jwt-token',
|
|
226
|
+
phoneNumber: '+1234567890'
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Assert
|
|
230
|
+
expect(result.success).toBe(false);
|
|
231
|
+
expect(result.error).toContain('Platform connector not found');
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test('should return error when findContact is not implemented', async () => {
|
|
235
|
+
// Arrange
|
|
236
|
+
jwt.decodeJwt.mockReturnValue({
|
|
237
|
+
id: 'user-123',
|
|
238
|
+
platform: 'testCRM'
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const mockConnector = {}; // No findContact method
|
|
242
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
243
|
+
|
|
244
|
+
// Act
|
|
245
|
+
const result = await findContactByPhone.execute({
|
|
246
|
+
jwtToken: 'mock-jwt-token',
|
|
247
|
+
phoneNumber: '+1234567890'
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// Assert
|
|
251
|
+
expect(result.success).toBe(false);
|
|
252
|
+
expect(result.error).toContain('not implemented');
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test('should handle unexpected errors gracefully', async () => {
|
|
256
|
+
// Arrange
|
|
257
|
+
jwt.decodeJwt.mockReturnValue({
|
|
258
|
+
id: 'user-123',
|
|
259
|
+
platform: 'testCRM'
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const mockConnector = {
|
|
263
|
+
findContact: jest.fn()
|
|
264
|
+
};
|
|
265
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
266
|
+
|
|
267
|
+
contactCore.findContact.mockRejectedValue(
|
|
268
|
+
new Error('Database connection failed')
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
// Act
|
|
272
|
+
const result = await findContactByPhone.execute({
|
|
273
|
+
jwtToken: 'mock-jwt-token',
|
|
274
|
+
phoneNumber: '+1234567890'
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Assert
|
|
278
|
+
expect(result.success).toBe(false);
|
|
279
|
+
expect(result.error).toBe('Database connection failed');
|
|
280
|
+
expect(result.errorDetails).toBeDefined();
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
const getCallLog = require('../../../mcp/tools/getCallLog');
|
|
2
|
+
const jwt = require('../../../lib/jwt');
|
|
3
|
+
const connectorRegistry = require('../../../connector/registry');
|
|
4
|
+
const logCore = require('../../../handlers/log');
|
|
5
|
+
|
|
6
|
+
// Mock dependencies
|
|
7
|
+
jest.mock('../../../lib/jwt');
|
|
8
|
+
jest.mock('../../../connector/registry');
|
|
9
|
+
jest.mock('../../../handlers/log');
|
|
10
|
+
|
|
11
|
+
describe('MCP Tool: getCallLog', () => {
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
jest.clearAllMocks();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('tool definition', () => {
|
|
17
|
+
test('should have correct tool definition', () => {
|
|
18
|
+
expect(getCallLog.definition).toBeDefined();
|
|
19
|
+
expect(getCallLog.definition.name).toBe('getCallLog');
|
|
20
|
+
expect(getCallLog.definition.description).toContain('REQUIRES AUTHENTICATION');
|
|
21
|
+
expect(getCallLog.definition.inputSchema).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('should require jwtToken and sessionIds parameters', () => {
|
|
25
|
+
expect(getCallLog.definition.inputSchema.required).toContain('jwtToken');
|
|
26
|
+
expect(getCallLog.definition.inputSchema.required).toContain('sessionIds');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('should have requireDetails optional parameter', () => {
|
|
30
|
+
expect(getCallLog.definition.inputSchema.properties).toHaveProperty('requireDetails');
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('execute', () => {
|
|
35
|
+
test('should get call log successfully', async () => {
|
|
36
|
+
// Arrange
|
|
37
|
+
const mockLogs = [
|
|
38
|
+
{
|
|
39
|
+
id: 'log-123',
|
|
40
|
+
sessionId: 'session-123',
|
|
41
|
+
contactId: 'contact-123',
|
|
42
|
+
phoneNumber: '+1234567890',
|
|
43
|
+
callDirection: 'Inbound',
|
|
44
|
+
callDuration: 120
|
|
45
|
+
}
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
jwt.decodeJwt.mockReturnValue({
|
|
49
|
+
id: 'user-123',
|
|
50
|
+
platform: 'testCRM'
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const mockConnector = {
|
|
54
|
+
getCallLog: jest.fn()
|
|
55
|
+
};
|
|
56
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
57
|
+
|
|
58
|
+
logCore.getCallLog.mockResolvedValue({
|
|
59
|
+
successful: true,
|
|
60
|
+
logs: mockLogs,
|
|
61
|
+
returnMessage: { message: 'Logs retrieved' }
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Act
|
|
65
|
+
const result = await getCallLog.execute({
|
|
66
|
+
jwtToken: 'mock-jwt-token',
|
|
67
|
+
sessionIds: 'session-123'
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Assert
|
|
71
|
+
expect(result).toEqual({
|
|
72
|
+
success: true,
|
|
73
|
+
data: mockLogs
|
|
74
|
+
});
|
|
75
|
+
expect(jwt.decodeJwt).toHaveBeenCalledWith('mock-jwt-token');
|
|
76
|
+
expect(connectorRegistry.getConnector).toHaveBeenCalledWith('testCRM');
|
|
77
|
+
expect(logCore.getCallLog).toHaveBeenCalledWith({
|
|
78
|
+
userId: 'user-123',
|
|
79
|
+
sessionIds: 'session-123',
|
|
80
|
+
platform: 'testCRM',
|
|
81
|
+
requireDetails: false
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('should get call logs with multiple session IDs', async () => {
|
|
86
|
+
// Arrange
|
|
87
|
+
const mockLogs = [
|
|
88
|
+
{ sessionId: 'session-123', contactId: 'contact-123' },
|
|
89
|
+
{ sessionId: 'session-456', contactId: 'contact-456' }
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
jwt.decodeJwt.mockReturnValue({
|
|
93
|
+
id: 'user-123',
|
|
94
|
+
platform: 'testCRM'
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const mockConnector = {
|
|
98
|
+
getCallLog: jest.fn()
|
|
99
|
+
};
|
|
100
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
101
|
+
|
|
102
|
+
logCore.getCallLog.mockResolvedValue({
|
|
103
|
+
successful: true,
|
|
104
|
+
logs: mockLogs
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Act
|
|
108
|
+
const result = await getCallLog.execute({
|
|
109
|
+
jwtToken: 'mock-jwt-token',
|
|
110
|
+
sessionIds: 'session-123,session-456'
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Assert
|
|
114
|
+
expect(result.success).toBe(true);
|
|
115
|
+
expect(result.data).toHaveLength(2);
|
|
116
|
+
expect(logCore.getCallLog).toHaveBeenCalledWith({
|
|
117
|
+
userId: 'user-123',
|
|
118
|
+
sessionIds: 'session-123,session-456',
|
|
119
|
+
platform: 'testCRM',
|
|
120
|
+
requireDetails: false
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('should get call logs with detailed information', async () => {
|
|
125
|
+
// Arrange
|
|
126
|
+
const mockLogs = [
|
|
127
|
+
{
|
|
128
|
+
sessionId: 'session-123',
|
|
129
|
+
contactId: 'contact-123',
|
|
130
|
+
detailedInfo: { recording: 'url', transcript: 'text' }
|
|
131
|
+
}
|
|
132
|
+
];
|
|
133
|
+
|
|
134
|
+
jwt.decodeJwt.mockReturnValue({
|
|
135
|
+
id: 'user-123',
|
|
136
|
+
platform: 'testCRM'
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const mockConnector = {
|
|
140
|
+
getCallLog: jest.fn()
|
|
141
|
+
};
|
|
142
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
143
|
+
|
|
144
|
+
logCore.getCallLog.mockResolvedValue({
|
|
145
|
+
successful: true,
|
|
146
|
+
logs: mockLogs
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Act
|
|
150
|
+
const result = await getCallLog.execute({
|
|
151
|
+
jwtToken: 'mock-jwt-token',
|
|
152
|
+
sessionIds: 'session-123',
|
|
153
|
+
requireDetails: true
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Assert
|
|
157
|
+
expect(result.success).toBe(true);
|
|
158
|
+
expect(result.data).toEqual(mockLogs);
|
|
159
|
+
expect(logCore.getCallLog).toHaveBeenCalledWith({
|
|
160
|
+
userId: 'user-123',
|
|
161
|
+
sessionIds: 'session-123',
|
|
162
|
+
platform: 'testCRM',
|
|
163
|
+
requireDetails: true
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('should return error when logs not found', async () => {
|
|
168
|
+
// Arrange
|
|
169
|
+
jwt.decodeJwt.mockReturnValue({
|
|
170
|
+
id: 'user-123',
|
|
171
|
+
platform: 'testCRM'
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const mockConnector = {
|
|
175
|
+
getCallLog: jest.fn()
|
|
176
|
+
};
|
|
177
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
178
|
+
|
|
179
|
+
logCore.getCallLog.mockResolvedValue({
|
|
180
|
+
successful: false,
|
|
181
|
+
logs: [],
|
|
182
|
+
returnMessage: { message: 'Logs not found' }
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Act
|
|
186
|
+
const result = await getCallLog.execute({
|
|
187
|
+
jwtToken: 'mock-jwt-token',
|
|
188
|
+
sessionIds: 'non-existent-session'
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Assert
|
|
192
|
+
expect(result).toEqual({
|
|
193
|
+
success: false,
|
|
194
|
+
error: 'Logs not found'
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test('should return error when JWT is invalid', async () => {
|
|
199
|
+
// Arrange
|
|
200
|
+
jwt.decodeJwt.mockReturnValue({
|
|
201
|
+
platform: 'testCRM'
|
|
202
|
+
// id is missing
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Act
|
|
206
|
+
const result = await getCallLog.execute({
|
|
207
|
+
jwtToken: 'invalid-token',
|
|
208
|
+
sessionIds: 'session-123'
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Assert
|
|
212
|
+
expect(result.success).toBe(false);
|
|
213
|
+
expect(result.error).toContain('Invalid JWT token');
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test('should return error when platform connector not found', async () => {
|
|
217
|
+
// Arrange
|
|
218
|
+
jwt.decodeJwt.mockReturnValue({
|
|
219
|
+
id: 'user-123',
|
|
220
|
+
platform: 'unknownCRM'
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
connectorRegistry.getConnector.mockReturnValue(null);
|
|
224
|
+
|
|
225
|
+
// Act
|
|
226
|
+
const result = await getCallLog.execute({
|
|
227
|
+
jwtToken: 'mock-jwt-token',
|
|
228
|
+
sessionIds: 'session-123'
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// Assert
|
|
232
|
+
expect(result.success).toBe(false);
|
|
233
|
+
expect(result.error).toContain('Platform connector not found');
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test('should return error when getCallLog is not implemented', async () => {
|
|
237
|
+
// Arrange
|
|
238
|
+
jwt.decodeJwt.mockReturnValue({
|
|
239
|
+
id: 'user-123',
|
|
240
|
+
platform: 'testCRM'
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const mockConnector = {}; // No getCallLog method
|
|
244
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
245
|
+
|
|
246
|
+
// Act
|
|
247
|
+
const result = await getCallLog.execute({
|
|
248
|
+
jwtToken: 'mock-jwt-token',
|
|
249
|
+
sessionIds: 'session-123'
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// Assert
|
|
253
|
+
expect(result.success).toBe(false);
|
|
254
|
+
expect(result.error).toContain('not implemented');
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
test('should handle unexpected errors gracefully', async () => {
|
|
258
|
+
// Arrange
|
|
259
|
+
jwt.decodeJwt.mockReturnValue({
|
|
260
|
+
id: 'user-123',
|
|
261
|
+
platform: 'testCRM'
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const mockConnector = {
|
|
265
|
+
getCallLog: jest.fn()
|
|
266
|
+
};
|
|
267
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
268
|
+
|
|
269
|
+
logCore.getCallLog.mockRejectedValue(
|
|
270
|
+
new Error('Database query failed')
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
// Act
|
|
274
|
+
const result = await getCallLog.execute({
|
|
275
|
+
jwtToken: 'mock-jwt-token',
|
|
276
|
+
sessionIds: 'session-123'
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
// Assert
|
|
280
|
+
expect(result.success).toBe(false);
|
|
281
|
+
expect(result.error).toBe('Database query failed');
|
|
282
|
+
expect(result.errorDetails).toBeDefined();
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|