mirror of
https://github.com/matrix-org/matrix-hookshot.git
synced 2025-03-10 21:19:13 +00:00
Add some tests for GenericHook
This commit is contained in:
parent
96192341ad
commit
e8525e7431
@ -25,7 +25,7 @@
|
||||
"start:app": "node --require source-map-support/register lib/App/BridgeApp.js",
|
||||
"start:webhooks": "node --require source-map-support/register lib/App/GithubWebhookApp.js",
|
||||
"start:matrixsender": "node --require source-map-support/register lib/App/MatrixSenderApp.js",
|
||||
"test": "mocha -r ts-node/register tests/*.ts tests/**/*.ts",
|
||||
"test": "mocha -r ts-node/register tests/init.ts tests/*.ts tests/**/*.ts",
|
||||
"lint": "yarn run lint:js && yarn run lint:rs",
|
||||
"lint:js": "eslint -c .eslintrc.js src/**/*.ts",
|
||||
"lint:rs": "cargo fmt --all -- --check",
|
||||
|
@ -198,6 +198,7 @@ export class GenericHookConnection extends BaseConnection implements IConnection
|
||||
eval: false,
|
||||
timeout: TRANSFORMATION_TIMEOUT_MS,
|
||||
});
|
||||
vm.setGlobal('data', data);
|
||||
vm.run(this.transformationFunction);
|
||||
content = vm.getGlobal('result');
|
||||
if (typeof content === "string") {
|
||||
@ -219,7 +220,7 @@ export class GenericHookConnection extends BaseConnection implements IConnection
|
||||
body: content,
|
||||
formatted_body: md.renderInline(content),
|
||||
format: "org.matrix.custom.html",
|
||||
"uk.half-shot.webhook_data": data,
|
||||
"uk.half-shot.hookshot.webhook_data": data,
|
||||
}, 'm.room.message', sender);
|
||||
|
||||
}
|
||||
|
@ -84,4 +84,4 @@ export class MessageSenderClient {
|
||||
},
|
||||
})).eventId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
140
tests/connections/GenericHookTest.ts
Normal file
140
tests/connections/GenericHookTest.ts
Normal file
@ -0,0 +1,140 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { expect } from "chai";
|
||||
import { BridgeGenericWebhooksConfig } from "../../src/Config/Config";
|
||||
import { GenericHookConnection, GenericHookConnectionState } from "../../src/Connections/GenericHook";
|
||||
import { MessageSenderClient } from "../../src/MatrixSender";
|
||||
import { createMessageQueue, MessageQueue } from "../../src/MessageQueue";
|
||||
import { AppserviceMock } from "../utils/AppserviceMock";
|
||||
|
||||
const ROOM_ID = "!foo:bar";
|
||||
|
||||
const TFFunction = "result = `The answer to '${data.question}' is ${data.answer}`;";
|
||||
|
||||
function createGenericHook(state: GenericHookConnectionState = {
|
||||
name: "some-name"
|
||||
}, config: BridgeGenericWebhooksConfig = { enabled: true, urlPrefix: "https://example.com/webhookurl"}): [GenericHookConnection, MessageQueue] {
|
||||
const mq = createMessageQueue({
|
||||
queue: {
|
||||
monolithic: true,
|
||||
},
|
||||
} as any);
|
||||
mq.subscribe('*');
|
||||
const messageClient = new MessageSenderClient(mq);
|
||||
const connection = new GenericHookConnection(ROOM_ID, state, "foobar", "foobar", messageClient, config, AppserviceMock.create())
|
||||
return [connection, mq];
|
||||
}
|
||||
|
||||
function handleMessage(mq: MessageQueue) {
|
||||
return new Promise(r => mq.on('matrix.message', (msg) => {
|
||||
mq.push({
|
||||
eventName: 'response.matrix.message',
|
||||
messageId: msg.messageId,
|
||||
sender: 'TestSender',
|
||||
data: { 'eventId': '$foo:bar' },
|
||||
});
|
||||
r(msg.data);
|
||||
}));
|
||||
}
|
||||
|
||||
describe("GenericHookConnection", () => {
|
||||
it("will handle a simple hook event", async () => {
|
||||
const webhookData = {simple: "data"};
|
||||
const [connection, mq] = createGenericHook();
|
||||
const messagePromise = handleMessage(mq);
|
||||
await connection.onGenericHook(webhookData);
|
||||
expect(await messagePromise).to.deep.equal({
|
||||
roomId: ROOM_ID,
|
||||
sender: connection.getUserId(),
|
||||
content: {
|
||||
body: "Received webhook data:\n\n```{\n \"simple\": \"data\"\n}```",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: "Received webhook data:\n\n<code>{ "simple": "data" }</code>",
|
||||
msgtype: "m.notice",
|
||||
"uk.half-shot.hookshot.webhook_data": webhookData,
|
||||
},
|
||||
type: 'm.room.message',
|
||||
});
|
||||
});
|
||||
it("will handle a hook event containing text", async () => {
|
||||
const webhookData = {text: "simple-message"};
|
||||
const [connection, mq] = createGenericHook();
|
||||
const messagePromise = handleMessage(mq);
|
||||
await connection.onGenericHook(webhookData);
|
||||
expect(await messagePromise).to.deep.equal({
|
||||
roomId: ROOM_ID,
|
||||
sender: connection.getUserId(),
|
||||
content: {
|
||||
body: "simple-message",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: "simple-message",
|
||||
msgtype: "m.notice",
|
||||
"uk.half-shot.hookshot.webhook_data": webhookData,
|
||||
},
|
||||
type: 'm.room.message',
|
||||
});
|
||||
});
|
||||
it("will handle a hook event containing text", async () => {
|
||||
const webhookData = {username: "Bobs-integration", type: 42};
|
||||
const [connection, mq] = createGenericHook();
|
||||
const messagePromise = handleMessage(mq);
|
||||
await connection.onGenericHook(webhookData);
|
||||
expect(await messagePromise).to.deep.equal({
|
||||
roomId: ROOM_ID,
|
||||
sender: connection.getUserId(),
|
||||
content: {
|
||||
body: "**Bobs-integration**: Received webhook data:\n\n```{\n \"username\": \"Bobs-integration\",\n \"type\": 42\n}```",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: "<strong>Bobs-integration</strong>: Received webhook data:\n\n<code>{ "username": "Bobs-integration", "type": 42 }</code>",
|
||||
msgtype: "m.notice",
|
||||
"uk.half-shot.hookshot.webhook_data": webhookData,
|
||||
},
|
||||
type: 'm.room.message',
|
||||
});
|
||||
});
|
||||
it("will handle a hook event with a transformation function", async () => {
|
||||
const webhookData = {question: 'What is the meaning of life?', answer: 42};
|
||||
const [connection, mq] = createGenericHook({name: 'test', transformationFunction: TFFunction}, {
|
||||
enabled: true,
|
||||
urlPrefix: "https://example.com/webhookurl",
|
||||
allowJsTransformationFunctions: true,
|
||||
}
|
||||
);
|
||||
const messagePromise = handleMessage(mq);
|
||||
await connection.onGenericHook(webhookData);
|
||||
expect(await messagePromise).to.deep.equal({
|
||||
roomId: ROOM_ID,
|
||||
sender: connection.getUserId(),
|
||||
content: {
|
||||
body: "Received webhook: The answer to 'What is the meaning of life?' is 42",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: "Received webhook: The answer to 'What is the meaning of life?' is 42",
|
||||
msgtype: "m.notice",
|
||||
"uk.half-shot.hookshot.webhook_data": webhookData,
|
||||
},
|
||||
type: 'm.room.message',
|
||||
});
|
||||
});
|
||||
it("will fail to handle a webhook with an invalid script", async () => {
|
||||
const webhookData = {question: 'What is the meaning of life?', answer: 42};
|
||||
const [connection, mq] = createGenericHook({name: 'test', transformationFunction: "bibble bobble"}, {
|
||||
enabled: true,
|
||||
urlPrefix: "https://example.com/webhookurl",
|
||||
allowJsTransformationFunctions: true,
|
||||
}
|
||||
);
|
||||
const messagePromise = handleMessage(mq);
|
||||
await connection.onGenericHook(webhookData);
|
||||
expect(await messagePromise).to.deep.equal({
|
||||
roomId: ROOM_ID,
|
||||
sender: connection.getUserId(),
|
||||
content: {
|
||||
body: "Webhook received but failed to process via transformation function",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: "Webhook received but failed to process via transformation function",
|
||||
msgtype: "m.notice",
|
||||
"uk.half-shot.hookshot.webhook_data": webhookData,
|
||||
},
|
||||
type: 'm.room.message',
|
||||
});
|
||||
});
|
||||
})
|
2
tests/init.ts
Normal file
2
tests/init.ts
Normal file
@ -0,0 +1,2 @@
|
||||
import LogWrapper from "../src/LogWrapper";
|
||||
LogWrapper.configureLogging("info");
|
16
tests/utils/AppserviceMock.ts
Normal file
16
tests/utils/AppserviceMock.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { IntentMock } from "./IntentMock";
|
||||
|
||||
export class AppserviceMock {
|
||||
static create(){
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return new this() as any;
|
||||
}
|
||||
|
||||
get botUserId() {
|
||||
return `@bot:example.com`;
|
||||
}
|
||||
|
||||
public getIntentForUserId() {
|
||||
return IntentMock.create();
|
||||
}
|
||||
}
|
@ -1,7 +1,14 @@
|
||||
export class MatrixClientMock {
|
||||
async setDisplayName() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
export class IntentMock {
|
||||
public readonly underlyingClient = new MatrixClientMock();
|
||||
public sentEvents: {roomId: string, content: any}[] = [];
|
||||
|
||||
static create(){
|
||||
static create(userId?: string){
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return new this() as any;
|
||||
}
|
||||
@ -22,4 +29,8 @@ export class IntentMock {
|
||||
content,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async ensureRegistered() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user