Skip to content

Commit 2fed310

Browse files
committed
Add tests
1 parent d43e7de commit 2fed310

File tree

3 files changed

+368
-4
lines changed

3 files changed

+368
-4
lines changed

packages/snaps-rpc-methods/jest.config.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ module.exports = deepmerge(baseConfig, {
1010
],
1111
coverageThreshold: {
1212
global: {
13-
branches: 95.32,
14-
functions: 98.73,
15-
lines: 98.89,
16-
statements: 98.59,
13+
branches: 95.37,
14+
functions: 98.76,
15+
lines: 98.92,
16+
statements: 98.62,
1717
},
1818
},
1919
});
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
import { JsonRpcEngine } from '@metamask/json-rpc-engine';
2+
import type { EndTraceParams, EndTraceResult } from '@metamask/snaps-sdk';
3+
import type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';
4+
5+
import { endTraceHandler } from './endTrace';
6+
7+
describe('snap_endTrace', () => {
8+
describe('endTraceHandler', () => {
9+
it('has the expected shape', () => {
10+
expect(endTraceHandler).toMatchObject({
11+
methodNames: ['snap_endTrace'],
12+
implementation: expect.any(Function),
13+
hookNames: {
14+
endTrace: true,
15+
getSnap: true,
16+
},
17+
});
18+
});
19+
});
20+
21+
describe('implementation', () => {
22+
it('calls the `endTrace` hook with the provided parameters', async () => {
23+
const { implementation } = endTraceHandler;
24+
25+
const endTrace = jest.fn().mockReturnValue(null);
26+
27+
const getSnap = jest.fn().mockReturnValue({ preinstalled: true });
28+
const hooks = { endTrace, getSnap };
29+
30+
const engine = new JsonRpcEngine();
31+
32+
engine.push((request, response, next, end) => {
33+
const result = implementation(
34+
request as JsonRpcRequest<EndTraceParams>,
35+
response as PendingJsonRpcResponse<EndTraceResult>,
36+
next,
37+
end,
38+
hooks,
39+
);
40+
41+
result?.catch(end);
42+
});
43+
44+
const response = await engine.handle({
45+
jsonrpc: '2.0',
46+
id: 1,
47+
method: 'snap_endTrace',
48+
params: {
49+
id: 'test-id',
50+
name: 'Test Trace',
51+
timestamp: 1234567890,
52+
},
53+
});
54+
55+
expect(response).toStrictEqual({
56+
jsonrpc: '2.0',
57+
id: 1,
58+
result: null,
59+
});
60+
61+
expect(endTrace).toHaveBeenCalledWith({
62+
id: 'test-id',
63+
name: 'Test Trace',
64+
timestamp: 1234567890,
65+
});
66+
});
67+
68+
it('throws an error if the Snap is not preinstalled', async () => {
69+
const { implementation } = endTraceHandler;
70+
71+
const endTrace = jest.fn();
72+
const getSnap = jest.fn().mockReturnValue({ preinstalled: false });
73+
const hooks = { endTrace, getSnap };
74+
75+
const engine = new JsonRpcEngine();
76+
77+
engine.push((request, response, next, end) => {
78+
const result = implementation(
79+
request as JsonRpcRequest<EndTraceParams>,
80+
response as PendingJsonRpcResponse<EndTraceResult>,
81+
next,
82+
end,
83+
hooks,
84+
);
85+
86+
result?.catch(end);
87+
});
88+
89+
const response = await engine.handle({
90+
jsonrpc: '2.0',
91+
id: 1,
92+
method: 'snap_endTrace',
93+
params: {
94+
id: 'test-id',
95+
name: 'Test Trace',
96+
data: { foo: 'bar' },
97+
tags: { tag1: 'value1', tag2: 42 },
98+
startTime: 1234567890,
99+
},
100+
});
101+
102+
expect(endTrace).not.toHaveBeenCalled();
103+
expect(response).toStrictEqual({
104+
jsonrpc: '2.0',
105+
id: 1,
106+
error: {
107+
code: -32601,
108+
message: 'The method does not exist / is not available.',
109+
stack: expect.any(String),
110+
},
111+
});
112+
});
113+
114+
it.each([
115+
[
116+
{ foo: 'bar' },
117+
'Invalid params: At path: name -- Expected a string, but received: undefined.',
118+
],
119+
[
120+
{ name: undefined },
121+
'Invalid params: At path: name -- Expected a string, but received: undefined.',
122+
],
123+
[
124+
{ name: 'Test Trace', id: 123 },
125+
'Invalid params: At path: id -- Expected a string, but received: 123.',
126+
],
127+
[
128+
{ name: 'Test Trace', id: 'test-id', timestamp: 'not-a-number' },
129+
'Invalid params: At path: timestamp -- Expected a number, but received: "not-a-number".',
130+
],
131+
])(
132+
'throws an error if the parameters are invalid',
133+
async (params, error) => {
134+
const { implementation } = endTraceHandler;
135+
136+
const endTrace = jest.fn();
137+
const getSnap = jest.fn().mockReturnValue({ preinstalled: true });
138+
const hooks = { endTrace, getSnap };
139+
140+
const engine = new JsonRpcEngine();
141+
142+
engine.push((request, response, next, end) => {
143+
const result = implementation(
144+
request as JsonRpcRequest<EndTraceParams>,
145+
response as PendingJsonRpcResponse<EndTraceResult>,
146+
next,
147+
end,
148+
hooks,
149+
);
150+
151+
result?.catch(end);
152+
});
153+
154+
// @ts-expect-error: Intentionally passing invalid params.
155+
// eslint-disable-next-line @typescript-eslint/await-thenable
156+
const response = await engine.handle({
157+
jsonrpc: '2.0',
158+
id: 1,
159+
method: 'snap_endTrace',
160+
params,
161+
});
162+
163+
expect(endTrace).not.toHaveBeenCalled();
164+
expect(response).toStrictEqual({
165+
jsonrpc: '2.0',
166+
id: 1,
167+
error: {
168+
code: -32602,
169+
message: error,
170+
stack: expect.any(String),
171+
},
172+
});
173+
},
174+
);
175+
});
176+
});
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import { JsonRpcEngine } from '@metamask/json-rpc-engine';
2+
import type { StartTraceParams } from '@metamask/snaps-sdk';
3+
import type { JsonRpcRequest } from '@metamask/utils';
4+
5+
import { startTraceHandler } from './startTrace';
6+
7+
describe('snap_startTrace', () => {
8+
describe('startTraceHandler', () => {
9+
it('has the expected shape', () => {
10+
expect(startTraceHandler).toMatchObject({
11+
methodNames: ['snap_startTrace'],
12+
implementation: expect.any(Function),
13+
hookNames: {
14+
startTrace: true,
15+
getSnap: true,
16+
},
17+
});
18+
});
19+
});
20+
21+
describe('implementation', () => {
22+
it('calls the `startTrace` hook with the provided parameters', async () => {
23+
const { implementation } = startTraceHandler;
24+
25+
const startTrace = jest.fn().mockReturnValue({
26+
traceId: 'test-trace-id',
27+
});
28+
29+
const getSnap = jest.fn().mockReturnValue({ preinstalled: true });
30+
const hooks = { startTrace, getSnap };
31+
32+
const engine = new JsonRpcEngine();
33+
34+
engine.push((request, response, next, end) => {
35+
const result = implementation(
36+
request as JsonRpcRequest<StartTraceParams>,
37+
response,
38+
next,
39+
end,
40+
hooks,
41+
);
42+
43+
result?.catch(end);
44+
});
45+
46+
const response = await engine.handle({
47+
jsonrpc: '2.0',
48+
id: 1,
49+
method: 'snap_startTrace',
50+
params: {
51+
id: 'test-id',
52+
name: 'Test Trace',
53+
data: { foo: 'bar' },
54+
tags: { tag1: 'value1', tag2: 42 },
55+
startTime: 1234567890,
56+
},
57+
});
58+
59+
expect(response).toStrictEqual({
60+
jsonrpc: '2.0',
61+
id: 1,
62+
result: {
63+
traceId: 'test-trace-id',
64+
},
65+
});
66+
67+
expect(startTrace).toHaveBeenCalledWith({
68+
id: 'test-id',
69+
name: 'Test Trace',
70+
data: { foo: 'bar' },
71+
tags: { tag1: 'value1', tag2: 42 },
72+
startTime: 1234567890,
73+
});
74+
});
75+
76+
it('throws an error if the Snap is not preinstalled', async () => {
77+
const { implementation } = startTraceHandler;
78+
79+
const startTrace = jest.fn();
80+
const getSnap = jest.fn().mockReturnValue({ preinstalled: false });
81+
const hooks = { startTrace, getSnap };
82+
83+
const engine = new JsonRpcEngine();
84+
85+
engine.push((request, response, next, end) => {
86+
const result = implementation(
87+
request as JsonRpcRequest<StartTraceParams>,
88+
response,
89+
next,
90+
end,
91+
hooks,
92+
);
93+
94+
result?.catch(end);
95+
});
96+
97+
const response = await engine.handle({
98+
jsonrpc: '2.0',
99+
id: 1,
100+
method: 'snap_startTrace',
101+
params: {
102+
id: 'test-id',
103+
name: 'Test Trace',
104+
data: { foo: 'bar' },
105+
tags: { tag1: 'value1', tag2: 42 },
106+
startTime: 1234567890,
107+
},
108+
});
109+
110+
expect(startTrace).not.toHaveBeenCalled();
111+
expect(response).toStrictEqual({
112+
jsonrpc: '2.0',
113+
id: 1,
114+
error: {
115+
code: -32601,
116+
message: 'The method does not exist / is not available.',
117+
stack: expect.any(String),
118+
},
119+
});
120+
});
121+
122+
it.each([
123+
[
124+
{ foo: 'bar' },
125+
'Invalid params: At path: name -- Expected a string, but received: undefined.',
126+
],
127+
[
128+
{ name: undefined },
129+
'Invalid params: At path: name -- Expected a string, but received: undefined.',
130+
],
131+
[
132+
{ name: 'Test Trace', id: 123 },
133+
'Invalid params: At path: id -- Expected a string, but received: 123.',
134+
],
135+
[
136+
{ name: 'Test Trace', id: 'test-id', data: 'not-an-object' },
137+
'Invalid params: At path: data -- Expected an object, but received: "not-an-object".',
138+
],
139+
[
140+
{ name: 'Test Trace', id: 'test-id', tags: 'not-an-object' },
141+
'Invalid params: At path: tags -- Expected an object, but received: "not-an-object".',
142+
],
143+
])(
144+
'throws an error if the parameters are invalid',
145+
async (params, error) => {
146+
const { implementation } = startTraceHandler;
147+
148+
const startTrace = jest.fn();
149+
const getSnap = jest.fn().mockReturnValue({ preinstalled: true });
150+
const hooks = { startTrace, getSnap };
151+
152+
const engine = new JsonRpcEngine();
153+
154+
engine.push((request, response, next, end) => {
155+
const result = implementation(
156+
request as JsonRpcRequest<StartTraceParams>,
157+
response,
158+
next,
159+
end,
160+
hooks,
161+
);
162+
163+
result?.catch(end);
164+
});
165+
166+
// @ts-expect-error: Intentionally passing invalid params.
167+
// eslint-disable-next-line @typescript-eslint/await-thenable
168+
const response = await engine.handle({
169+
jsonrpc: '2.0',
170+
id: 1,
171+
method: 'snap_startTrace',
172+
params,
173+
});
174+
175+
expect(startTrace).not.toHaveBeenCalled();
176+
expect(response).toStrictEqual({
177+
jsonrpc: '2.0',
178+
id: 1,
179+
error: {
180+
code: -32602,
181+
message: error,
182+
stack: expect.any(String),
183+
},
184+
});
185+
},
186+
);
187+
});
188+
});

0 commit comments

Comments
 (0)