Skip to content

Commit 19202f3

Browse files
committed
Add more tests
1 parent 637a21a commit 19202f3

File tree

5 files changed

+120
-7
lines changed

5 files changed

+120
-7
lines changed
+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"branches": 93.06,
2+
"branches": 92.41,
33
"functions": 96.54,
4-
"lines": 98.02,
5-
"statements": 97.74
4+
"lines": 97.99,
5+
"statements": 97.71
66
}

packages/snaps-controllers/src/snaps/SnapController.test.tsx

+71
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import {
6060
AssertionError,
6161
base64ToBytes,
6262
stringToBytes,
63+
createDeferredPromise,
6364
} from '@metamask/utils';
6465
import { File } from 'buffer';
6566
import { webcrypto } from 'crypto';
@@ -78,6 +79,7 @@ import {
7879
getNodeEESMessenger,
7980
getPersistedSnapsState,
8081
getSnapController,
82+
getSnapControllerEncryptor,
8183
getSnapControllerMessenger,
8284
getSnapControllerOptions,
8385
getSnapControllerWithEES,
@@ -9164,6 +9166,40 @@ describe('SnapController', () => {
91649166

91659167
snapController.destroy();
91669168
});
9169+
9170+
it('logs an error message if the state fails to persist', async () => {
9171+
const messenger = getSnapControllerMessenger();
9172+
9173+
const errorValue = new Error('Failed to persist state.');
9174+
const snapController = getSnapController(
9175+
getSnapControllerOptions({
9176+
messenger,
9177+
state: {
9178+
snaps: getPersistedSnapsState(),
9179+
},
9180+
// @ts-expect-error - Missing required properties.
9181+
encryptor: {
9182+
...getSnapControllerEncryptor(),
9183+
encryptWithKey: jest.fn().mockRejectedValue(errorValue),
9184+
},
9185+
}),
9186+
);
9187+
9188+
const { promise, resolve } = createDeferredPromise();
9189+
const error = jest.spyOn(console, 'error').mockImplementation(resolve);
9190+
9191+
await messenger.call(
9192+
'SnapController:updateSnapState',
9193+
MOCK_SNAP_ID,
9194+
{ foo: 'bar' },
9195+
true,
9196+
);
9197+
9198+
await promise;
9199+
expect(error).toHaveBeenCalledWith(errorValue);
9200+
9201+
snapController.destroy();
9202+
});
91679203
});
91689204

91699205
describe('SnapController:clearSnapState', () => {
@@ -9222,6 +9258,41 @@ describe('SnapController', () => {
92229258

92239259
snapController.destroy();
92249260
});
9261+
9262+
it('logs an error message if the state fails to persist', async () => {
9263+
const messenger = getSnapControllerMessenger();
9264+
9265+
const errorValue = new Error('Failed to persist state.');
9266+
const snapController = getSnapController(
9267+
getSnapControllerOptions({
9268+
messenger,
9269+
state: {
9270+
snaps: getPersistedSnapsState(),
9271+
},
9272+
// @ts-expect-error - Missing required properties.
9273+
encryptor: {
9274+
...getSnapControllerEncryptor(),
9275+
encryptWithKey: jest.fn().mockRejectedValue(errorValue),
9276+
},
9277+
}),
9278+
);
9279+
9280+
const { promise, resolve } = createDeferredPromise();
9281+
const error = jest.spyOn(console, 'error').mockImplementation(resolve);
9282+
9283+
// @ts-expect-error - Property `update` is protected.
9284+
// eslint-disable-next-line jest/prefer-spy-on
9285+
snapController.update = jest.fn().mockImplementation(() => {
9286+
throw errorValue;
9287+
});
9288+
9289+
await messenger.call('SnapController:clearSnapState', MOCK_SNAP_ID, true);
9290+
9291+
await promise;
9292+
expect(error).toHaveBeenCalledWith(errorValue);
9293+
9294+
snapController.destroy();
9295+
});
92259296
});
92269297

92279298
describe('SnapController:updateBlockedSnaps', () => {

packages/snaps-controllers/src/test-utils/controller.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {
1111
exportKey,
1212
generateSalt,
1313
isVaultUpdated,
14+
encrypt,
15+
decrypt,
1416
} from '@metamask/browser-passworder';
1517
import type {
1618
PermissionConstraint,
@@ -540,8 +542,10 @@ export const DEFAULT_ENCRYPTION_KEY_DERIVATION_OPTIONS = {
540542
},
541543
};
542544

543-
const getSnapControllerEncryptor = () => {
545+
export const getSnapControllerEncryptor = () => {
544546
return {
547+
encrypt,
548+
decrypt,
545549
encryptWithKey,
546550
decryptWithKey,
547551
keyFromPassword: async (

packages/snaps-utils/coverage.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"branches": 99.74,
3-
"functions": 98.93,
4-
"lines": 99.46,
5-
"statements": 96.31
3+
"functions": 98.95,
4+
"lines": 99.47,
5+
"statements": 96.33
66
}
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { createDeferredPromise } from '@metamask/utils';
2+
3+
import { withMutex } from './mutex';
4+
5+
describe('withMutex', () => {
6+
it('runs the function with a mutex', async () => {
7+
jest.useFakeTimers();
8+
9+
const { promise, resolve: resolveDeferred } = createDeferredPromise();
10+
11+
const fn = jest.fn().mockImplementation(async () => {
12+
return await new Promise<void>((resolve) => {
13+
resolveDeferred();
14+
setTimeout(() => {
15+
resolve();
16+
}, 1000);
17+
});
18+
});
19+
20+
const wrappedFn = withMutex(fn);
21+
22+
const first = wrappedFn();
23+
const second = wrappedFn();
24+
25+
await promise;
26+
jest.advanceTimersByTime(1000);
27+
28+
expect(fn).toHaveBeenCalledTimes(1);
29+
30+
await first;
31+
32+
jest.advanceTimersByTime(1000);
33+
34+
await second;
35+
36+
expect(fn).toHaveBeenCalledTimes(2);
37+
});
38+
});

0 commit comments

Comments
 (0)