Skip to content

Commit

Permalink
Test sendToDevice in ClientWidgetApi
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewFerr committed Nov 5, 2024
1 parent 7a5a2bc commit e993d32
Showing 1 changed file with 246 additions and 0 deletions.
246 changes: 246 additions & 0 deletions test/ClientWidgetApi-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
IMatrixApiError,
IReadEventFromWidgetActionRequest,
ISendEventFromWidgetActionRequest,
ISendToDeviceFromWidgetActionRequest,
IUpdateDelayedEventFromWidgetActionRequest,
IUploadFileActionFromWidgetActionRequest,
IWidgetApiErrorResponseDataDetails,
Expand Down Expand Up @@ -117,6 +118,7 @@ describe('ClientWidgetApi', () => {
sendEvent: jest.fn(),
sendDelayedEvent: jest.fn(),
updateDelayedEvent: jest.fn(),
sendToDevice: jest.fn(),
validateCapabilities: jest.fn(),
searchUserDirectory: jest.fn(),
getMediaConfig: jest.fn(),
Expand Down Expand Up @@ -721,6 +723,250 @@ describe('ClientWidgetApi', () => {
});
});

describe('send_to_device action', () => {
it('sends unencrypted to-device events', async () => {
const event: ISendToDeviceFromWidgetActionRequest = {
api: WidgetApiDirection.FromWidget,
widgetId: 'test',
requestId: '0',
action: WidgetApiFromWidgetAction.SendToDevice,
data: {
type: 'net.example.test',
encrypted: false,
messages: {
'@foo:bar.com': {
'DEVICEID': {
'example_content_key': 'value',
},
},
},
},
};

await loadIframe([`org.matrix.msc3819.send.to_device:${event.data.type}`]);

emitEvent(new CustomEvent('', { detail: event }));

await waitFor(() => {
expect(transport.reply).toHaveBeenCalledWith(event, {});
});

expect(driver.sendToDevice).toHaveBeenCalledWith(
event.data.type,
event.data.encrypted,
event.data.messages,
);
});

it('fails to send to-device events without event type', async () => {
const event: IWidgetApiRequest = {
api: WidgetApiDirection.FromWidget,
widgetId: 'test',
requestId: '0',
action: WidgetApiFromWidgetAction.SendToDevice,
data: {
encrypted: false,
messages: {
'@foo:bar.com': {
'DEVICEID': {
'example_content_key': 'value',
},
},
},
},
};

await loadIframe([`org.matrix.msc3819.send.to_device:${event.data.type}`]);

emitEvent(new CustomEvent('', { detail: event }));

await waitFor(() => {
expect(transport.reply).toBeCalledWith(event, {
error: { message: 'Invalid request - missing event type' },
});
});

expect(driver.sendToDevice).not.toBeCalled();
});

it('fails to send to-device events without event contents', async () => {
const event: IWidgetApiRequest = {
api: WidgetApiDirection.FromWidget,
widgetId: 'test',
requestId: '0',
action: WidgetApiFromWidgetAction.SendToDevice,
data: {
type: 'net.example.test',
encrypted: false,
},
};

await loadIframe([`org.matrix.msc3819.send.to_device:${event.data.type}`]);

emitEvent(new CustomEvent('', { detail: event }));

await waitFor(() => {
expect(transport.reply).toBeCalledWith(event, {
error: { message: 'Invalid request - missing event contents' },
});
});

expect(driver.sendToDevice).not.toBeCalled();
});

it('fails to send to-device events without encryption flag', async () => {
const event: IWidgetApiRequest = {
api: WidgetApiDirection.FromWidget,
widgetId: 'test',
requestId: '0',
action: WidgetApiFromWidgetAction.SendToDevice,
data: {
type: 'net.example.test',
messages: {
'@foo:bar.com': {
'DEVICEID': {
'example_content_key': 'value',
},
},
},
},
};

await loadIframe([`org.matrix.msc3819.send.to_device:${event.data.type}`]);

emitEvent(new CustomEvent('', { detail: event }));

await waitFor(() => {
expect(transport.reply).toBeCalledWith(event, {
error: { message: 'Invalid request - missing encryption flag' },
});
});

expect(driver.sendToDevice).not.toBeCalled();
});

it('fails to send to-device events with any event type', async () => {
const event: ISendToDeviceFromWidgetActionRequest = {
api: WidgetApiDirection.FromWidget,
widgetId: 'test',
requestId: '0',
action: WidgetApiFromWidgetAction.SendToDevice,
data: {
type: 'net.example.test',
encrypted: false,
messages: {
'@foo:bar.com': {
'DEVICEID': {
'example_content_key': 'value',
},
},
},
},
};

await loadIframe([`org.matrix.msc3819.send.to_device:${event.data.type}_different`]);

emitEvent(new CustomEvent('', { detail: event }));

await waitFor(() => {
expect(transport.reply).toBeCalledWith(event, {
error: { message: 'Cannot send to-device events of this type' },
});
});

expect(driver.sendToDevice).not.toBeCalled();
});

it('should reject requests when the driver throws an exception', async () => {
driver.sendToDevice.mockRejectedValue(
new Error("M_FORBIDDEN: You don't have permission to send to-device events"),
);

const event: ISendToDeviceFromWidgetActionRequest = {
api: WidgetApiDirection.FromWidget,
widgetId: 'test',
requestId: '0',
action: WidgetApiFromWidgetAction.SendToDevice,
data: {
type: 'net.example.test',
encrypted: false,
messages: {
'@foo:bar.com': {
'DEVICEID': {
'example_content_key': 'value',
},
},
},
},
};

await loadIframe([`org.matrix.msc3819.send.to_device:${event.data.type}`]);

emitEvent(new CustomEvent('', { detail: event }));

await waitFor(() => {
expect(transport.reply).toBeCalledWith(event, {
error: { message: 'Error sending event' },
});
});
});

it('should reject with Matrix API error response thrown by driver', async () => {
driver.processError.mockImplementation(processCustomMatrixError);

driver.sendToDevice.mockRejectedValue(
new CustomMatrixError(
'failed to send event',
400,
'M_FORBIDDEN',
{
reason: "You don't have permission to send to-device events",
},
),
);

const event: ISendToDeviceFromWidgetActionRequest = {
api: WidgetApiDirection.FromWidget,
widgetId: 'test',
requestId: '0',
action: WidgetApiFromWidgetAction.SendToDevice,
data: {
type: 'net.example.test',
encrypted: false,
messages: {
'@foo:bar.com': {
'DEVICEID': {
'example_content_key': 'value',
},
},
},
},
};

await loadIframe([`org.matrix.msc3819.send.to_device:${event.data.type}`]);

emitEvent(new CustomEvent('', { detail: event }));

await waitFor(() => {
expect(transport.reply).toBeCalledWith(event, {
error: {
message: 'Error sending event',
matrix_api_error: {
http_status: 400,
http_headers: {},
url: '',
response: {
errcode: 'M_FORBIDDEN',
error: 'failed to send event',
reason: "You don't have permission to send to-device events",
},
} satisfies IMatrixApiError,
},
});
});
});
});

describe('org.matrix.msc2876.read_events action', () => {
it('reads state events with any state key', async () => {
driver.readStateEvents.mockResolvedValue([
Expand Down

0 comments on commit e993d32

Please sign in to comment.