Skip to content

Commit

Permalink
refactor: add jest module (#302)
Browse files Browse the repository at this point in the history
* chore: add jest module

* chore: update jest config

* chore: update test case
  • Loading branch information
stanleyyconsensys authored Jul 30, 2024
1 parent 63a7789 commit 73113b4
Show file tree
Hide file tree
Showing 8 changed files with 967 additions and 21 deletions.
6 changes: 6 additions & 0 deletions packages/starknet-snap/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
],
};
34 changes: 34 additions & 0 deletions packages/starknet-snap/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module.exports = {
preset: '@metamask/snaps-jest',
transform: {
'^.+\\.(t|j)sx?$': 'ts-jest',
},
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
restoreMocks: true,
resetMocks: true,
verbose: true,
testPathIgnorePatterns: ['/node_modules/', '/__mocks__/'],
testMatch: ['<rootDir>/src/**/?(*.)+(spec|test).[tj]s?(x)'],
// Switch off the collectCoverage until jest replace mocha
collectCoverage: false,
// An array of glob patterns indicating a set of files for which coverage information should be collected
collectCoverageFrom: [
'./src/**/*.ts',
'!./src/**/*.d.ts',
'!./src/**/index.ts',
'!./src/**/__BAK__/**',
'!./src/**/__mocks__/**',
'!./src/config/*.ts',
'!./src/**/type?(s).ts',
'!./src/**/exception?(s).ts',
'!./src/**/constant?(s).ts',
'!./test/**',
'./src/index.ts',
],
// The directory where Jest should output its coverage files
coverageDirectory: 'coverage',
// Indicates which provider should be used to instrument code for coverage
coverageProvider: 'babel',
// A list of reporter names that Jest uses when writing coverage reports
coverageReporters: ['html', 'json-summary', 'text'],
};
6 changes: 6 additions & 0 deletions packages/starknet-snap/jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { MockSnapProvider } from './src/__mocks__/snap-provider.mock';

// eslint-disable-next-line no-restricted-globals
const globalAny: any = global;

globalAny.snap = new MockSnapProvider();
10 changes: 7 additions & 3 deletions packages/starknet-snap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@
"build:clean": "yarn clean && yarn build",
"clean": "rimraf dist",
"cover:report": "nyc report --reporter=lcov --reporter=text",
"jest": "jest --passWithNoTests",
"lint": "yarn lint:eslint && yarn lint:misc --check",
"lint:eslint": "eslint . --cache --ext js,ts",
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
"lint:misc": "prettier '**/*.ts' '**/*.json' '**/*.md' '!CHANGELOG.md' --ignore-path .gitignore",
"serve": "mm-snap serve",
"start": "mm-snap watch",
"test": "yarn run test:unit && yarn run cover:report",
"test": "yarn run test:unit && yarn run cover:report && yarn run jest",
"test:unit": "nyc --check-coverage --statements 70 --branches 70 --functions 70 --lines 70 mocha --colors -r ts-node/register \"test/**/*.test.ts\"",
"test:unit:one": "nyc --check-coverage --statements 70 --branches 70 --functions 70 --lines 70 mocha --colors -r ts-node/register"
},
Expand All @@ -46,12 +47,13 @@
"starknet_v4.22.0": "npm:[email protected]"
},
"devDependencies": {
"@babel/preset-typescript": "^7.23.3",
"@metamask/eslint-config": "^12.2.0",
"@metamask/eslint-config-jest": "^12.1.0",
"@metamask/eslint-config-nodejs": "^12.1.0",
"@metamask/eslint-config-typescript": "^12.1.0",
"@metamask/snaps-cli": "^6.1.0",
"@metamask/snaps-jest": "^8.0.0",
"@metamask/snaps-cli": "^6.2.1",
"@metamask/snaps-jest": "^8.2.0",
"@types/chai": "^4.3.1",
"@types/chai-as-promised": "^7.1.5",
"@types/sinon": "^10.0.11",
Expand All @@ -70,13 +72,15 @@
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^6.1.1",
"jest": "^29.5.0",
"mocha": "^9.2.2",
"nyc": "^15.1.0",
"prettier": "^2.7.1",
"prettier-plugin-packagejson": "^2.2.11",
"rimraf": "^3.0.2",
"sinon": "^13.0.2",
"sinon-chai": "^3.7.0",
"ts-jest": "^29.1.0",
"ts-node": "^10.9.2",
"typescript": "^4.7.4"
},
Expand Down
42 changes: 42 additions & 0 deletions packages/starknet-snap/src/__mocks__/snap-provider.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export type SnapProvider = {
registerRpcMessageHandler: (fn) => unknown;
request(options: {
method: string;
params?: { [key: string]: unknown } | unknown[];
}): unknown;
};

export class MockSnapProvider implements SnapProvider {
public readonly registerRpcMessageHandler = jest.fn();

public readonly requestStub = jest.fn();
/* eslint-disable */
public readonly rpcStubs = {
snap_getBip32Entropy: jest.fn(),
snap_getBip44Entropy: jest.fn(),
snap_dialog: jest.fn(),
snap_manageState: jest.fn(),
};
/* eslint-disable */

/**
* Calls this.requestStub or this.rpcStubs[req.method], if the method has
* a dedicated stub.
* @param args
* @param args.method
* @param args.params
*/
public request(args: {
method: string;
params: { [key: string]: unknown } | unknown[];
}): unknown {
const { method, params } = args;
if (Object.hasOwnProperty.call(this.rpcStubs, method)) {
if (Array.isArray(params)) {
return this.rpcStubs[method](...params);
}
return this.rpcStubs[method](params);
}
return this.requestStub(args);
}
}
82 changes: 82 additions & 0 deletions packages/starknet-snap/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { onRpcRequest } from '.';
import * as createAccountApi from './createAccount';
import * as keyPairUtils from './utils/keyPair';
import { LogLevel, logger } from './utils/logger';

jest.mock('./utils/logger');

describe('onRpcRequest', function () {
const createMockSpy = () => {
const createAccountSpy = jest.spyOn(createAccountApi, 'createAccount');
const keyPairSpy = jest.spyOn(keyPairUtils, 'getAddressKeyDeriver');
const getLogLevelSpy = jest.spyOn(logger, 'getLogLevel');
return {
createAccountSpy,
keyPairSpy,
getLogLevelSpy,
};
};

const createMockRequest = (params = {}) => {
return {
origin: 'http://localhost:3000',
request: {
method: 'starkNet_createAccount',
params,
jsonrpc: '2.0' as const,
id: 1,
},
};
};

it('processes request successfully', async function () {
const { createAccountSpy, keyPairSpy, getLogLevelSpy } = createMockSpy();

createAccountSpy.mockReturnThis();
keyPairSpy.mockReturnThis();
getLogLevelSpy.mockReturnValue(LogLevel.OFF);

await onRpcRequest(createMockRequest());

expect(keyPairSpy).toHaveBeenCalledTimes(1);
expect(createAccountSpy).toHaveBeenCalledTimes(1);
});

it('throws `Unable to execute the rpc request` error if an error has thrown and LogLevel is 0', async function () {
const { createAccountSpy, keyPairSpy, getLogLevelSpy } = createMockSpy();

createAccountSpy.mockRejectedValue(new Error('Custom Error'));
keyPairSpy.mockReturnThis();
getLogLevelSpy.mockReturnValue(LogLevel.OFF);

await expect(onRpcRequest(createMockRequest())).rejects.toThrow(
'Unable to execute the rpc request',
);
});

it.each([
LogLevel.DEBUG,
LogLevel.ALL,
LogLevel.ERROR,
LogLevel.INFO,
LogLevel.TRACE,
LogLevel.WARN,
])(
`throws 'Unable to execute the rpc request' error if an error has thrown and LogLevel is %s`,
async function (logLevel) {
const { createAccountSpy, keyPairSpy, getLogLevelSpy } = createMockSpy();

createAccountSpy.mockRejectedValue(new Error('Custom Error'));
keyPairSpy.mockReturnThis();
getLogLevelSpy.mockReturnValue(logLevel);

await expect(
onRpcRequest(
createMockRequest({
debugLevel: LogLevel[logLevel],
}),
),
).rejects.toThrow('Custom Error');
},
);
});
31 changes: 31 additions & 0 deletions packages/starknet-snap/src/utils/__mocks__/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
export enum LogLevel {
ERROR = 1,
WARN = 2,
INFO = 3,
DEBUG = 4,
TRACE = 5,
ALL = 6,
OFF = 0,
}

export class Logger {
log = jest.fn();

warn = jest.fn();

error = jest.fn();

debug = jest.fn();

info = jest.fn();

trace = jest.fn();

init = jest.fn();

getLogLevel = jest.fn();

logLevel = 0;
}

export const logger = new Logger();
Loading

0 comments on commit 73113b4

Please sign in to comment.