Skip to content

Commit eb980b2

Browse files
Add tests for protocol endowment
1 parent 994c2ac commit eb980b2

File tree

4 files changed

+161
-4
lines changed

4 files changed

+161
-4
lines changed

packages/snaps-rpc-methods/src/endowments/keyring.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ describe('endowment:keyring', () => {
2323
subjectTypes: [SubjectType.Snap],
2424
validator: expect.any(Function),
2525
});
26+
27+
expect(specification.endowmentGetter()).toBeNull();
2628
});
2729

2830
describe('validator', () => {
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import { PermissionType, SubjectType } from '@metamask/permission-controller';
2+
import { SnapCaveatType } from '@metamask/snaps-utils';
3+
4+
import { SnapEndowments } from './enum';
5+
import {
6+
getProtocolCaveatMapper,
7+
getProtocolCaveatScopes,
8+
protocolCaveatSpecifications,
9+
protocolEndowmentBuilder,
10+
} from './protocol';
11+
12+
describe('endowment:protocol', () => {
13+
it('builds the expected permission specification', () => {
14+
const specification = protocolEndowmentBuilder.specificationBuilder({});
15+
expect(specification).toStrictEqual({
16+
permissionType: PermissionType.Endowment,
17+
targetName: SnapEndowments.Protocol,
18+
endowmentGetter: expect.any(Function),
19+
allowedCaveats: [
20+
SnapCaveatType.ProtocolSnapScopes,
21+
SnapCaveatType.MaxRequestTime,
22+
],
23+
subjectTypes: [SubjectType.Snap],
24+
validator: expect.any(Function),
25+
});
26+
27+
expect(specification.endowmentGetter()).toBeNull();
28+
});
29+
30+
describe('validator', () => {
31+
it('throws if the caveat is not a single "protocolSnapScopes"', () => {
32+
const specification = protocolEndowmentBuilder.specificationBuilder({});
33+
34+
expect(() =>
35+
specification.validator({
36+
// @ts-expect-error Missing other required permission types.
37+
caveats: undefined,
38+
}),
39+
).toThrow('Expected the following caveats: "protocolSnapScopes".');
40+
41+
expect(() =>
42+
// @ts-expect-error Missing other required permission types.
43+
specification.validator({
44+
caveats: [{ type: 'foo', value: 'bar' }],
45+
}),
46+
).toThrow(
47+
'Expected the following caveats: "protocolSnapScopes", "maxRequestTime", received "foo".',
48+
);
49+
50+
expect(() =>
51+
// @ts-expect-error Missing other required permission types.
52+
specification.validator({
53+
caveats: [
54+
{ type: SnapCaveatType.ProtocolSnapScopes, value: 'bar' },
55+
{ type: SnapCaveatType.ProtocolSnapScopes, value: 'bar' },
56+
],
57+
}),
58+
).toThrow('Duplicate caveats are not allowed.');
59+
});
60+
});
61+
});
62+
63+
describe('getProtocolCaveatMapper', () => {
64+
it('maps a value to a caveat', () => {
65+
expect(
66+
getProtocolCaveatMapper({
67+
scopes: {
68+
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': {
69+
methods: ['getVersion'],
70+
},
71+
},
72+
}),
73+
).toStrictEqual({
74+
caveats: [
75+
{
76+
type: SnapCaveatType.ProtocolSnapScopes,
77+
value: {
78+
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': {
79+
methods: ['getVersion'],
80+
},
81+
},
82+
},
83+
],
84+
});
85+
});
86+
87+
it('returns null if value is empty', () => {
88+
expect(getProtocolCaveatMapper({})).toStrictEqual({ caveats: null });
89+
});
90+
});
91+
92+
describe('getProtocolCaveatScopes', () => {
93+
it('returns the scopes from the caveat', () => {
94+
expect(
95+
// @ts-expect-error Missing other required permission types.
96+
getProtocolCaveatScopes({
97+
caveats: [
98+
{
99+
type: SnapCaveatType.ProtocolSnapScopes,
100+
value: {
101+
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': {
102+
methods: ['getVersion'],
103+
},
104+
},
105+
},
106+
],
107+
}),
108+
).toStrictEqual({
109+
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': {
110+
methods: ['getVersion'],
111+
},
112+
});
113+
});
114+
115+
it('returns null if no caveat found', () => {
116+
expect(
117+
// @ts-expect-error Missing other required permission types.
118+
getProtocolCaveatScopes({
119+
caveats: null,
120+
}),
121+
).toBeNull();
122+
});
123+
});
124+
125+
describe('protocolCaveatSpecifications', () => {
126+
describe('validator', () => {
127+
it('throws if the caveat values are invalid', () => {
128+
expect(() =>
129+
protocolCaveatSpecifications[
130+
SnapCaveatType.ProtocolSnapScopes
131+
].validator?.(
132+
// @ts-expect-error Missing value type.
133+
{
134+
type: SnapCaveatType.ProtocolSnapScopes,
135+
},
136+
),
137+
).toThrow('Expected a plain object.');
138+
139+
expect(() =>
140+
protocolCaveatSpecifications[
141+
SnapCaveatType.ProtocolSnapScopes
142+
].validator?.({
143+
type: SnapCaveatType.ProtocolSnapScopes,
144+
value: {
145+
foo: 'bar',
146+
},
147+
}),
148+
).toThrow(
149+
'Invalid scopes specified: At path: foo -- Expected a string matching `/^(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-_a-zA-Z0-9]{1,32})$/` but received "foo".',
150+
);
151+
});
152+
});
153+
});

packages/snaps-rpc-methods/src/endowments/protocol.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ const specificationBuilder: PermissionSpecificationBuilder<
4949
return {
5050
permissionType: PermissionType.Endowment,
5151
targetName: permissionName,
52-
allowedCaveats: [SnapCaveatType.ChainIds, SnapCaveatType.MaxRequestTime],
52+
allowedCaveats: [
53+
SnapCaveatType.ProtocolSnapScopes,
54+
SnapCaveatType.MaxRequestTime,
55+
],
5356
endowmentGetter: (_getterOptions?: EndowmentGetterParams) => null,
5457
validator: createGenericPermissionValidator([
5558
{ type: SnapCaveatType.ProtocolSnapScopes },
@@ -127,7 +130,7 @@ function validateCaveat(caveat: Caveat<string, any>): void {
127130
assertStruct(
128131
value,
129132
ProtocolScopesStruct,
130-
'Invalid chains specified',
133+
'Invalid scopes specified',
131134
rpcErrors.invalidParams,
132135
);
133136
}

packages/snaps-rpc-methods/src/permissions.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ describe('buildSnapEndowmentSpecifications', () => {
8484
},
8585
"endowment:protocol": {
8686
"allowedCaveats": [
87-
"chainIds",
88-
"snapRpcMethods",
87+
"protocolSnapScopes",
8988
"maxRequestTime",
9089
],
9190
"endowmentGetter": [Function],

0 commit comments

Comments
 (0)