@app-connect/core 0.0.3 → 1.6.4
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 +434 -425
- package/adapter/mock.js +76 -76
- package/adapter/registry.js +247 -247
- package/handlers/admin.js +62 -60
- package/handlers/auth.js +205 -156
- package/handlers/contact.js +274 -274
- package/handlers/disposition.js +193 -193
- package/handlers/log.js +612 -586
- package/handlers/user.js +101 -101
- package/index.js +1302 -1202
- package/jest.config.js +56 -56
- package/lib/analytics.js +52 -52
- package/lib/callLogComposer.js +550 -451
- package/lib/constants.js +9 -0
- package/lib/encode.js +30 -30
- package/lib/generalErrorMessage.js +41 -41
- package/lib/jwt.js +16 -16
- package/lib/oauth.js +79 -29
- package/lib/util.js +43 -40
- package/models/adminConfigModel.js +17 -17
- package/models/cacheModel.js +23 -23
- package/models/callLogModel.js +27 -27
- package/models/dynamo/lockSchema.js +24 -24
- package/models/dynamo/noteCacheSchema.js +30 -0
- package/models/messageLogModel.js +25 -25
- package/models/sequelize.js +16 -16
- package/models/userModel.js +38 -38
- package/package.json +67 -64
- package/releaseNotes.json +701 -577
- package/test/adapter/registry.test.js +270 -270
- package/test/handlers/auth.test.js +230 -230
- package/test/lib/jwt.test.js +161 -161
- package/test/setup.js +176 -176
|
@@ -1,271 +1,271 @@
|
|
|
1
|
-
const adapterRegistry = require('../../adapter/registry');
|
|
2
|
-
|
|
3
|
-
describe('AdapterRegistry Interface Registration with Composition', () => {
|
|
4
|
-
beforeEach(() => {
|
|
5
|
-
// Clear the registry before each test
|
|
6
|
-
adapterRegistry.adapters.clear();
|
|
7
|
-
adapterRegistry.manifests.clear();
|
|
8
|
-
adapterRegistry.platformInterfaces.clear();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
test('should register interface functions for a platform', () => {
|
|
12
|
-
const mockFunction = jest.fn();
|
|
13
|
-
|
|
14
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'testInterface', mockFunction);
|
|
15
|
-
|
|
16
|
-
expect(adapterRegistry.hasPlatformInterface('testPlatform', 'testInterface')).toBe(true);
|
|
17
|
-
expect(adapterRegistry.getPlatformInterfaces('testPlatform').get('testInterface')).toBe(mockFunction);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test('should throw error when registering non-function as interface', () => {
|
|
21
|
-
expect(() => {
|
|
22
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'testInterface', 'not a function');
|
|
23
|
-
}).toThrow('Interface function must be a function, got: string');
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
test('should return original adapter when no interfaces are registered', () => {
|
|
27
|
-
const mockAdapter = {
|
|
28
|
-
getAuthType: () => 'apiKey',
|
|
29
|
-
createCallLog: jest.fn(),
|
|
30
|
-
updateCallLog: jest.fn()
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
34
|
-
|
|
35
|
-
const retrievedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
36
|
-
expect(retrievedAdapter).toBe(mockAdapter);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
test('should return composed adapter with interface functions when interfaces are registered', () => {
|
|
40
|
-
const mockInterface = jest.fn();
|
|
41
|
-
const mockAdapter = {
|
|
42
|
-
getAuthType: () => 'apiKey',
|
|
43
|
-
createCallLog: jest.fn(),
|
|
44
|
-
updateCallLog: jest.fn()
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
// Register interface function first
|
|
48
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'customMethod', mockInterface);
|
|
49
|
-
|
|
50
|
-
// Register adapter
|
|
51
|
-
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
52
|
-
|
|
53
|
-
// Get composed adapter
|
|
54
|
-
const composedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
55
|
-
|
|
56
|
-
// Should be a different object (composed)
|
|
57
|
-
expect(composedAdapter).not.toBe(mockAdapter);
|
|
58
|
-
|
|
59
|
-
// Should have the interface function
|
|
60
|
-
expect(composedAdapter.customMethod).toBe(mockInterface);
|
|
61
|
-
|
|
62
|
-
// Should still have original methods
|
|
63
|
-
expect(composedAdapter.getAuthType).toBe(mockAdapter.getAuthType);
|
|
64
|
-
expect(composedAdapter.createCallLog).toBe(mockAdapter.createCallLog);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
test('should not override existing adapter methods when composing interfaces', () => {
|
|
68
|
-
const existingMethod = jest.fn();
|
|
69
|
-
const mockAdapter = {
|
|
70
|
-
getAuthType: () => 'apiKey',
|
|
71
|
-
createCallLog: jest.fn(),
|
|
72
|
-
updateCallLog: jest.fn(),
|
|
73
|
-
existingMethod: existingMethod
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
// Register adapter first
|
|
77
|
-
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
78
|
-
|
|
79
|
-
// Try to register interface with same name as existing method
|
|
80
|
-
const newMethod = jest.fn();
|
|
81
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'existingMethod', newMethod);
|
|
82
|
-
|
|
83
|
-
// Get composed adapter
|
|
84
|
-
const composedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
85
|
-
|
|
86
|
-
// Should not override the existing method
|
|
87
|
-
expect(composedAdapter.existingMethod).toBe(existingMethod);
|
|
88
|
-
expect(composedAdapter.existingMethod).not.toBe(newMethod);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test('should preserve original adapter when composing interfaces', () => {
|
|
92
|
-
const mockInterface = jest.fn();
|
|
93
|
-
const mockAdapter = {
|
|
94
|
-
getAuthType: () => 'apiKey',
|
|
95
|
-
createCallLog: jest.fn(),
|
|
96
|
-
updateCallLog: jest.fn()
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'customMethod', mockInterface);
|
|
100
|
-
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
101
|
-
|
|
102
|
-
// Get original adapter
|
|
103
|
-
const originalAdapter = adapterRegistry.getOriginalAdapter('testPlatform');
|
|
104
|
-
|
|
105
|
-
// Original adapter should be unchanged
|
|
106
|
-
expect(originalAdapter).toBe(mockAdapter);
|
|
107
|
-
expect(originalAdapter.customMethod).toBeUndefined();
|
|
108
|
-
|
|
109
|
-
// Composed adapter should have the interface
|
|
110
|
-
const composedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
111
|
-
expect(composedAdapter.customMethod).toBe(mockInterface);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
test('should unregister interface functions', () => {
|
|
115
|
-
const mockFunction = jest.fn();
|
|
116
|
-
|
|
117
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'testInterface', mockFunction);
|
|
118
|
-
expect(adapterRegistry.hasPlatformInterface('testPlatform', 'testInterface')).toBe(true);
|
|
119
|
-
|
|
120
|
-
adapterRegistry.unregisterAdapterInterface('testPlatform', 'testInterface');
|
|
121
|
-
expect(adapterRegistry.hasPlatformInterface('testPlatform', 'testInterface')).toBe(false);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
test('should return empty map for non-existent platform interfaces', () => {
|
|
125
|
-
const interfaces = adapterRegistry.getPlatformInterfaces('nonExistentPlatform');
|
|
126
|
-
expect(interfaces).toBeInstanceOf(Map);
|
|
127
|
-
expect(interfaces.size).toBe(0);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
test('should return false for non-existent platform interface', () => {
|
|
131
|
-
expect(adapterRegistry.hasPlatformInterface('nonExistentPlatform', 'anyInterface')).toBe(false);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
test('should handle multiple interface functions for same platform', () => {
|
|
135
|
-
const mockFunction1 = jest.fn();
|
|
136
|
-
const mockFunction2 = jest.fn();
|
|
137
|
-
const mockAdapter = {
|
|
138
|
-
getAuthType: () => 'apiKey',
|
|
139
|
-
createCallLog: jest.fn(),
|
|
140
|
-
updateCallLog: jest.fn()
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'interface1', mockFunction1);
|
|
144
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'interface2', mockFunction2);
|
|
145
|
-
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
146
|
-
|
|
147
|
-
const platformInterfaces = adapterRegistry.getPlatformInterfaces('testPlatform');
|
|
148
|
-
expect(platformInterfaces.size).toBe(2);
|
|
149
|
-
expect(platformInterfaces.get('interface1')).toBe(mockFunction1);
|
|
150
|
-
expect(platformInterfaces.get('interface2')).toBe(mockFunction2);
|
|
151
|
-
|
|
152
|
-
// Check composed adapter has both interfaces
|
|
153
|
-
const composedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
154
|
-
expect(composedAdapter.interface1).toBe(mockFunction1);
|
|
155
|
-
expect(composedAdapter.interface2).toBe(mockFunction2);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
test('should clean up platform interfaces when unregistering adapter', () => {
|
|
159
|
-
const mockFunction = jest.fn();
|
|
160
|
-
const mockAdapter = {
|
|
161
|
-
getAuthType: () => 'apiKey',
|
|
162
|
-
createCallLog: jest.fn(),
|
|
163
|
-
updateCallLog: jest.fn()
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'testInterface', mockFunction);
|
|
167
|
-
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
168
|
-
|
|
169
|
-
expect(adapterRegistry.hasPlatformInterface('testPlatform', 'testInterface')).toBe(true);
|
|
170
|
-
|
|
171
|
-
adapterRegistry.unregisterAdapter('testPlatform');
|
|
172
|
-
|
|
173
|
-
expect(adapterRegistry.hasPlatformInterface('testPlatform', 'testInterface')).toBe(false);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
test('should get adapter capabilities correctly', () => {
|
|
177
|
-
const mockInterface = jest.fn();
|
|
178
|
-
const mockAdapter = {
|
|
179
|
-
getAuthType: () => 'apiKey',
|
|
180
|
-
createCallLog: jest.fn(),
|
|
181
|
-
updateCallLog: jest.fn()
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'customMethod', mockInterface);
|
|
185
|
-
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
186
|
-
|
|
187
|
-
const capabilities = adapterRegistry.getAdapterCapabilities('testPlatform');
|
|
188
|
-
|
|
189
|
-
expect(capabilities.platform).toBe('testPlatform');
|
|
190
|
-
expect(capabilities.originalMethods).toContain('getAuthType');
|
|
191
|
-
expect(capabilities.originalMethods).toContain('createCallLog');
|
|
192
|
-
expect(capabilities.originalMethods).toContain('updateCallLog');
|
|
193
|
-
expect(capabilities.composedMethods).toContain('customMethod');
|
|
194
|
-
expect(capabilities.registeredInterfaces).toContain('customMethod');
|
|
195
|
-
expect(capabilities.authType).toBe('apiKey');
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
test('should handle interface registration after adapter registration', () => {
|
|
199
|
-
const mockAdapter = {
|
|
200
|
-
getAuthType: () => 'apiKey',
|
|
201
|
-
createCallLog: jest.fn(),
|
|
202
|
-
updateCallLog: jest.fn()
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
// Register adapter first
|
|
206
|
-
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
207
|
-
|
|
208
|
-
// Register interface function after
|
|
209
|
-
const mockInterface = jest.fn();
|
|
210
|
-
adapterRegistry.registerAdapterInterface('testPlatform', 'customMethod', mockInterface);
|
|
211
|
-
|
|
212
|
-
// Get composed adapter
|
|
213
|
-
const composedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
214
|
-
|
|
215
|
-
// Should have the interface function
|
|
216
|
-
expect(composedAdapter.customMethod).toBe(mockInterface);
|
|
217
|
-
|
|
218
|
-
// Original adapter should be unchanged
|
|
219
|
-
const originalAdapter = adapterRegistry.getOriginalAdapter('testPlatform');
|
|
220
|
-
expect(originalAdapter.customMethod).toBeUndefined();
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
test('should return interface-only adapter when no base adapter is registered', () => {
|
|
224
|
-
const mockInterface1 = jest.fn();
|
|
225
|
-
const mockInterface2 = jest.fn();
|
|
226
|
-
|
|
227
|
-
// Register only interface functions, no base adapter
|
|
228
|
-
adapterRegistry.registerAdapterInterface('interfaceOnlyPlatform', 'method1', mockInterface1);
|
|
229
|
-
adapterRegistry.registerAdapterInterface('interfaceOnlyPlatform', 'method2', mockInterface2);
|
|
230
|
-
|
|
231
|
-
// Get adapter - should return interface-only object
|
|
232
|
-
const interfaceOnlyAdapter = adapterRegistry.getAdapter('interfaceOnlyPlatform');
|
|
233
|
-
|
|
234
|
-
// Should have interface functions
|
|
235
|
-
expect(interfaceOnlyAdapter.method1).toBe(mockInterface1);
|
|
236
|
-
expect(interfaceOnlyAdapter.method2).toBe(mockInterface2);
|
|
237
|
-
|
|
238
|
-
// Should not have base adapter methods
|
|
239
|
-
expect(interfaceOnlyAdapter.getAuthType).toBeUndefined();
|
|
240
|
-
|
|
241
|
-
// Should be a plain object, not inherited from any adapter
|
|
242
|
-
expect(Object.getPrototypeOf(interfaceOnlyAdapter)).toBe(Object.prototype);
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
test('should throw error when no adapter and no interfaces are registered', () => {
|
|
246
|
-
expect(() => {
|
|
247
|
-
adapterRegistry.getAdapter('nonExistentPlatform');
|
|
248
|
-
}).toThrow('Adapter not found for platform: nonExistentPlatform');
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
test('should handle mixed scenarios correctly', () => {
|
|
252
|
-
// Scenario 1: Only interfaces, no adapter
|
|
253
|
-
adapterRegistry.registerAdapterInterface('mixedPlatform', 'interfaceMethod', jest.fn());
|
|
254
|
-
const interfaceOnly = adapterRegistry.getAdapter('mixedPlatform');
|
|
255
|
-
expect(interfaceOnly.interfaceMethod).toBeDefined();
|
|
256
|
-
expect(interfaceOnly.getAuthType).toBeUndefined();
|
|
257
|
-
|
|
258
|
-
// Scenario 2: Add adapter later
|
|
259
|
-
const mockAdapter = {
|
|
260
|
-
getAuthType: () => 'apiKey',
|
|
261
|
-
createCallLog: jest.fn(),
|
|
262
|
-
updateCallLog: jest.fn()
|
|
263
|
-
};
|
|
264
|
-
adapterRegistry.registerAdapter('mixedPlatform', mockAdapter);
|
|
265
|
-
|
|
266
|
-
const composedAdapter = adapterRegistry.getAdapter('mixedPlatform');
|
|
267
|
-
expect(composedAdapter.interfaceMethod).toBeDefined();
|
|
268
|
-
expect(composedAdapter.getAuthType).toBeDefined();
|
|
269
|
-
expect(composedAdapter.getAuthType()).toBe('apiKey');
|
|
270
|
-
});
|
|
1
|
+
const adapterRegistry = require('../../adapter/registry');
|
|
2
|
+
|
|
3
|
+
describe('AdapterRegistry Interface Registration with Composition', () => {
|
|
4
|
+
beforeEach(() => {
|
|
5
|
+
// Clear the registry before each test
|
|
6
|
+
adapterRegistry.adapters.clear();
|
|
7
|
+
adapterRegistry.manifests.clear();
|
|
8
|
+
adapterRegistry.platformInterfaces.clear();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('should register interface functions for a platform', () => {
|
|
12
|
+
const mockFunction = jest.fn();
|
|
13
|
+
|
|
14
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'testInterface', mockFunction);
|
|
15
|
+
|
|
16
|
+
expect(adapterRegistry.hasPlatformInterface('testPlatform', 'testInterface')).toBe(true);
|
|
17
|
+
expect(adapterRegistry.getPlatformInterfaces('testPlatform').get('testInterface')).toBe(mockFunction);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('should throw error when registering non-function as interface', () => {
|
|
21
|
+
expect(() => {
|
|
22
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'testInterface', 'not a function');
|
|
23
|
+
}).toThrow('Interface function must be a function, got: string');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('should return original adapter when no interfaces are registered', () => {
|
|
27
|
+
const mockAdapter = {
|
|
28
|
+
getAuthType: () => 'apiKey',
|
|
29
|
+
createCallLog: jest.fn(),
|
|
30
|
+
updateCallLog: jest.fn()
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
34
|
+
|
|
35
|
+
const retrievedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
36
|
+
expect(retrievedAdapter).toBe(mockAdapter);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('should return composed adapter with interface functions when interfaces are registered', () => {
|
|
40
|
+
const mockInterface = jest.fn();
|
|
41
|
+
const mockAdapter = {
|
|
42
|
+
getAuthType: () => 'apiKey',
|
|
43
|
+
createCallLog: jest.fn(),
|
|
44
|
+
updateCallLog: jest.fn()
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Register interface function first
|
|
48
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'customMethod', mockInterface);
|
|
49
|
+
|
|
50
|
+
// Register adapter
|
|
51
|
+
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
52
|
+
|
|
53
|
+
// Get composed adapter
|
|
54
|
+
const composedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
55
|
+
|
|
56
|
+
// Should be a different object (composed)
|
|
57
|
+
expect(composedAdapter).not.toBe(mockAdapter);
|
|
58
|
+
|
|
59
|
+
// Should have the interface function
|
|
60
|
+
expect(composedAdapter.customMethod).toBe(mockInterface);
|
|
61
|
+
|
|
62
|
+
// Should still have original methods
|
|
63
|
+
expect(composedAdapter.getAuthType).toBe(mockAdapter.getAuthType);
|
|
64
|
+
expect(composedAdapter.createCallLog).toBe(mockAdapter.createCallLog);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('should not override existing adapter methods when composing interfaces', () => {
|
|
68
|
+
const existingMethod = jest.fn();
|
|
69
|
+
const mockAdapter = {
|
|
70
|
+
getAuthType: () => 'apiKey',
|
|
71
|
+
createCallLog: jest.fn(),
|
|
72
|
+
updateCallLog: jest.fn(),
|
|
73
|
+
existingMethod: existingMethod
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Register adapter first
|
|
77
|
+
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
78
|
+
|
|
79
|
+
// Try to register interface with same name as existing method
|
|
80
|
+
const newMethod = jest.fn();
|
|
81
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'existingMethod', newMethod);
|
|
82
|
+
|
|
83
|
+
// Get composed adapter
|
|
84
|
+
const composedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
85
|
+
|
|
86
|
+
// Should not override the existing method
|
|
87
|
+
expect(composedAdapter.existingMethod).toBe(existingMethod);
|
|
88
|
+
expect(composedAdapter.existingMethod).not.toBe(newMethod);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('should preserve original adapter when composing interfaces', () => {
|
|
92
|
+
const mockInterface = jest.fn();
|
|
93
|
+
const mockAdapter = {
|
|
94
|
+
getAuthType: () => 'apiKey',
|
|
95
|
+
createCallLog: jest.fn(),
|
|
96
|
+
updateCallLog: jest.fn()
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'customMethod', mockInterface);
|
|
100
|
+
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
101
|
+
|
|
102
|
+
// Get original adapter
|
|
103
|
+
const originalAdapter = adapterRegistry.getOriginalAdapter('testPlatform');
|
|
104
|
+
|
|
105
|
+
// Original adapter should be unchanged
|
|
106
|
+
expect(originalAdapter).toBe(mockAdapter);
|
|
107
|
+
expect(originalAdapter.customMethod).toBeUndefined();
|
|
108
|
+
|
|
109
|
+
// Composed adapter should have the interface
|
|
110
|
+
const composedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
111
|
+
expect(composedAdapter.customMethod).toBe(mockInterface);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('should unregister interface functions', () => {
|
|
115
|
+
const mockFunction = jest.fn();
|
|
116
|
+
|
|
117
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'testInterface', mockFunction);
|
|
118
|
+
expect(adapterRegistry.hasPlatformInterface('testPlatform', 'testInterface')).toBe(true);
|
|
119
|
+
|
|
120
|
+
adapterRegistry.unregisterAdapterInterface('testPlatform', 'testInterface');
|
|
121
|
+
expect(adapterRegistry.hasPlatformInterface('testPlatform', 'testInterface')).toBe(false);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('should return empty map for non-existent platform interfaces', () => {
|
|
125
|
+
const interfaces = adapterRegistry.getPlatformInterfaces('nonExistentPlatform');
|
|
126
|
+
expect(interfaces).toBeInstanceOf(Map);
|
|
127
|
+
expect(interfaces.size).toBe(0);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('should return false for non-existent platform interface', () => {
|
|
131
|
+
expect(adapterRegistry.hasPlatformInterface('nonExistentPlatform', 'anyInterface')).toBe(false);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('should handle multiple interface functions for same platform', () => {
|
|
135
|
+
const mockFunction1 = jest.fn();
|
|
136
|
+
const mockFunction2 = jest.fn();
|
|
137
|
+
const mockAdapter = {
|
|
138
|
+
getAuthType: () => 'apiKey',
|
|
139
|
+
createCallLog: jest.fn(),
|
|
140
|
+
updateCallLog: jest.fn()
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'interface1', mockFunction1);
|
|
144
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'interface2', mockFunction2);
|
|
145
|
+
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
146
|
+
|
|
147
|
+
const platformInterfaces = adapterRegistry.getPlatformInterfaces('testPlatform');
|
|
148
|
+
expect(platformInterfaces.size).toBe(2);
|
|
149
|
+
expect(platformInterfaces.get('interface1')).toBe(mockFunction1);
|
|
150
|
+
expect(platformInterfaces.get('interface2')).toBe(mockFunction2);
|
|
151
|
+
|
|
152
|
+
// Check composed adapter has both interfaces
|
|
153
|
+
const composedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
154
|
+
expect(composedAdapter.interface1).toBe(mockFunction1);
|
|
155
|
+
expect(composedAdapter.interface2).toBe(mockFunction2);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
test('should clean up platform interfaces when unregistering adapter', () => {
|
|
159
|
+
const mockFunction = jest.fn();
|
|
160
|
+
const mockAdapter = {
|
|
161
|
+
getAuthType: () => 'apiKey',
|
|
162
|
+
createCallLog: jest.fn(),
|
|
163
|
+
updateCallLog: jest.fn()
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'testInterface', mockFunction);
|
|
167
|
+
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
168
|
+
|
|
169
|
+
expect(adapterRegistry.hasPlatformInterface('testPlatform', 'testInterface')).toBe(true);
|
|
170
|
+
|
|
171
|
+
adapterRegistry.unregisterAdapter('testPlatform');
|
|
172
|
+
|
|
173
|
+
expect(adapterRegistry.hasPlatformInterface('testPlatform', 'testInterface')).toBe(false);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('should get adapter capabilities correctly', () => {
|
|
177
|
+
const mockInterface = jest.fn();
|
|
178
|
+
const mockAdapter = {
|
|
179
|
+
getAuthType: () => 'apiKey',
|
|
180
|
+
createCallLog: jest.fn(),
|
|
181
|
+
updateCallLog: jest.fn()
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'customMethod', mockInterface);
|
|
185
|
+
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
186
|
+
|
|
187
|
+
const capabilities = adapterRegistry.getAdapterCapabilities('testPlatform');
|
|
188
|
+
|
|
189
|
+
expect(capabilities.platform).toBe('testPlatform');
|
|
190
|
+
expect(capabilities.originalMethods).toContain('getAuthType');
|
|
191
|
+
expect(capabilities.originalMethods).toContain('createCallLog');
|
|
192
|
+
expect(capabilities.originalMethods).toContain('updateCallLog');
|
|
193
|
+
expect(capabilities.composedMethods).toContain('customMethod');
|
|
194
|
+
expect(capabilities.registeredInterfaces).toContain('customMethod');
|
|
195
|
+
expect(capabilities.authType).toBe('apiKey');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
test('should handle interface registration after adapter registration', () => {
|
|
199
|
+
const mockAdapter = {
|
|
200
|
+
getAuthType: () => 'apiKey',
|
|
201
|
+
createCallLog: jest.fn(),
|
|
202
|
+
updateCallLog: jest.fn()
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// Register adapter first
|
|
206
|
+
adapterRegistry.registerAdapter('testPlatform', mockAdapter);
|
|
207
|
+
|
|
208
|
+
// Register interface function after
|
|
209
|
+
const mockInterface = jest.fn();
|
|
210
|
+
adapterRegistry.registerAdapterInterface('testPlatform', 'customMethod', mockInterface);
|
|
211
|
+
|
|
212
|
+
// Get composed adapter
|
|
213
|
+
const composedAdapter = adapterRegistry.getAdapter('testPlatform');
|
|
214
|
+
|
|
215
|
+
// Should have the interface function
|
|
216
|
+
expect(composedAdapter.customMethod).toBe(mockInterface);
|
|
217
|
+
|
|
218
|
+
// Original adapter should be unchanged
|
|
219
|
+
const originalAdapter = adapterRegistry.getOriginalAdapter('testPlatform');
|
|
220
|
+
expect(originalAdapter.customMethod).toBeUndefined();
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test('should return interface-only adapter when no base adapter is registered', () => {
|
|
224
|
+
const mockInterface1 = jest.fn();
|
|
225
|
+
const mockInterface2 = jest.fn();
|
|
226
|
+
|
|
227
|
+
// Register only interface functions, no base adapter
|
|
228
|
+
adapterRegistry.registerAdapterInterface('interfaceOnlyPlatform', 'method1', mockInterface1);
|
|
229
|
+
adapterRegistry.registerAdapterInterface('interfaceOnlyPlatform', 'method2', mockInterface2);
|
|
230
|
+
|
|
231
|
+
// Get adapter - should return interface-only object
|
|
232
|
+
const interfaceOnlyAdapter = adapterRegistry.getAdapter('interfaceOnlyPlatform');
|
|
233
|
+
|
|
234
|
+
// Should have interface functions
|
|
235
|
+
expect(interfaceOnlyAdapter.method1).toBe(mockInterface1);
|
|
236
|
+
expect(interfaceOnlyAdapter.method2).toBe(mockInterface2);
|
|
237
|
+
|
|
238
|
+
// Should not have base adapter methods
|
|
239
|
+
expect(interfaceOnlyAdapter.getAuthType).toBeUndefined();
|
|
240
|
+
|
|
241
|
+
// Should be a plain object, not inherited from any adapter
|
|
242
|
+
expect(Object.getPrototypeOf(interfaceOnlyAdapter)).toBe(Object.prototype);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
test('should throw error when no adapter and no interfaces are registered', () => {
|
|
246
|
+
expect(() => {
|
|
247
|
+
adapterRegistry.getAdapter('nonExistentPlatform');
|
|
248
|
+
}).toThrow('Adapter not found for platform: nonExistentPlatform');
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
test('should handle mixed scenarios correctly', () => {
|
|
252
|
+
// Scenario 1: Only interfaces, no adapter
|
|
253
|
+
adapterRegistry.registerAdapterInterface('mixedPlatform', 'interfaceMethod', jest.fn());
|
|
254
|
+
const interfaceOnly = adapterRegistry.getAdapter('mixedPlatform');
|
|
255
|
+
expect(interfaceOnly.interfaceMethod).toBeDefined();
|
|
256
|
+
expect(interfaceOnly.getAuthType).toBeUndefined();
|
|
257
|
+
|
|
258
|
+
// Scenario 2: Add adapter later
|
|
259
|
+
const mockAdapter = {
|
|
260
|
+
getAuthType: () => 'apiKey',
|
|
261
|
+
createCallLog: jest.fn(),
|
|
262
|
+
updateCallLog: jest.fn()
|
|
263
|
+
};
|
|
264
|
+
adapterRegistry.registerAdapter('mixedPlatform', mockAdapter);
|
|
265
|
+
|
|
266
|
+
const composedAdapter = adapterRegistry.getAdapter('mixedPlatform');
|
|
267
|
+
expect(composedAdapter.interfaceMethod).toBeDefined();
|
|
268
|
+
expect(composedAdapter.getAuthType).toBeDefined();
|
|
269
|
+
expect(composedAdapter.getAuthType()).toBe('apiKey');
|
|
270
|
+
});
|
|
271
271
|
});
|