Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Commit

Permalink
Move all purser-core tests to TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
chmanie committed Apr 23, 2020
1 parent f10f506 commit 3db0578
Show file tree
Hide file tree
Showing 43 changed files with 444 additions and 511 deletions.
8 changes: 7 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
"plugins": [
"@typescript-eslint"
],
"env": {
"es2020": true,
"node": true,
"browser": true
},
"rules": {
"no-unused-vars": "off",
"camelcase": "off",
Expand All @@ -26,7 +31,8 @@
"jest": true
},
"rules": {
"max-len": "off"
"max-len": "off",
"@typescript-eslint/ban-ts-ignore": "off"
}
}
]
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export const Wallet = jest.fn().mockImplementation(privateKey => {
export const Wallet: jest.Mock<any, any> & {
createRandom?: jest.Mock<any, any>;
fromEncryptedJson?: jest.Mock<any, any>;
} = jest.fn().mockImplementation(privateKey => {
if (privateKey === '0x0' || !privateKey) {
throw new Error();
}
Expand Down
File renamed without changes.
13 changes: 4 additions & 9 deletions packages/purser-core/__tests__/GenericWallet.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import HDKey from 'hdkey';
import { computeAddress } from 'ethers/utils';

import { jestMocked } from '../../testutils';
import { GenericWallet } from '../src';
import {
safeIntegerValidator,
Expand All @@ -15,15 +16,9 @@ jest.mock('ethers/utils');
jest.mock('../src/validators');
jest.mock('../src/normalizers');

const mockedAddressNormalizer = (addressNormalizer as unknown) as jest.Mock<
typeof addressNormalizer
>;
const mockedHexSequenceNormalizer = (hexSequenceNormalizer as unknown) as jest.Mock<
typeof hexSequenceNormalizer
>;
const mockedComputeAddress = (computeAddress as unknown) as jest.Mock<
typeof computeAddress
>;
const mockedAddressNormalizer = jestMocked(addressNormalizer);
const mockedHexSequenceNormalizer = jestMocked(hexSequenceNormalizer);
const mockedComputeAddress = jestMocked(computeAddress);

/*
* Common values
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { derivationPathSerializer } from '@colony/purser-core/helpers';

jest.dontMock('@colony/purser-core/helpers');
import { derivationPathSerializer } from '../../src/helpers';

describe('`Core` Module', () => {
describe('`derivationPathSerializer()` helper', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
import { messageVerificationObjectValidator } from '@colony/purser-core/helpers';
import {
hexSequenceValidator,
messageValidator,
} from '@colony/purser-core/validators';
import { hexSequenceNormalizer } from '@colony/purser-core/normalizers';
import { jestMocked } from '../../../testutils';

jest.dontMock('@colony/purser-core/helpers');
import { messageVerificationObjectValidator } from '../../src/helpers';
import { hexSequenceValidator, messageValidator } from '../../src/validators';
import { hexSequenceNormalizer } from '../../src/normalizers';

jest.mock('@colony/purser-core/validators');
/*
* @TODO Fix manual mocks
* This is needed since Jest won't see our manual mocks (because of our custom monorepo structure)
* and will replace them with automatic ones
*/
jest.mock('@colony/purser-core/normalizers', () =>
require('@mocks/purser-core/normalizers.js'),
);
jest.mock('../../src/validators');
jest.mock('../../src/normalizers');

const mockedHexSequenceValidator = jestMocked(hexSequenceValidator);
const mockedHexSequenceNormalizer = jestMocked(hexSequenceNormalizer);
const mockedMessageValidator = jestMocked(messageValidator);
/*
* These values are not correct. Do not use the as reference.
* If the validators wouldn't be mocked, they wouldn't pass.
Expand All @@ -31,9 +24,9 @@ const mockedMessageObject = {
describe('`Core` Module', () => {
describe('`messageVerificationObjectValidator()` helper', () => {
afterEach(() => {
hexSequenceValidator.mockClear();
messageValidator.mockClear();
hexSequenceNormalizer.mockClear();
mockedHexSequenceValidator.mockClear();
mockedMessageValidator.mockClear();
mockedHexSequenceNormalizer.mockClear();
});
test("Validates only the signature's object values", async () => {
messageVerificationObjectValidator(mockedMessageObject);
Expand Down Expand Up @@ -71,13 +64,12 @@ describe('`Core` Module', () => {
*
* See:https://jestjs.io/docs/en/mock-function-api.html#mockfnmockrestore
*/
messageValidator.mockImplementation(value => {
if (!value) {
throw new Error();
}
return true;
mockedMessageValidator.mockImplementationOnce(() => {
throw new Error();
});
expect(() => messageVerificationObjectValidator()).toThrow();
expect(() =>
messageVerificationObjectValidator({ message: '', signature: '' }),
).toThrow();
});
});
});
Original file line number Diff line number Diff line change
@@ -1,41 +1,26 @@
import { hashPersonalMessage, ecrecover } from 'ethereumjs-util';

import { recoverPublicKey } from '@colony/purser-core/helpers';
import { jestMocked } from '../../../testutils';
import { recoverPublicKey } from '../../src/helpers';
import {
hexSequenceNormalizer,
recoveryParamNormalizer,
} from '@colony/purser-core/normalizers';
} from '../../src/normalizers';

import { HEX_HASH_TYPE } from '@colony/purser-core/defaults';

jest.dontMock('@colony/purser-core/helpers');
import { HEX_HASH_TYPE } from '../../src/defaults';

jest.mock('ethereumjs-util');
/*
* @TODO Fix manual mocks
* This is needed since Jest won't see our manual mocks (because of our custom monorepo structure)
* and will replace them with automatic ones
*/
jest.mock('@colony/purser-core/normalizers', () =>
require('@mocks/purser-core/normalizers.js'),
);

/*
* These values are not correct. Do not use the as reference.
* If the validators wouldn't be mocked, they wouldn't pass.
*/
jest.mock('../../src/normalizers');

/*
* Mocking a returned Buffer here
*/
const recoveredPublicKey = 'recovered-mocked-public-key';
const recoveredPublicKeyBuffer = {
toString: () => recoveredPublicKey,
};
const message = 'mocked-message';
const recoveredPublicKeyBuffer = Buffer.from(recoveredPublicKey);
const message = 'Hello, world!';
const invalidsignature = '0';
const validSignature =
'00000000000000000000000000000000000000000000000000000000000000000';
'f0445266ddd86f7d043dc1f538fe0b2fda271555af4ab5951ed84ec999e2d14e65829d0a66b34bcb752635e9ecd668e509622f9d91e7640958701208a13338e61c';
const signatureObject = {
message,
signature: validSignature,
Expand All @@ -44,17 +29,21 @@ const signatureObject = {
/*
* Mock the Buffer global object
*/
global.Buffer = {
from: jest.fn(value => value),
alloc: jest.fn(value => '0'.repeat(value)),
};
jest.spyOn(global.Buffer, 'from');
jest.spyOn(global.Buffer, 'alloc');
const mockedBufferFrom = jestMocked(global.Buffer.from);
const mockedBufferAlloc = jestMocked(global.Buffer.alloc);
const mockedHexSequenceNormalizer = jestMocked(hexSequenceNormalizer);
const mockedRecoveryParamNormalizer = jestMocked(recoveryParamNormalizer);
const mockedEcrecover = jestMocked(ecrecover);

describe('`Core` Module', () => {
describe('`recoverPublicKey()` helper', () => {
afterEach(() => {
global.Buffer.from.mockClear();
global.Buffer.alloc.mockClear();
hexSequenceNormalizer.mockClear();
mockedBufferFrom.mockClear();
mockedBufferAlloc.mockClear();
mockedHexSequenceNormalizer.mockClear();
mockedRecoveryParamNormalizer.mockClear();
});
test('Normalizes the signature and makes it a Buffer', async () => {
recoverPublicKey(signatureObject);
Expand Down Expand Up @@ -95,49 +84,54 @@ describe('`Core` Module', () => {
* Calls the normalizer
*/
expect(recoveryParamNormalizer).toHaveBeenCalled();
expect(recoveryParamNormalizer).toHaveBeenCalledWith(validSignature[64]);
expect(recoveryParamNormalizer).toHaveBeenCalledWith(
Buffer.from(validSignature, HEX_HASH_TYPE)[64],
);
});
test('Creates a hash of the message value', async () => {
recoverPublicKey(signatureObject);
/*
* Calls the `ethereumjs-util` `hashPersonalMessage` method
*/
expect(hashPersonalMessage).toHaveBeenCalled();
expect(hashPersonalMessage).toHaveBeenCalledWith(message);
expect(hashPersonalMessage).toHaveBeenCalledWith(Buffer.from(message));
});
test('Recovers the public key', async () => {
recoverPublicKey(signatureObject);
/*
* Calls the `ethereumjs-util` `ecrecover` method
*/
expect(ecrecover).toHaveBeenCalled();
expect(ecrecover).toHaveBeenCalledWith(
expect(mockedEcrecover).toHaveBeenCalled();
expect(mockedEcrecover).toHaveBeenCalledWith(
/*
* Message hash (as a hex Buffer)
*/
message,
Buffer.from(message),
/*
* Recovery param
*/
validSignature[64],
Buffer.from(validSignature, HEX_HASH_TYPE)[64],
/*
* R signature component (which is the first 32 bits of the signature)
*/
validSignature.slice(0, 32),
Buffer.from(validSignature, HEX_HASH_TYPE).slice(0, 32),
/*
* S signature component (which is the last 32 bits of the signature)
*/
validSignature.slice(32, 64),
Buffer.from(validSignature, HEX_HASH_TYPE).slice(32, 64),
);
});
test('Normalizes the recovered public key before returning', async () => {
ecrecover.mockImplementation(() => recoveredPublicKeyBuffer);
mockedEcrecover.mockImplementation(() => recoveredPublicKeyBuffer);
recoverPublicKey(signatureObject);
/*
* Normalizes the value before returning (also adds the `0x` prefix)
*/
expect(hexSequenceNormalizer).toHaveBeenCalled();
expect(hexSequenceNormalizer).nthCalledWith(2, recoveredPublicKey);
expect(hexSequenceNormalizer).nthCalledWith(
2,
Buffer.from(recoveredPublicKey).toString(HEX_HASH_TYPE),
);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,36 +1,34 @@
import { transactionObjectValidator } from '@colony/purser-core/helpers';
import { jestMocked } from '../../../testutils';

import { transactionObjectValidator } from '../../src/helpers';
import {
bigNumberValidator,
safeIntegerValidator,
addressValidator,
hexSequenceValidator,
} from '@colony/purser-core/validators';
import { bigNumber } from '@colony/purser-core/utils';

import { TRANSACTION } from '@colony/purser-core/defaults';
} from '../../src/validators';
import { bigNumber } from '../../src/utils';
import { TRANSACTION } from '../../src/defaults';

jest.dontMock('@colony/purser-core/helpers');
jest.mock('../../src/validators');
jest.mock('../../src/utils');

jest.mock('@colony/purser-core/validators');
/*
* @TODO Fix manual mocks
* This is needed since Jest won't see our manual mocks (because of our custom monorepo structure)
* and will replace them with automatic ones
*/
jest.mock('@colony/purser-core/utils', () =>
require('@mocks/purser-core/utils.js'),
);
const mockedBigNumberValidator = jestMocked(bigNumberValidator);
const mockedSafeIntegerValidator = jestMocked(safeIntegerValidator);
const mockedAddressValidator = jestMocked(addressValidator);
const mockedHexSequenceValidator = jestMocked(hexSequenceValidator);
const mockedBigNumber = jestMocked(bigNumber);

/*
* These values are not correct. Do not use the as reference.
* If the validators wouldn't be mocked, they wouldn't pass.
*/
const derivationPath = 'mocked-derivation-path';
const chainId = 'mocked-chain-id';
const chainId = 1337;
const inputData = 'mocked-data';
const gasLimit = 'mocked-gas-limit';
const gasPrice = 'mocked-gas-price';
const nonce = 'mocked-nonce';
const nonce = 7;
const to = 'mocked-destination-address';
const value = 'mocked-transaction-value';
const mockedTransactionObject = {
Expand All @@ -47,11 +45,11 @@ const mockedTransactionObject = {
describe('`Core` Module', () => {
describe('`transactionObjectValidator()` helper', () => {
afterEach(() => {
bigNumberValidator.mockClear();
safeIntegerValidator.mockClear();
addressValidator.mockClear();
hexSequenceValidator.mockClear();
bigNumber.mockClear();
mockedBigNumberValidator.mockClear();
mockedSafeIntegerValidator.mockClear();
mockedAddressValidator.mockClear();
mockedHexSequenceValidator.mockClear();
mockedBigNumber.mockClear();
});
test("Validates all the transaction's object values", async () => {
transactionObjectValidator(mockedTransactionObject);
Expand Down Expand Up @@ -100,7 +98,7 @@ describe('`Core` Module', () => {
expect(validatedTransactionObject).toHaveProperty('inputData');
});
test('Has defaults for all object values (except for `to`)', async () => {
bigNumber.mockImplementation(number => number);
mockedBigNumber.mockImplementation(number => number);
const validatedTransactionObject = transactionObjectValidator();
expect(validatedTransactionObject).toHaveProperty(
'gasPrice',
Expand Down Expand Up @@ -129,7 +127,6 @@ describe('`Core` Module', () => {
});
test('Validates destination (to), only if it was provided', async () => {
transactionObjectValidator({
derivationPath,
gasPrice,
gasLimit,
chainId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import { userInputValidator } from '@colony/purser-core/helpers';
import { warning } from '@colony/purser-core/utils';
import { jestMocked } from '../../../testutils';

jest.dontMock('@colony/purser-core/helpers');
import { userInputValidator } from '../../src/helpers';
import { warning } from '../../src/utils';

/*
* @TODO Fix manual mocks
* This is needed since Jest won't see our manual mocks (because of our custom monorepo structure)
* and will replace them with automatic ones
*/
jest.mock('@colony/purser-core/utils', () =>
require('@mocks/purser-core/utils.js'),
);
jest.mock('../../src/utils');

const mockedWarning = jestMocked(warning);

/*
* These values are not correct. Do not use the as reference.
Expand All @@ -25,7 +20,7 @@ const mockedArgument = {
describe('`Core` Module', () => {
describe('`userInputValidator()` helper', () => {
afterEach(() => {
warning.mockClear();
mockedWarning.mockClear();
});
test('Continues operation if first argument is an Object', () => {
/*
Expand Down
Loading

0 comments on commit 3db0578

Please sign in to comment.