@app-connect/core 1.7.25 → 1.7.26
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/.env.test +5 -5
- package/README.md +441 -441
- package/connector/developerPortal.js +31 -31
- package/connector/mock.js +84 -77
- package/connector/proxy/engine.js +164 -164
- package/connector/proxy/index.js +500 -500
- package/connector/registry.js +252 -252
- package/docs/README.md +50 -50
- package/docs/architecture.md +93 -93
- package/docs/connectors.md +116 -116
- package/docs/handlers.md +125 -125
- package/docs/libraries.md +101 -101
- package/docs/models.md +144 -144
- package/docs/routes.md +115 -115
- package/docs/tests.md +73 -73
- package/handlers/admin.js +523 -523
- package/handlers/appointment.js +193 -0
- package/handlers/auth.js +296 -296
- package/handlers/calldown.js +99 -99
- package/handlers/contact.js +280 -280
- package/handlers/disposition.js +82 -80
- package/handlers/log.js +984 -973
- package/handlers/managedAuth.js +446 -446
- package/handlers/plugin.js +208 -208
- package/handlers/user.js +142 -142
- package/index.js +3140 -2652
- package/jest.config.js +56 -56
- package/lib/analytics.js +54 -54
- package/lib/authSession.js +109 -109
- package/lib/cacheCleanup.js +21 -0
- package/lib/callLogComposer.js +898 -898
- package/lib/callLogLookup.js +34 -0
- package/lib/constants.js +8 -8
- package/lib/debugTracer.js +177 -177
- package/lib/encode.js +30 -30
- package/lib/errorHandler.js +218 -206
- package/lib/generalErrorMessage.js +41 -41
- package/lib/jwt.js +18 -18
- package/lib/logger.js +190 -190
- package/lib/migrateCallLogsSchema.js +116 -0
- package/lib/ringcentral.js +266 -266
- package/lib/s3ErrorLogReport.js +65 -65
- package/lib/sharedSMSComposer.js +471 -471
- package/lib/util.js +67 -67
- package/mcp/README.md +412 -395
- package/mcp/lib/validator.js +91 -91
- package/mcp/mcpHandler.js +425 -425
- package/mcp/tools/cancelAppointment.js +101 -0
- package/mcp/tools/checkAuthStatus.js +105 -105
- package/mcp/tools/confirmAppointment.js +101 -0
- package/mcp/tools/createAppointment.js +157 -0
- package/mcp/tools/createCallLog.js +327 -316
- package/mcp/tools/createContact.js +117 -117
- package/mcp/tools/createMessageLog.js +287 -287
- package/mcp/tools/doAuth.js +60 -60
- package/mcp/tools/findContactByName.js +93 -93
- package/mcp/tools/findContactByPhone.js +101 -101
- package/mcp/tools/getCallLog.js +111 -102
- package/mcp/tools/getGoogleFilePicker.js +99 -99
- package/mcp/tools/getHelp.js +43 -43
- package/mcp/tools/getPublicConnectors.js +94 -94
- package/mcp/tools/getSessionInfo.js +90 -90
- package/mcp/tools/index.js +51 -41
- package/mcp/tools/listAppointments.js +163 -0
- package/mcp/tools/logout.js +96 -96
- package/mcp/tools/rcGetCallLogs.js +65 -65
- package/mcp/tools/updateAppointment.js +154 -0
- package/mcp/tools/updateCallLog.js +130 -126
- package/mcp/ui/App/App.tsx +358 -358
- package/mcp/ui/App/components/AuthInfoForm.tsx +113 -113
- package/mcp/ui/App/components/AuthSuccess.tsx +22 -22
- package/mcp/ui/App/components/ConnectorList.tsx +82 -82
- package/mcp/ui/App/components/DebugPanel.tsx +43 -43
- package/mcp/ui/App/components/OAuthConnect.tsx +270 -270
- package/mcp/ui/App/lib/callTool.ts +130 -130
- package/mcp/ui/App/lib/debugLog.ts +41 -41
- package/mcp/ui/App/lib/developerPortal.ts +111 -111
- package/mcp/ui/App/main.css +5 -5
- package/mcp/ui/App/root.tsx +13 -13
- package/mcp/ui/index.html +13 -13
- package/mcp/ui/package-lock.json +6356 -6356
- package/mcp/ui/package.json +25 -25
- package/mcp/ui/tsconfig.json +26 -26
- package/mcp/ui/vite.config.ts +16 -16
- package/models/accountDataModel.js +33 -33
- package/models/adminConfigModel.js +35 -35
- package/models/cacheModel.js +30 -26
- package/models/callDownListModel.js +34 -34
- package/models/callLogModel.js +33 -27
- package/models/dynamo/connectorSchema.js +146 -146
- package/models/dynamo/lockSchema.js +24 -24
- package/models/dynamo/noteCacheSchema.js +29 -29
- package/models/llmSessionModel.js +17 -17
- package/models/messageLogModel.js +25 -25
- package/models/sequelize.js +16 -16
- package/models/userModel.js +45 -45
- package/package.json +1 -1
- package/releaseNotes.json +1093 -1081
- package/test/connector/proxy/engine.test.js +126 -126
- package/test/connector/proxy/index.test.js +279 -279
- package/test/connector/proxy/sample.json +161 -161
- package/test/connector/registry.test.js +415 -415
- package/test/handlers/admin.test.js +616 -616
- package/test/handlers/auth.test.js +1018 -1018
- package/test/handlers/contact.test.js +1014 -1014
- package/test/handlers/log.test.js +1298 -1160
- package/test/handlers/managedAuth.test.js +457 -457
- package/test/handlers/plugin.test.js +380 -380
- package/test/index.test.js +105 -105
- package/test/lib/cacheCleanup.test.js +42 -0
- package/test/lib/callLogComposer.test.js +1231 -1231
- package/test/lib/debugTracer.test.js +328 -328
- package/test/lib/jwt.test.js +176 -176
- package/test/lib/logger.test.js +206 -206
- package/test/lib/oauth.test.js +359 -359
- package/test/lib/ringcentral.test.js +467 -467
- package/test/lib/sharedSMSComposer.test.js +1084 -1084
- package/test/lib/util.test.js +329 -329
- package/test/mcp/tools/checkAuthStatus.test.js +83 -83
- package/test/mcp/tools/createCallLog.test.js +436 -436
- package/test/mcp/tools/createContact.test.js +58 -58
- package/test/mcp/tools/createMessageLog.test.js +595 -595
- package/test/mcp/tools/doAuth.test.js +113 -113
- package/test/mcp/tools/findContactByName.test.js +275 -275
- package/test/mcp/tools/findContactByPhone.test.js +296 -296
- package/test/mcp/tools/getCallLog.test.js +298 -298
- package/test/mcp/tools/getGoogleFilePicker.test.js +281 -281
- package/test/mcp/tools/getPublicConnectors.test.js +107 -107
- package/test/mcp/tools/getSessionInfo.test.js +127 -127
- package/test/mcp/tools/logout.test.js +233 -233
- package/test/mcp/tools/rcGetCallLogs.test.js +56 -56
- package/test/mcp/tools/updateCallLog.test.js +360 -360
- package/test/models/accountDataModel.test.js +98 -98
- package/test/models/dynamo/connectorSchema.test.js +189 -189
- package/test/models/models.test.js +568 -539
- package/test/routes/managedAuthRoutes.test.js +104 -104
- package/test/setup.js +178 -178
|
@@ -1,298 +1,298 @@
|
|
|
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 decodeJwt returns null', async () => {
|
|
217
|
-
jwt.decodeJwt.mockReturnValue(null);
|
|
218
|
-
|
|
219
|
-
const result = await getCallLog.execute({
|
|
220
|
-
jwtToken: 'invalid-token',
|
|
221
|
-
sessionIds: ['session-123']
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
expect(result.success).toBe(false);
|
|
225
|
-
expect(result.error).toContain('Invalid JWT token');
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
test('should return error when platform connector not found', async () => {
|
|
229
|
-
// Arrange
|
|
230
|
-
jwt.decodeJwt.mockReturnValue({
|
|
231
|
-
id: 'user-123',
|
|
232
|
-
platform: 'unknownCRM'
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
connectorRegistry.getConnector.mockReturnValue(null);
|
|
236
|
-
|
|
237
|
-
// Act
|
|
238
|
-
const result = await getCallLog.execute({
|
|
239
|
-
jwtToken: 'mock-jwt-token',
|
|
240
|
-
sessionIds: 'session-123'
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
// Assert
|
|
244
|
-
expect(result.success).toBe(false);
|
|
245
|
-
expect(result.error).toContain('Platform connector not found');
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
test('should return error when getCallLog is not implemented', async () => {
|
|
249
|
-
// Arrange
|
|
250
|
-
jwt.decodeJwt.mockReturnValue({
|
|
251
|
-
id: 'user-123',
|
|
252
|
-
platform: 'testCRM'
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
const mockConnector = {}; // No getCallLog method
|
|
256
|
-
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
257
|
-
|
|
258
|
-
// Act
|
|
259
|
-
const result = await getCallLog.execute({
|
|
260
|
-
jwtToken: 'mock-jwt-token',
|
|
261
|
-
sessionIds: 'session-123'
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
// Assert
|
|
265
|
-
expect(result.success).toBe(false);
|
|
266
|
-
expect(result.error).toContain('not implemented');
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
test('should handle unexpected errors gracefully', async () => {
|
|
270
|
-
// Arrange
|
|
271
|
-
jwt.decodeJwt.mockReturnValue({
|
|
272
|
-
id: 'user-123',
|
|
273
|
-
platform: 'testCRM'
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
const mockConnector = {
|
|
277
|
-
getCallLog: jest.fn()
|
|
278
|
-
};
|
|
279
|
-
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
280
|
-
|
|
281
|
-
logCore.getCallLog.mockRejectedValue(
|
|
282
|
-
new Error('Database query failed')
|
|
283
|
-
);
|
|
284
|
-
|
|
285
|
-
// Act
|
|
286
|
-
const result = await getCallLog.execute({
|
|
287
|
-
jwtToken: 'mock-jwt-token',
|
|
288
|
-
sessionIds: 'session-123'
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
// Assert
|
|
292
|
-
expect(result.success).toBe(false);
|
|
293
|
-
expect(result.error).toBe('Database query failed');
|
|
294
|
-
expect(result.errorDetails).toBeDefined();
|
|
295
|
-
});
|
|
296
|
-
});
|
|
297
|
-
});
|
|
298
|
-
|
|
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 decodeJwt returns null', async () => {
|
|
217
|
+
jwt.decodeJwt.mockReturnValue(null);
|
|
218
|
+
|
|
219
|
+
const result = await getCallLog.execute({
|
|
220
|
+
jwtToken: 'invalid-token',
|
|
221
|
+
sessionIds: ['session-123']
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
expect(result.success).toBe(false);
|
|
225
|
+
expect(result.error).toContain('Invalid JWT token');
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test('should return error when platform connector not found', async () => {
|
|
229
|
+
// Arrange
|
|
230
|
+
jwt.decodeJwt.mockReturnValue({
|
|
231
|
+
id: 'user-123',
|
|
232
|
+
platform: 'unknownCRM'
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
connectorRegistry.getConnector.mockReturnValue(null);
|
|
236
|
+
|
|
237
|
+
// Act
|
|
238
|
+
const result = await getCallLog.execute({
|
|
239
|
+
jwtToken: 'mock-jwt-token',
|
|
240
|
+
sessionIds: 'session-123'
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// Assert
|
|
244
|
+
expect(result.success).toBe(false);
|
|
245
|
+
expect(result.error).toContain('Platform connector not found');
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test('should return error when getCallLog is not implemented', async () => {
|
|
249
|
+
// Arrange
|
|
250
|
+
jwt.decodeJwt.mockReturnValue({
|
|
251
|
+
id: 'user-123',
|
|
252
|
+
platform: 'testCRM'
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
const mockConnector = {}; // No getCallLog method
|
|
256
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
257
|
+
|
|
258
|
+
// Act
|
|
259
|
+
const result = await getCallLog.execute({
|
|
260
|
+
jwtToken: 'mock-jwt-token',
|
|
261
|
+
sessionIds: 'session-123'
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// Assert
|
|
265
|
+
expect(result.success).toBe(false);
|
|
266
|
+
expect(result.error).toContain('not implemented');
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test('should handle unexpected errors gracefully', async () => {
|
|
270
|
+
// Arrange
|
|
271
|
+
jwt.decodeJwt.mockReturnValue({
|
|
272
|
+
id: 'user-123',
|
|
273
|
+
platform: 'testCRM'
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
const mockConnector = {
|
|
277
|
+
getCallLog: jest.fn()
|
|
278
|
+
};
|
|
279
|
+
connectorRegistry.getConnector.mockReturnValue(mockConnector);
|
|
280
|
+
|
|
281
|
+
logCore.getCallLog.mockRejectedValue(
|
|
282
|
+
new Error('Database query failed')
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
// Act
|
|
286
|
+
const result = await getCallLog.execute({
|
|
287
|
+
jwtToken: 'mock-jwt-token',
|
|
288
|
+
sessionIds: 'session-123'
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
// Assert
|
|
292
|
+
expect(result.success).toBe(false);
|
|
293
|
+
expect(result.error).toBe('Database query failed');
|
|
294
|
+
expect(result.errorDetails).toBeDefined();
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|