Skip to content

Commit e9b74ae

Browse files
committed
tests(apps): fix node-runtime tests
1 parent b410886 commit e9b74ae

12 files changed

Lines changed: 219 additions & 121 deletions

packages/apps/node-runtime/src/handlers/tests/api-handler.test.ts

Lines changed: 76 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as assert from 'node:assert';
22
import { beforeEach, describe, it, mock } from 'node:test';
33

4+
import type { IRead, IModify, IHttp, IPersistence } from '@rocket.chat/apps-engine/definition/accessors';
5+
import type { IApiRequest, IApiEndpointInfo, IApiResponse } from '@rocket.chat/apps-engine/definition/api';
46
import type { IApiEndpoint } from '@rocket.chat/apps-engine/definition/api/IApiEndpoint';
57
import { JsonRpcError } from 'jsonrpc-lite';
68

@@ -9,13 +11,71 @@ import apiHandler from '../api-handler';
911
import { createMockRequest } from './helpers/mod';
1012

1113
describe('handlers > api', () => {
12-
const mockEndpoint: IApiEndpoint = {
14+
const mockEndpoint: Required<Omit<IApiEndpoint, 'delete'>> = {
1315
path: '/test',
14-
get: (request: any, endpoint: any, read: any, modify: any, http: any, persis: any) => Promise.resolve('ok'),
15-
post: (request: any, endpoint: any, read: any, modify: any, http: any, persis: any) => Promise.resolve('ok'),
16-
put: (request: any, endpoint: any, read: any, modify: any, http: any, persis: any) => {
16+
examples: {},
17+
authRequired: false,
18+
_availableMethods: [],
19+
get(
20+
_request: IApiRequest,
21+
_endpoint: IApiEndpointInfo,
22+
_read: IRead,
23+
_modify: IModify,
24+
_http: IHttp,
25+
_persis: IPersistence,
26+
): Promise<IApiResponse> {
27+
return Promise.resolve({ status: 200 });
28+
},
29+
post(
30+
_request: IApiRequest,
31+
_endpoint: IApiEndpointInfo,
32+
_read: IRead,
33+
_modify: IModify,
34+
_http: IHttp,
35+
_persis: IPersistence,
36+
): Promise<IApiResponse> {
37+
return Promise.resolve({ status: 200 });
38+
},
39+
put(
40+
_request: IApiRequest,
41+
_endpoint: IApiEndpointInfo,
42+
_read: IRead,
43+
_modify: IModify,
44+
_http: IHttp,
45+
_persis: IPersistence,
46+
): Promise<IApiResponse> {
1747
throw new Error('Method execution error example');
1848
},
49+
head(
50+
_request: IApiRequest,
51+
_endpoint: IApiEndpointInfo,
52+
_read: IRead,
53+
_modify: IModify,
54+
_http: IHttp,
55+
_persis: IPersistence,
56+
): Promise<IApiResponse> {
57+
throw new Error('Function not implemented.');
58+
},
59+
options(
60+
_request: IApiRequest,
61+
_endpoint: IApiEndpointInfo,
62+
_read: IRead,
63+
_modify: IModify,
64+
_http: IHttp,
65+
_persis: IPersistence,
66+
): Promise<IApiResponse> {
67+
throw new Error('Function not implemented.');
68+
},
69+
patch(
70+
_request: IApiRequest,
71+
_endpoint: IApiEndpointInfo,
72+
_read: IRead,
73+
_modify: IModify,
74+
_http: IHttp,
75+
_persis: IPersistence,
76+
): Promise<IApiResponse> {
77+
throw new Error('Function not implemented.');
78+
},
1979
};
2080

2181
beforeEach(() => {
@@ -28,7 +88,7 @@ describe('handlers > api', () => {
2888

2989
const result = await apiHandler(createMockRequest({ method: 'api:/test:get', params: ['request', 'endpointInfo'] }));
3090

31-
assert.deepStrictEqual(result, 'ok');
91+
assert.deepStrictEqual(result, { status: 200 });
3292
assert.deepStrictEqual(_spy.mock.calls[0].arguments.length, 6);
3393
assert.deepStrictEqual(_spy.mock.calls[0].arguments[0], 'request');
3494
assert.deepStrictEqual(_spy.mock.calls[0].arguments[1], 'endpointInfo');
@@ -41,7 +101,7 @@ describe('handlers > api', () => {
41101

42102
const result = await apiHandler(createMockRequest({ method: 'api:/test:post', params: ['request', 'endpointInfo'] }));
43103

44-
assert.deepStrictEqual(result, 'ok');
104+
assert.deepStrictEqual(result, { status: 200 });
45105
assert.deepStrictEqual(_spy.mock.calls[0].arguments.length, 6);
46106
assert.deepStrictEqual(_spy.mock.calls[0].arguments[0], 'request');
47107
assert.deepStrictEqual(_spy.mock.calls[0].arguments[1], 'endpointInfo');
@@ -53,8 +113,8 @@ describe('handlers > api', () => {
53113
const result = await apiHandler(createMockRequest({ method: `api:/test:delete`, params: ['request', 'endpointInfo'] }));
54114

55115
assert.ok(result instanceof JsonRpcError, `Expected instance of ${JsonRpcError.name}`);
56-
assert.strictEqual((result as any).message, `/test's delete not exists`);
57-
assert.strictEqual((result as any).code, -32000);
116+
assert.strictEqual(result.message, `/test's delete not exists`);
117+
assert.strictEqual(result.code, -32000);
58118
});
59119

60120
it('correctly handles an error if endpoint not exists', async () => {
@@ -74,9 +134,11 @@ describe('handlers > api', () => {
74134
});
75135

76136
it('correctly handles dynamic paths with parameters (e.g., webhook/:event)', async () => {
77-
const mockDynamicEndpoint: IApiEndpoint = {
137+
const mockDynamicEndpoint = {
138+
...mockEndpoint,
78139
path: 'webhook/:event',
79-
post: (request: any, endpoint: any, read: any, modify: any, http: any, persis: any) => Promise.resolve('webhook handled'),
140+
post: (_request: any, _endpoint: any, _read: any, _modify: any, _http: any, _persis: any) =>
141+
Promise.resolve('webhook handled' as any),
80142
};
81143

82144
AppObjectRegistry.set('api:webhook/:event', mockDynamicEndpoint);
@@ -94,9 +156,10 @@ describe('handlers > api', () => {
94156
});
95157

96158
it('correctly handles paths with multiple segments and colons', async () => {
97-
const mockComplexEndpoint: IApiEndpoint = {
159+
const mockComplexEndpoint = {
160+
...mockEndpoint,
98161
path: 'api/v1/:resource/:id',
99-
get: (request: any, endpoint: any, read: any, modify: any, http: any, persis: any) => Promise.resolve('complex path'),
162+
get: (_request: any, _endpoint: any, _read: any, _modify: any, _http: any, _persis: any) => Promise.resolve({ status: 201 }),
100163
};
101164

102165
AppObjectRegistry.set('api:api/v1/:resource/:id', mockComplexEndpoint);
@@ -105,7 +168,7 @@ describe('handlers > api', () => {
105168

106169
const result = await apiHandler(createMockRequest({ method: 'api:api/v1/:resource/:id:get', params: ['request', 'endpointInfo'] }));
107170

108-
assert.deepStrictEqual(result, 'complex path');
171+
assert.deepStrictEqual(result, { status: 201 });
109172
assert.deepStrictEqual(_spy.mock.calls[0].arguments.length, 6);
110173

111174
_spy.mock.restore();

packages/apps/node-runtime/src/handlers/tests/scheduler-handler.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ describe('handlers > scheduler', () => {
2424
mockAppAccessors.getConfigurationExtend().scheduler.registerProcessors([
2525
{
2626
id: 'mockId',
27-
processor: () => Promise.resolve('it works!'),
27+
processor: () => Promise.resolve(),
2828
},
2929
]);
3030
});

packages/apps/node-runtime/src/handlers/tests/slashcommand-handler.test.ts

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import * as assert from 'node:assert';
22
import { beforeEach, describe, it, mock } from 'node:test';
33

4+
import type { IRead, IModify, IHttp, IPersistence } from '@rocket.chat/apps-engine/definition/accessors';
5+
import type { ISlashCommand, SlashCommandContext } from '@rocket.chat/apps-engine/definition/slashcommands';
6+
47
import { AppObjectRegistry } from '../../AppObjectRegistry';
58
import { createMockRequest } from './helpers/mod';
69
import type { AppAccessors } from '../../lib/accessors/mod';
@@ -16,38 +19,36 @@ describe('handlers > slashcommand', () => {
1619
getSenderFn: () => (id: string) => Promise.resolve([{ __type: 'bridgeCall' }, { id }]),
1720
} as unknown as AppAccessors;
1821

19-
const mockCommandExecutorOnly = {
22+
const mockCommandExecutorOnly: ISlashCommand = {
2023
command: 'executor-only',
2124
i18nParamsExample: 'test',
2225
i18nDescription: 'test',
2326
providesPreview: false,
24-
async executor(context: any, read: any, modify: any, http: any, persis: any): Promise<void> {},
27+
executor(_context: SlashCommandContext, _read: IRead, _modify: IModify, _http: IHttp, _persis: IPersistence): Promise<void> {
28+
return Promise.resolve();
29+
},
2530
};
2631

27-
const mockCommandExecutorAndPreview = {
32+
const mockCommandExecutorAndPreview: ISlashCommand = {
2833
command: 'executor-and-preview',
2934
i18nParamsExample: 'test',
3035
i18nDescription: 'test',
3136
providesPreview: true,
32-
async executor(context: any, read: any, modify: any, http: any, persis: any): Promise<void> {},
33-
async previewer(context: any, read: any, modify: any, http: any, persis: any): Promise<void> {},
34-
async executePreviewItem(previewItem: any, context: any, read: any, modify: any, http: any, persis: any): Promise<void> {},
35-
};
36-
37-
const mockCommandPreviewWithNoExecutor = {
38-
command: 'preview-with-no-executor',
39-
i18nParamsExample: 'test',
40-
i18nDescription: 'test',
41-
providesPreview: true,
42-
async previewer(context: any, read: any, modify: any, http: any, persis: any): Promise<void> {},
43-
async executePreviewItem(previewItem: any, context: any, read: any, modify: any, http: any, persis: any): Promise<void> {},
37+
executor(_context: SlashCommandContext, _read: IRead, _modify: IModify, _http: IHttp, _persis: IPersistence): Promise<void> {
38+
return Promise.resolve();
39+
},
40+
previewer(_context, _read, _modify, _http, _persis) {
41+
return Promise.resolve({ i18nTitle: 'test', items: [] });
42+
},
43+
executePreviewItem(_item, _context, _read, _modify, _http, _persis) {
44+
return Promise.resolve();
45+
},
4446
};
4547

4648
beforeEach(() => {
4749
AppObjectRegistry.clear();
4850
AppObjectRegistry.set('slashcommand:executor-only', mockCommandExecutorOnly);
4951
AppObjectRegistry.set('slashcommand:executor-and-preview', mockCommandExecutorAndPreview);
50-
AppObjectRegistry.set('slashcommand:preview-with-no-executor', mockCommandPreviewWithNoExecutor);
5152
});
5253

5354
it('correctly handles execution of a slash command', async () => {

packages/apps/node-runtime/src/handlers/tests/uikit-handler.test.ts

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import * as assert from 'node:assert';
22
import { after, beforeEach, describe, it } from 'node:test';
33

4-
import jsonrpc from 'jsonrpc-lite';
4+
import jsonrpc, { type Defined } from 'jsonrpc-lite';
55

66
import { AppObjectRegistry } from '../../AppObjectRegistry';
7+
import { Logger } from '../../lib/logger';
8+
import type { RequestContext } from '../../lib/requestContext';
79
import handleUIKitInteraction, {
810
UIKitActionButtonInteractionContext,
911
UIKitBlockInteractionContext,
@@ -12,6 +14,14 @@ import handleUIKitInteraction, {
1214
UIKitViewSubmitInteractionContext,
1315
} from '../uikit/handler';
1416

17+
function makeMockRequest(method: string, payload: { [k: string]: Defined }): RequestContext {
18+
return Object.assign(jsonrpc.request(1, method, [payload]), {
19+
context: {
20+
logger: new Logger(method),
21+
},
22+
});
23+
}
24+
1525
describe('handlers > uikit', () => {
1626
const mockApp = {
1727
getID: (): string => 'appId',
@@ -31,73 +41,63 @@ describe('handlers > uikit', () => {
3141
});
3242

3343
it('successfully handles a call for "executeBlockActionHandler"', async () => {
34-
const request = jsonrpc.request(1, 'app:executeBlockActionHandler', [
35-
{
36-
actionId: 'actionId',
37-
blockId: 'blockId',
38-
value: 'value',
39-
viewId: 'viewId',
40-
},
41-
]);
44+
const request = makeMockRequest('app:executeBlockActionHandler', {
45+
actionId: 'actionId',
46+
blockId: 'blockId',
47+
value: 'value',
48+
viewId: 'viewId',
49+
});
4250

4351
const result = await handleUIKitInteraction(request);
4452
assert.ok(result instanceof UIKitBlockInteractionContext, `Expected instance of ${UIKitBlockInteractionContext.name}`);
4553
});
4654

4755
it('successfully handles a call for "executeViewSubmitHandler"', async () => {
48-
const request = jsonrpc.request(1, 'app:executeViewSubmitHandler', [
49-
{
50-
viewId: 'viewId',
51-
appId: 'appId',
52-
userId: 'userId',
53-
isAppUser: true,
54-
values: {},
55-
},
56-
]);
56+
const request = makeMockRequest('app:executeViewSubmitHandler', {
57+
viewId: 'viewId',
58+
appId: 'appId',
59+
userId: 'userId',
60+
isAppUser: true,
61+
values: {},
62+
});
5763

5864
const result = await handleUIKitInteraction(request);
5965
assert.ok(result instanceof UIKitViewSubmitInteractionContext, `Expected instance of ${UIKitViewSubmitInteractionContext.name}`);
6066
});
6167

6268
it('successfully handles a call for "executeViewClosedHandler"', async () => {
63-
const request = jsonrpc.request(1, 'app:executeViewClosedHandler', [
64-
{
65-
viewId: 'viewId',
66-
appId: 'appId',
67-
userId: 'userId',
68-
isAppUser: true,
69-
},
70-
]);
69+
const request = makeMockRequest('app:executeViewClosedHandler', {
70+
viewId: 'viewId',
71+
appId: 'appId',
72+
userId: 'userId',
73+
isAppUser: true,
74+
});
7175

7276
const result = await handleUIKitInteraction(request);
7377
assert.ok(result instanceof UIKitViewCloseInteractionContext, `Expected instance of ${UIKitViewCloseInteractionContext.name}`);
7478
});
7579

7680
it('successfully handles a call for "executeActionButtonHandler"', async () => {
77-
const request = jsonrpc.request(1, 'app:executeActionButtonHandler', [
78-
{
79-
actionId: 'actionId',
80-
appId: 'appId',
81-
userId: 'userId',
82-
isAppUser: true,
83-
},
84-
]);
81+
const request = makeMockRequest('app:executeActionButtonHandler', {
82+
actionId: 'actionId',
83+
appId: 'appId',
84+
userId: 'userId',
85+
isAppUser: true,
86+
});
8587

8688
const result = await handleUIKitInteraction(request);
8789
assert.ok(result instanceof UIKitActionButtonInteractionContext, `Expected instance of ${UIKitActionButtonInteractionContext.name}`);
8890
});
8991

9092
it('successfully handles a call for "executeLivechatBlockActionHandler"', async () => {
91-
const request = jsonrpc.request(1, 'app:executeLivechatBlockActionHandler', [
92-
{
93-
actionId: 'actionId',
94-
appId: 'appId',
95-
userId: 'userId',
96-
visitor: {},
97-
isAppUser: true,
98-
room: {},
99-
},
100-
]);
93+
const request = makeMockRequest('app:executeLivechatBlockActionHandler', {
94+
actionId: 'actionId',
95+
appId: 'appId',
96+
userId: 'userId',
97+
visitor: {},
98+
isAppUser: true,
99+
room: {},
100+
});
101101

102102
const result = await handleUIKitInteraction(request);
103103
assert.ok(result instanceof UIKitLivechatBlockInteractionContext, `Expected instance of ${UIKitLivechatBlockInteractionContext.name}`);

packages/apps/node-runtime/src/handlers/tests/upload-event-handler.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ describe('handlers > upload', () => {
2929
app = {
3030
extendConfiguration: () => {},
3131
executePreFileUpload: () => Promise.resolve(),
32-
} as unknown as App;
32+
} as unknown as App & IPreFileUpload;
3333

3434
AppObjectRegistry.set('app', app);
3535

0 commit comments

Comments
 (0)