@morgan-stanley/composeui-fdc3 0.1.0-alpha.5
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/LICENSE +201 -0
- package/README.md +6 -0
- package/jest.config.ts +23 -0
- package/package.json +49 -0
- package/rollup.config.js +16 -0
- package/src/ComposeUIChannel.spec.ts +242 -0
- package/src/ComposeUIContextListener.spec.ts +109 -0
- package/src/ComposeUIDesktopAgent.spec.ts +197 -0
- package/src/ComposeUIDesktopAgent.ts +252 -0
- package/src/ComposeUIIntentHandling.spec.ts +369 -0
- package/src/ComposeUIMessageRouterChannelFactory.spec.ts +200 -0
- package/src/ComposeUIMessageRouterMetadataClient.spec.ts +240 -0
- package/src/ComposeUIMessageRouterOpenClient.spec.ts +239 -0
- package/src/index.ts +66 -0
- package/src/infrastructure/ChannelFactory.ts +25 -0
- package/src/infrastructure/ChannelItem.ts +20 -0
- package/src/infrastructure/ChannelType.ts +14 -0
- package/src/infrastructure/ComposeUIChannel.ts +87 -0
- package/src/infrastructure/ComposeUIContextListener.ts +154 -0
- package/src/infrastructure/ComposeUIErrors.ts +21 -0
- package/src/infrastructure/ComposeUIIntentListener.ts +105 -0
- package/src/infrastructure/ComposeUIIntentResolution.ts +58 -0
- package/src/infrastructure/ComposeUIPrivateChannel.ts +197 -0
- package/src/infrastructure/ComposeUITopic.ts +155 -0
- package/src/infrastructure/IntentsClient.ts +22 -0
- package/src/infrastructure/MessageRouterChannelFactory.ts +182 -0
- package/src/infrastructure/MessageRouterIntentsClient.ts +125 -0
- package/src/infrastructure/MessageRouterMetadataClient.ts +75 -0
- package/src/infrastructure/MessageRouterOpenClient.ts +106 -0
- package/src/infrastructure/MetadataClient.ts +19 -0
- package/src/infrastructure/OpenAppIdentifier.ts +18 -0
- package/src/infrastructure/OpenClient.ts +18 -0
- package/src/infrastructure/PrivateChannelContextListenerEventListener.ts +45 -0
- package/src/infrastructure/PrivateChannelDisconnectEventListener.ts +45 -0
- package/src/infrastructure/messages/Fdc3AddContextListenerRequest.ts +22 -0
- package/src/infrastructure/messages/Fdc3AddContextListenerResponse.ts +17 -0
- package/src/infrastructure/messages/Fdc3CreateAppChannelRequest.ts +17 -0
- package/src/infrastructure/messages/Fdc3CreateAppChannelResponse.ts +17 -0
- package/src/infrastructure/messages/Fdc3CreatePrivateChannelRequest.ts +16 -0
- package/src/infrastructure/messages/Fdc3CreatePrivateChannelResponse.ts +17 -0
- package/src/infrastructure/messages/Fdc3FindChannelRequest.ts +24 -0
- package/src/infrastructure/messages/Fdc3FindChannelResponse.ts +17 -0
- package/src/infrastructure/messages/Fdc3FindInstancesRequest.ts +17 -0
- package/src/infrastructure/messages/Fdc3FindInstancesResponse.ts +18 -0
- package/src/infrastructure/messages/Fdc3FindIntentRequest.ts +24 -0
- package/src/infrastructure/messages/Fdc3FindIntentResponse.ts +19 -0
- package/src/infrastructure/messages/Fdc3FindIntentsByContextRequest.ts +23 -0
- package/src/infrastructure/messages/Fdc3FindIntentsByContextResponse.ts +19 -0
- package/src/infrastructure/messages/Fdc3GetAppMetadataRequest.ts +17 -0
- package/src/infrastructure/messages/Fdc3GetAppMetadataResponse.ts +18 -0
- package/src/infrastructure/messages/Fdc3GetCurrentContextRequest.ts +18 -0
- package/src/infrastructure/messages/Fdc3GetInfoRequest.ts +17 -0
- package/src/infrastructure/messages/Fdc3GetInfoResponse.ts +18 -0
- package/src/infrastructure/messages/Fdc3GetIntentResultRequest.ts +23 -0
- package/src/infrastructure/messages/Fdc3GetIntentResultResponse.ts +23 -0
- package/src/infrastructure/messages/Fdc3GetOpenedAppContextRequest.ts +15 -0
- package/src/infrastructure/messages/Fdc3GetOpenedAppContextResponse.ts +18 -0
- package/src/infrastructure/messages/Fdc3GetUserChannelsRequest.ts +15 -0
- package/src/infrastructure/messages/Fdc3GetUserChannelsResponse.ts +18 -0
- package/src/infrastructure/messages/Fdc3IntentListenerRequest.ts +22 -0
- package/src/infrastructure/messages/Fdc3IntentListenerResponse.ts +17 -0
- package/src/infrastructure/messages/Fdc3JoinUserChannelRequest.ts +15 -0
- package/src/infrastructure/messages/Fdc3JoinUserChannelResponse.ts +20 -0
- package/src/infrastructure/messages/Fdc3OpenRequest.ts +21 -0
- package/src/infrastructure/messages/Fdc3OpenResponse.ts +18 -0
- package/src/infrastructure/messages/Fdc3PrivateChannelInternalEvent.ts +26 -0
- package/src/infrastructure/messages/Fdc3RaiseIntentForContextRequest.ts +20 -0
- package/src/infrastructure/messages/Fdc3RaiseIntentRequest.ts +24 -0
- package/src/infrastructure/messages/Fdc3RaiseIntentResolutionRequest.ts +20 -0
- package/src/infrastructure/messages/Fdc3RaiseIntentResponse.ts +21 -0
- package/src/infrastructure/messages/Fdc3RemoveContextListenerRequest.ts +19 -0
- package/src/infrastructure/messages/Fdc3RemoveContextListenerResponse.ts +17 -0
- package/src/infrastructure/messages/Fdc3StoreIntentResultRequest.ts +29 -0
- package/src/infrastructure/messages/Fdc3StoreIntentResultResponse.ts +17 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Morgan Stanley makes this available to you under the Apache License,
|
|
3
|
+
* Version 2.0 (the "License"). You may obtain a copy of the License at
|
|
4
|
+
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
5
|
+
* See the NOTICE file distributed with this work for additional information
|
|
6
|
+
* regarding copyright ownership. Unless required by applicable law or agreed
|
|
7
|
+
* to in writing, software distributed under the License is distributed on an
|
|
8
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
9
|
+
* or implied. See the License for the specific language governing permissions
|
|
10
|
+
* and limitations under the License.
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { jest } from '@jest/globals';
|
|
15
|
+
import { ComposeUIDesktopAgent } from './ComposeUIDesktopAgent';
|
|
16
|
+
import { ComposeUITopic } from './infrastructure/ComposeUITopic';
|
|
17
|
+
import { AppIdentifier, Channel, ChannelError, Context, IntentHandler, Listener, PrivateChannel } from '@finos/fdc3';
|
|
18
|
+
import { ComposeUIErrors } from './infrastructure/ComposeUIErrors';
|
|
19
|
+
import { Fdc3FindIntentsByContextResponse } from './infrastructure/messages/Fdc3FindIntentsByContextResponse';
|
|
20
|
+
import { Fdc3RaiseIntentResponse } from './infrastructure/messages/Fdc3RaiseIntentResponse';
|
|
21
|
+
import { ComposeUIIntentListener } from './infrastructure/ComposeUIIntentListener';
|
|
22
|
+
import { ChannelType } from './infrastructure/ChannelType';
|
|
23
|
+
|
|
24
|
+
describe("Tests for ComposeUIDesktopAgent's intent handling", () => {
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
window.composeui = {
|
|
28
|
+
fdc3: {
|
|
29
|
+
config: {
|
|
30
|
+
appId: "testAppId",
|
|
31
|
+
instanceId: "testInstanceId"
|
|
32
|
+
},
|
|
33
|
+
channelId : "test",
|
|
34
|
+
openAppIdentifier: {
|
|
35
|
+
openedAppContextId: "test"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('findIntent will throw error as no answer was provided by the DesktopAgent backend', async () => {
|
|
42
|
+
const messageRouterClientMock = {
|
|
43
|
+
clientId: "dummy",
|
|
44
|
+
subscribe: jest.fn(() => {
|
|
45
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
46
|
+
}),
|
|
47
|
+
|
|
48
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
49
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
50
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
51
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
52
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
53
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
54
|
+
invoke: jest.fn(() => { return Promise.resolve(undefined) })
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
58
|
+
await expect(testDesktopAgent.findIntent("testIntent"))
|
|
59
|
+
.rejects
|
|
60
|
+
.toThrow(ComposeUIErrors.NoAnswerWasProvided);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('findIntent will throw error as it got error from the DesktopAgent backend', async () => {
|
|
64
|
+
const fdc3IntentResponse = {
|
|
65
|
+
appIntent: [],
|
|
66
|
+
error: "Error happens..."
|
|
67
|
+
};
|
|
68
|
+
const messageRouterClientMock = {
|
|
69
|
+
clientId: "dummy",
|
|
70
|
+
subscribe: jest.fn(() => {
|
|
71
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
72
|
+
}),
|
|
73
|
+
|
|
74
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
75
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
76
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
77
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
78
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
79
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
80
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(fdc3IntentResponse)}`) })
|
|
81
|
+
};
|
|
82
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
83
|
+
await expect(testDesktopAgent.findIntent("testIntent"))
|
|
84
|
+
.rejects
|
|
85
|
+
.toThrow("Error happens...");
|
|
86
|
+
|
|
87
|
+
expect(messageRouterClientMock.invoke).toHaveBeenCalledWith(ComposeUITopic.findIntent(), JSON.stringify({ fdc3InstanceId: window?.composeui?.fdc3.config?.instanceId, intent: "testIntent" }));
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('findIntent will return AppIntent', async () => {
|
|
91
|
+
const messageRouterClientMock = {
|
|
92
|
+
clientId: "dummy",
|
|
93
|
+
subscribe: jest.fn(() => {
|
|
94
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
95
|
+
}),
|
|
96
|
+
|
|
97
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
98
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
99
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
100
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
101
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
102
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
103
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify({ appIntent: { itent: "dummyIntent", apps: [{ appId: "appId1" }, { appId: "appdId2" }] } })}`) })
|
|
104
|
+
};
|
|
105
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
106
|
+
var resultAppIntent = await testDesktopAgent.findIntent("dummyIntent");
|
|
107
|
+
expect(messageRouterClientMock.invoke).toHaveBeenCalledWith(ComposeUITopic.findIntent(), JSON.stringify({ fdc3InstanceId: window?.composeui?.fdc3.config?.instanceId, intent: "dummyIntent" }));
|
|
108
|
+
expect(resultAppIntent).toMatchObject({ itent: "dummyIntent", apps: [{ appId: "appId1" }, { appId: "appdId2" }] });
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('findIntentsByContext throws error no response came from the DesktopAgent service, undefined message', async () => {
|
|
112
|
+
const messageRouterClientMock = {
|
|
113
|
+
clientId: "dummy",
|
|
114
|
+
subscribe: jest.fn(() => {
|
|
115
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
116
|
+
}),
|
|
117
|
+
|
|
118
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
119
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
120
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
121
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
122
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
123
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
124
|
+
invoke: jest.fn(() => { return Promise.resolve(undefined) })
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
128
|
+
await expect(testDesktopAgent.findIntentsByContext({ type: "fdc3.Instrument" }))
|
|
129
|
+
.rejects
|
|
130
|
+
.toThrow(ComposeUIErrors.NoAnswerWasProvided);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('findIntentsByContext throws error as it got error message from the DesktopAgent service', async () => {
|
|
134
|
+
const fdc3IntentResponse: Fdc3FindIntentsByContextResponse = {
|
|
135
|
+
appIntents: [],
|
|
136
|
+
error: "Error happens..."
|
|
137
|
+
};
|
|
138
|
+
const messageRouterClientMock = {
|
|
139
|
+
clientId: "dummy",
|
|
140
|
+
subscribe: jest.fn(() => {
|
|
141
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
142
|
+
}),
|
|
143
|
+
|
|
144
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
145
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
146
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
147
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
148
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
149
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
150
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(fdc3IntentResponse)}`) })
|
|
151
|
+
};
|
|
152
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
153
|
+
await expect(testDesktopAgent.findIntentsByContext({ type: "testType" }))
|
|
154
|
+
.rejects
|
|
155
|
+
.toThrow(fdc3IntentResponse.error);
|
|
156
|
+
|
|
157
|
+
expect(messageRouterClientMock.invoke).toHaveBeenCalledWith(ComposeUITopic.findIntentsByContext(), JSON.stringify({ fdc3InstanceId: window.composeui.fdc3.config?.instanceId, context: { type: "testType" } }));
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('findIntentsByContext resolves and calls the invoke method of the messageRouterClient', async () => {
|
|
161
|
+
const request = {
|
|
162
|
+
fdc3InstanceId: window?.composeui?.fdc3.config?.instanceId,
|
|
163
|
+
context: {
|
|
164
|
+
type: 'fdc3.Instrument'
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const response: Fdc3FindIntentsByContextResponse = {
|
|
169
|
+
appIntents: [
|
|
170
|
+
{
|
|
171
|
+
intent: { name: 'fdc3.Instrument', displayName: 'fdc3.Instrument' },
|
|
172
|
+
apps: [
|
|
173
|
+
{ appId: "appId1" },
|
|
174
|
+
{ appId: "appId2" }
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
intent: { name: 'fdc3.Instrument2', displayName: 'fdc3.Instrument2' },
|
|
179
|
+
apps: [
|
|
180
|
+
{ appId: "appId3" },
|
|
181
|
+
{ appId: "appId4" }
|
|
182
|
+
]
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const messageRouterClientMock = {
|
|
188
|
+
clientId: "dummy",
|
|
189
|
+
subscribe: jest.fn(() => {
|
|
190
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
191
|
+
}),
|
|
192
|
+
|
|
193
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
194
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
195
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
196
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
197
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
198
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
199
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(response)}`) })
|
|
200
|
+
};
|
|
201
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
202
|
+
var resultAppIntent = await testDesktopAgent.findIntentsByContext({ type: "fdc3.Instrument" });
|
|
203
|
+
|
|
204
|
+
expect(messageRouterClientMock.invoke).toHaveBeenCalledWith(ComposeUITopic.findIntentsByContext(), JSON.stringify(request));
|
|
205
|
+
expect(resultAppIntent).toMatchObject(response.appIntents!);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('raiseIntent will throw exception, due no answer came from the DesktopAgent service', async () => {
|
|
209
|
+
const messageRouterClientMock = {
|
|
210
|
+
clientId: "dummy",
|
|
211
|
+
subscribe: jest.fn(() => {
|
|
212
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
213
|
+
}),
|
|
214
|
+
|
|
215
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
216
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
217
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
218
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
219
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
220
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
221
|
+
invoke: jest.fn(() => { return Promise.resolve(undefined) })
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
225
|
+
await expect(testDesktopAgent.raiseIntent("testIntent", { type: "fdc3.Instrument" }))
|
|
226
|
+
.rejects
|
|
227
|
+
.toThrow(ComposeUIErrors.NoAnswerWasProvided);
|
|
228
|
+
|
|
229
|
+
expect(messageRouterClientMock.invoke).toHaveBeenCalledTimes(1);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('raiseIntent will throw exception, due error was defined by the DesktopAgent service', async () => {
|
|
233
|
+
const fdc3IntentResponse: Fdc3RaiseIntentResponse = {
|
|
234
|
+
messageId: "1",
|
|
235
|
+
error: "Error happens..."
|
|
236
|
+
};
|
|
237
|
+
const messageRouterClientMock = {
|
|
238
|
+
clientId: "dummy",
|
|
239
|
+
subscribe: jest.fn(() => {
|
|
240
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
241
|
+
}),
|
|
242
|
+
|
|
243
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
244
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
245
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
246
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
247
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
248
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
249
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(fdc3IntentResponse)}`) })
|
|
250
|
+
};
|
|
251
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
252
|
+
await expect(testDesktopAgent.raiseIntent("testIntent", { type: "testType" }))
|
|
253
|
+
.rejects
|
|
254
|
+
.toThrow(fdc3IntentResponse.error);
|
|
255
|
+
|
|
256
|
+
expect(messageRouterClientMock.invoke).toHaveBeenCalledTimes(1);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('raiseIntent will resolve the first item, due the DesktopAgent service sent just one application', async () => {
|
|
260
|
+
const fdc3IntentResponse: Fdc3RaiseIntentResponse = {
|
|
261
|
+
messageId: "1",
|
|
262
|
+
intent: "test",
|
|
263
|
+
appMetadata: { appId: "test1" }
|
|
264
|
+
};
|
|
265
|
+
const messageRouterClientMock = {
|
|
266
|
+
clientId: "dummy",
|
|
267
|
+
subscribe: jest.fn(() => {
|
|
268
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
269
|
+
}),
|
|
270
|
+
|
|
271
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
272
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
273
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
274
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
275
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
276
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
277
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(fdc3IntentResponse)}`) })
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
const channelFactoryMock = {
|
|
282
|
+
getChannel: jest.fn((channelId: string, channelType: ChannelType) => { return <Promise<Channel>>Promise.reject("not implemented") }),
|
|
283
|
+
createPrivateChannel: jest.fn(() => { return <Promise<PrivateChannel>>Promise.reject("not implemented") }),
|
|
284
|
+
getIntentListener: jest.fn((intent: string, handler: IntentHandler) => { return <Promise<Listener>>Promise.reject("not implemented") })
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
288
|
+
var result = await testDesktopAgent.raiseIntent("test", { type: "test" });
|
|
289
|
+
expect(messageRouterClientMock.invoke).toHaveBeenCalledTimes(1);
|
|
290
|
+
expect(result.intent).toMatch("test");
|
|
291
|
+
expect(result.source).toMatchObject(<AppIdentifier>fdc3IntentResponse.appMetadata)
|
|
292
|
+
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('addIntentListener will resolve an intentListener', async () => {
|
|
296
|
+
const messageRouterClientMock = {
|
|
297
|
+
clientId: "dummy",
|
|
298
|
+
subscribe: jest.fn(() => {
|
|
299
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
300
|
+
}),
|
|
301
|
+
|
|
302
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
303
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
304
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
305
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
306
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
307
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
308
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify({ stored: true })}`) })
|
|
309
|
+
};
|
|
310
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
311
|
+
const intentHandler: IntentHandler = (context, metadata) => {
|
|
312
|
+
return;
|
|
313
|
+
};
|
|
314
|
+
const result = await testDesktopAgent.addIntentListener("testIntent", intentHandler);
|
|
315
|
+
|
|
316
|
+
expect(messageRouterClientMock.subscribe).toHaveBeenCalledTimes(1);
|
|
317
|
+
expect(result).toBeInstanceOf(ComposeUIIntentListener);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it('addIntentListener will fail as no answer provided', async () => {
|
|
321
|
+
const messageRouterClientMock = {
|
|
322
|
+
clientId: "dummy",
|
|
323
|
+
subscribe: jest.fn(() => {
|
|
324
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
325
|
+
}),
|
|
326
|
+
|
|
327
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
328
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
329
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
330
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
331
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
332
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
333
|
+
invoke: jest.fn(() => { return Promise.resolve("") })
|
|
334
|
+
};
|
|
335
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
336
|
+
const intentHandler: IntentHandler = (context, metadata) => {
|
|
337
|
+
return;
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
await expect(testDesktopAgent.addIntentListener("testIntent", intentHandler))
|
|
341
|
+
.rejects
|
|
342
|
+
.toThrow(ComposeUIErrors.NoAnswerWasProvided);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
it('addIntentListener will fail as the service not stored', async () => {
|
|
346
|
+
const messageRouterClientMock = {
|
|
347
|
+
clientId: "dummy",
|
|
348
|
+
subscribe: jest.fn(() => {
|
|
349
|
+
return Promise.resolve({ unsubscribe: () => { } });
|
|
350
|
+
}),
|
|
351
|
+
|
|
352
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
353
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
354
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
355
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
356
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
357
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
358
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify({ stored: false, error: undefined })}`) })
|
|
359
|
+
};
|
|
360
|
+
const testDesktopAgent = new ComposeUIDesktopAgent(messageRouterClientMock);
|
|
361
|
+
const intentHandler: IntentHandler = (context, metadata) => {
|
|
362
|
+
return;
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
await expect(testDesktopAgent.addIntentListener("testIntent", intentHandler))
|
|
366
|
+
.rejects
|
|
367
|
+
.toThrow(ComposeUIErrors.SubscribeFailure);
|
|
368
|
+
});
|
|
369
|
+
});
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Morgan Stanley makes this available to you under the Apache License,
|
|
3
|
+
* Version 2.0 (the "License"). You may obtain a copy of the License at
|
|
4
|
+
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
5
|
+
* See the NOTICE file distributed with this work for additional information
|
|
6
|
+
* regarding copyright ownership. Unless required by applicable law or agreed
|
|
7
|
+
* to in writing, software distributed under the License is distributed on an
|
|
8
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
9
|
+
* or implied. See the License for the specific language governing permissions
|
|
10
|
+
* and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { ChannelError } from "@finos/fdc3";
|
|
14
|
+
import { ChannelFactory } from "./infrastructure/ChannelFactory";
|
|
15
|
+
import { MessageRouterChannelFactory } from "./infrastructure/MessageRouterChannelFactory";
|
|
16
|
+
import { Fdc3JoinUserChannelResponse } from "./infrastructure/messages/Fdc3JoinUserChannelResponse";
|
|
17
|
+
import { ComposeUIChannel } from "./infrastructure/ComposeUIChannel";
|
|
18
|
+
import { Fdc3GetUserChannelsResponse } from "./infrastructure/messages/Fdc3GetUserChannelsResponse";
|
|
19
|
+
|
|
20
|
+
describe("", () => {
|
|
21
|
+
let channelFactory: ChannelFactory;
|
|
22
|
+
|
|
23
|
+
it('joinUserChannel returns CreationFailed error as no response received', async() => {
|
|
24
|
+
let messageRouterClient = {
|
|
25
|
+
clientId: "dummyId",
|
|
26
|
+
subscribe: jest.fn(() => { return Promise.resolve({ unsubscribe: () => { } }); }),
|
|
27
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
28
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
29
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
30
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
31
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
32
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
33
|
+
invoke: jest.fn(() => { return Promise.resolve(undefined)})
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
channelFactory = new MessageRouterChannelFactory(messageRouterClient, "dummyId");
|
|
37
|
+
|
|
38
|
+
await expect(channelFactory.joinUserChannel("dummyId"))
|
|
39
|
+
.rejects
|
|
40
|
+
.toThrow(ChannelError.CreationFailed);
|
|
41
|
+
|
|
42
|
+
expect(messageRouterClient.invoke).toHaveBeenCalledTimes(1);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('joinUserChannel returns error as error received in the response', async() => {
|
|
46
|
+
const response: Fdc3JoinUserChannelResponse = {
|
|
47
|
+
error: "testError",
|
|
48
|
+
success: false
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
let messageRouterClient = {
|
|
52
|
+
clientId: "dummyId",
|
|
53
|
+
subscribe: jest.fn(() => { return Promise.resolve({ unsubscribe: () => { } }); }),
|
|
54
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
55
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
56
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
57
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
58
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
59
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
60
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(response)}`)})
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
channelFactory = new MessageRouterChannelFactory(messageRouterClient, "dummyId");
|
|
64
|
+
|
|
65
|
+
await expect(channelFactory.joinUserChannel("dummyId"))
|
|
66
|
+
.rejects
|
|
67
|
+
.toThrow("testError");
|
|
68
|
+
|
|
69
|
+
expect(messageRouterClient.invoke).toHaveBeenCalledTimes(1);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('joinUserChannel returns error as the success property set to false', async() => {
|
|
73
|
+
const response: Fdc3JoinUserChannelResponse = {
|
|
74
|
+
displayMetadata: {
|
|
75
|
+
name: "test",
|
|
76
|
+
},
|
|
77
|
+
success: false
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
let messageRouterClient = {
|
|
81
|
+
clientId: "dummyId",
|
|
82
|
+
subscribe: jest.fn(() => { return Promise.resolve({ unsubscribe: () => { } }); }),
|
|
83
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
84
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
85
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
86
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
87
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
88
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
89
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(response)}`)})
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
channelFactory = new MessageRouterChannelFactory(messageRouterClient, "dummyId");
|
|
93
|
+
|
|
94
|
+
await expect(channelFactory.joinUserChannel("dummyId"))
|
|
95
|
+
.rejects
|
|
96
|
+
.toThrow(ChannelError.CreationFailed);
|
|
97
|
+
|
|
98
|
+
expect(messageRouterClient.invoke).toHaveBeenCalledTimes(1);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('joinUserChannel returns channel', async() => {
|
|
102
|
+
const response: Fdc3JoinUserChannelResponse = {
|
|
103
|
+
displayMetadata: {
|
|
104
|
+
name: "test",
|
|
105
|
+
},
|
|
106
|
+
success: true
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
let messageRouterClient = {
|
|
110
|
+
clientId: "dummyId",
|
|
111
|
+
subscribe: jest.fn(() => { return Promise.resolve({ unsubscribe: () => { } }); }),
|
|
112
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
113
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
114
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
115
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
116
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
117
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
118
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(response)}`)})
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
channelFactory = new MessageRouterChannelFactory(messageRouterClient, "dummyId");
|
|
122
|
+
|
|
123
|
+
const result = await channelFactory.joinUserChannel("dummyId");
|
|
124
|
+
expect(result).toBeInstanceOf(ComposeUIChannel);
|
|
125
|
+
expect(messageRouterClient.invoke).toHaveBeenCalledTimes(1);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('getUserChannels returns NoChannelFound error as no response received', async() => {
|
|
129
|
+
let messageRouterClient = {
|
|
130
|
+
clientId: "dummyId",
|
|
131
|
+
subscribe: jest.fn(() => { return Promise.resolve({ unsubscribe: () => { } }); }),
|
|
132
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
133
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
134
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
135
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
136
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
137
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
138
|
+
invoke: jest.fn(() => { return Promise.resolve(undefined)})
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
channelFactory = new MessageRouterChannelFactory(messageRouterClient, "dummyId");
|
|
142
|
+
|
|
143
|
+
await expect(channelFactory.getUserChannels())
|
|
144
|
+
.rejects
|
|
145
|
+
.toThrow(ChannelError.NoChannelFound);
|
|
146
|
+
|
|
147
|
+
expect(messageRouterClient.invoke).toHaveBeenCalledTimes(1);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('getUserChannels returns error as error response received', async() => {
|
|
151
|
+
const response: Fdc3GetUserChannelsResponse = {
|
|
152
|
+
error: "testError"
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
let messageRouterClient = {
|
|
156
|
+
clientId: "dummyId",
|
|
157
|
+
subscribe: jest.fn(() => { return Promise.resolve({ unsubscribe: () => { } }); }),
|
|
158
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
159
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
160
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
161
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
162
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
163
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
164
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(response)}`)})
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
channelFactory = new MessageRouterChannelFactory(messageRouterClient, "dummyId");
|
|
168
|
+
|
|
169
|
+
await expect(channelFactory.getUserChannels())
|
|
170
|
+
.rejects
|
|
171
|
+
.toThrow("testError");
|
|
172
|
+
|
|
173
|
+
expect(messageRouterClient.invoke).toHaveBeenCalledTimes(1);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('getUserChannels returns channels', async() => {
|
|
177
|
+
const response: Fdc3GetUserChannelsResponse = {
|
|
178
|
+
channels: [{id: "testId", type: "user", displayMetadata: {name: "testDisplayMetadata"}}]
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
let messageRouterClient = {
|
|
182
|
+
clientId: "dummyId",
|
|
183
|
+
subscribe: jest.fn(() => { return Promise.resolve({ unsubscribe: () => { } }); }),
|
|
184
|
+
publish: jest.fn(() => { return Promise.resolve() }),
|
|
185
|
+
connect: jest.fn(() => { return Promise.resolve() }),
|
|
186
|
+
registerEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
187
|
+
unregisterEndpoint: jest.fn(() => { return Promise.resolve() }),
|
|
188
|
+
registerService: jest.fn(() => { return Promise.resolve() }),
|
|
189
|
+
unregisterService: jest.fn(() => { return Promise.resolve() }),
|
|
190
|
+
invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(response)}`)})
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
channelFactory = new MessageRouterChannelFactory(messageRouterClient, "dummyId");
|
|
194
|
+
|
|
195
|
+
const result = await channelFactory.getUserChannels();
|
|
196
|
+
expect(result).toBeDefined();
|
|
197
|
+
expect(result.length).toBe(1);
|
|
198
|
+
expect(result.at(0)).toMatchObject({id: "testId", type: "user", displayMetadata: {name: "testDisplayMetadata"}})
|
|
199
|
+
});
|
|
200
|
+
});
|