Skip to content

Commit 2fa6ba1

Browse files
committed
Test navigation in ClientWidgetApi
1 parent e993d32 commit 2fa6ba1

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

test/ClientWidgetApi-test.ts

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { PostmessageTransport } from '../src/transport/PostmessageTransport';
3232
import {
3333
IDownloadFileActionFromWidgetActionRequest,
3434
IMatrixApiError,
35+
INavigateActionRequest,
3536
IReadEventFromWidgetActionRequest,
3637
ISendEventFromWidgetActionRequest,
3738
ISendToDeviceFromWidgetActionRequest,
@@ -113,6 +114,7 @@ describe('ClientWidgetApi', () => {
113114
document.body.appendChild(iframe);
114115

115116
driver = {
117+
navigate: jest.fn(),
116118
readStateEvents: jest.fn(),
117119
readEventRelations: jest.fn(),
118120
sendEvent: jest.fn(),
@@ -159,6 +161,155 @@ describe('ClientWidgetApi', () => {
159161
expect(clientWidgetApi.hasCapability('m.sticker')).toBe(false);
160162
});
161163

164+
describe('navigate action', () => {
165+
it('navigates', async () => {
166+
driver.navigate.mockResolvedValue(Promise.resolve());
167+
168+
const event: INavigateActionRequest = {
169+
api: WidgetApiDirection.FromWidget,
170+
widgetId: 'test',
171+
requestId: '0',
172+
action: WidgetApiFromWidgetAction.MSC2931Navigate,
173+
data: {
174+
uri: 'https://matrix.to/#/#room:example.net',
175+
},
176+
};
177+
178+
await loadIframe(['org.matrix.msc2931.navigate']);
179+
180+
emitEvent(new CustomEvent('', { detail: event }));
181+
182+
await waitFor(() => {
183+
expect(transport.reply).toHaveBeenCalledWith(event, {});
184+
});
185+
186+
expect(driver.navigate).toHaveBeenCalledWith(
187+
event.data.uri,
188+
);
189+
});
190+
191+
it('fails to navigate', async () => {
192+
const event: INavigateActionRequest = {
193+
api: WidgetApiDirection.FromWidget,
194+
widgetId: 'test',
195+
requestId: '0',
196+
action: WidgetApiFromWidgetAction.MSC2931Navigate,
197+
data: {
198+
uri: 'https://matrix.to/#/#room:example.net',
199+
},
200+
};
201+
202+
await loadIframe([]); // Without the required capability
203+
204+
emitEvent(new CustomEvent('', { detail: event }));
205+
206+
await waitFor(() => {
207+
expect(transport.reply).toBeCalledWith(event, {
208+
error: { message: 'Missing capability' },
209+
});
210+
});
211+
212+
expect(driver.navigate).not.toBeCalled();
213+
});
214+
215+
it('fails to navigate to an unsupported URI', async () => {
216+
const event: INavigateActionRequest = {
217+
api: WidgetApiDirection.FromWidget,
218+
widgetId: 'test',
219+
requestId: '0',
220+
action: WidgetApiFromWidgetAction.MSC2931Navigate,
221+
data: {
222+
uri: 'https://example.net',
223+
},
224+
};
225+
226+
await loadIframe(['org.matrix.msc2931.navigate']);
227+
228+
emitEvent(new CustomEvent('', { detail: event }));
229+
230+
await waitFor(() => {
231+
expect(transport.reply).toBeCalledWith(event, {
232+
error: { message: 'Invalid matrix.to URI' },
233+
});
234+
});
235+
236+
expect(driver.navigate).not.toBeCalled();
237+
});
238+
239+
it('should reject requests when the driver throws an exception', async () => {
240+
driver.navigate.mockRejectedValue(
241+
new Error("M_UNKNOWN: Unknown error"),
242+
);
243+
244+
const event: INavigateActionRequest = {
245+
api: WidgetApiDirection.FromWidget,
246+
widgetId: 'test',
247+
requestId: '0',
248+
action: WidgetApiFromWidgetAction.MSC2931Navigate,
249+
data: {
250+
uri: 'https://matrix.to/#/#room:example.net',
251+
},
252+
};
253+
254+
await loadIframe(['org.matrix.msc2931.navigate']);
255+
256+
emitEvent(new CustomEvent('', { detail: event }));
257+
258+
await waitFor(() => {
259+
expect(transport.reply).toBeCalledWith(event, {
260+
error: { message: 'Error handling navigation' },
261+
});
262+
});
263+
});
264+
265+
it('should reject with Matrix API error response thrown by driver', async () => {
266+
driver.processError.mockImplementation(processCustomMatrixError);
267+
268+
driver.navigate.mockRejectedValue(
269+
new CustomMatrixError(
270+
'failed to navigate',
271+
400,
272+
'M_UNKNOWN',
273+
{
274+
reason: 'Unknown error',
275+
},
276+
),
277+
);
278+
279+
const event: INavigateActionRequest = {
280+
api: WidgetApiDirection.FromWidget,
281+
widgetId: 'test',
282+
requestId: '0',
283+
action: WidgetApiFromWidgetAction.MSC2931Navigate,
284+
data: {
285+
uri: 'https://matrix.to/#/#room:example.net',
286+
},
287+
};
288+
289+
await loadIframe(['org.matrix.msc2931.navigate']);
290+
291+
emitEvent(new CustomEvent('', { detail: event }));
292+
293+
await waitFor(() => {
294+
expect(transport.reply).toBeCalledWith(event, {
295+
error: {
296+
message: 'Error handling navigation',
297+
matrix_api_error: {
298+
http_status: 400,
299+
http_headers: {},
300+
url: '',
301+
response: {
302+
errcode: 'M_UNKNOWN',
303+
error: 'failed to navigate',
304+
reason: 'Unknown error',
305+
},
306+
} satisfies IMatrixApiError,
307+
},
308+
});
309+
});
310+
});
311+
});
312+
162313
describe('send_event action', () => {
163314
it('sends message events', async () => {
164315
const roomId = '!room:example.org';

0 commit comments

Comments
 (0)