Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BREAKING: Add support for new state methods to snaps-simulation #2966

Merged
merged 4 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
238 changes: 238 additions & 0 deletions packages/examples/packages/manage-state/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,244 @@ describe('onRpcRequest', () => {
});
});

describe('setState', () => {
it('sets the state to the params', async () => {
const { request } = await installSnap();

expect(
await request({
method: 'setState',
params: {
value: {
items: ['foo'],
},
},
}),
).toRespondWith(null);

expect(
await request({
method: 'getState',
}),
).toRespondWith({
items: ['foo'],
});
});

it('sets the state at a specific key', async () => {
const { request } = await installSnap();

expect(
await request({
method: 'setState',
params: {
value: 'foo',
key: 'nested.key',
},
}),
).toRespondWith(null);

expect(
await request({
method: 'getState',
}),
).toRespondWith({
nested: {
key: 'foo',
},
});
});

it('sets the unencrypted state to the params', async () => {
const { request } = await installSnap();

expect(
await request({
method: 'setState',
params: {
value: {
items: ['foo'],
},
encrypted: false,
},
}),
).toRespondWith(null);

expect(
await request({
method: 'getState',
}),
).toRespondWith(null);

expect(
await request({
method: 'getState',
params: {
encrypted: false,
},
}),
).toRespondWith({
items: ['foo'],
});
});

it('throws if the state is not an object and no key is specified', async () => {
const { request } = await installSnap();

const response = await request({
method: 'setState',
params: {
value: 'foo',
},
});

expect(response).toRespondWithError(
expect.objectContaining({
code: -32602,
message:
'Invalid params: Value must be an object if key is not provided.',
}),
);
});
});

describe('getState', () => {
it('returns `null` if no state has been set', async () => {
const { request } = await installSnap();

const response = await request({
method: 'getState',
});

expect(response).toRespondWith(null);
});

it('returns the state', async () => {
const { request } = await installSnap();

await request({
method: 'setState',
params: {
value: {
items: ['foo'],
},
},
});

const response = await request({
method: 'getState',
});

expect(response).toRespondWith({
items: ['foo'],
});
});

it('returns the state at a specific key', async () => {
const { request } = await installSnap();

await request({
method: 'setState',
params: {
value: {
nested: {
key: 'foo',
},
},
},
});

const response = await request({
method: 'getState',
params: {
key: 'nested.key',
},
});

expect(response).toRespondWith('foo');
});

it('returns the unencrypted state', async () => {
const { request } = await installSnap();

await request({
method: 'setState',
params: {
value: {
items: ['foo'],
},
encrypted: false,
},
});

const response = await request({
method: 'getState',
params: {
encrypted: false,
},
});

expect(response).toRespondWith({
items: ['foo'],
});
});
});

describe('clearState', () => {
it('clears the state', async () => {
const { request } = await installSnap();

await request({
method: 'setState',
params: {
value: {
items: ['foo'],
},
},
});

await request({
method: 'clearState',
});

const response = await request({
method: 'getState',
});

expect(response).toRespondWith(null);
});

it('clears the unencrypted state', async () => {
const { request } = await installSnap();

await request({
method: 'setState',
params: {
value: {
items: ['foo'],
},
encrypted: false,
},
});

await request({
method: 'clearState',
params: {
encrypted: false,
},
});

const response = await request({
method: 'getState',
params: {
encrypted: false,
},
});

expect(response).toRespondWith(null);
});
});

describe('legacy_setState', () => {
it('sets the state to the params', async () => {
const { request } = await installSnap();
Expand Down
4 changes: 2 additions & 2 deletions packages/snaps-simulation/src/controllers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import {
} from '@metamask/permission-controller';

import { getControllers } from './controllers';
import type { MiddlewareHooks } from './simulation';
import type { RestrictedMiddlewareHooks } from './simulation';
import { getMockOptions } from './test-utils';

const MOCK_HOOKS: MiddlewareHooks = {
const MOCK_HOOKS: RestrictedMiddlewareHooks = {
getIsLocked: jest.fn(),
getMnemonic: jest.fn(),
getSnapFile: jest.fn(),
Expand Down
4 changes: 2 additions & 2 deletions packages/snaps-simulation/src/controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { getSafeJson } from '@metamask/utils';
import { getPermissionSpecifications } from './methods';
import { UNRESTRICTED_METHODS } from './methods/constants';
import type { SimulationOptions } from './options';
import type { MiddlewareHooks } from './simulation';
import type { RestrictedMiddlewareHooks } from './simulation';
import type { RunSagaFunction } from './store';

export type RootControllerAllowedActions =
Expand All @@ -49,7 +49,7 @@ export type RootControllerMessenger = ControllerMessenger<

export type GetControllersOptions = {
controllerMessenger: ControllerMessenger<any, any>;
hooks: MiddlewareHooks;
hooks: RestrictedMiddlewareHooks;
runSaga: RunSagaFunction;
options: SimulationOptions;
};
Expand Down
3 changes: 2 additions & 1 deletion packages/snaps-simulation/src/methods/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './get-preferences';
export * from './interface';
export * from './notifications';
export * from './permitted';
export * from './request-user-approval';
export * from './state';
export * from './interface';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './state';
Loading
Loading