diff --git a/codecov.yml b/codecov.yml index c80b88db171..04c1e91d8e5 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,3 +1,5 @@ +ignore: + - "./packages/web3-core/src/formatters.ts" # ignore deprecated formatters from coverage report coverage: status: project: @@ -75,4 +77,4 @@ comment: behavior: 'default' require_changes: false require_base: no - require_head: no \ No newline at end of file + require_head: no diff --git a/packages/web3-core/src/web3_config.ts b/packages/web3-core/src/web3_config.ts index 11e80a843b1..772653cfdeb 100644 --- a/packages/web3-core/src/web3_config.ts +++ b/packages/web3-core/src/web3_config.ts @@ -104,7 +104,7 @@ export abstract class Web3Config // TODO: Improve and add key check const keys = Object.keys(options) as (keyof Web3ConfigOptions)[]; for (const key of keys) { - this._triggerConfigChange(key, options[key]) + this._triggerConfigChange(key, options[key]); } Object.assign(this.config, options); } diff --git a/packages/web3-core/src/web3_request_manager.ts b/packages/web3-core/src/web3_request_manager.ts index df12bc5b13d..c995edfbd20 100644 --- a/packages/web3-core/src/web3_request_manager.ts +++ b/packages/web3-core/src/web3_request_manager.ts @@ -187,11 +187,11 @@ export class Web3RequestManager< 'Provider not available. Use `.setProvider` or `.provider=` to initialize the provider.', ); } - + const payload = jsonRpc.isBatchRequest(request) - ? jsonRpc.toBatchPayload(request) + ? jsonRpc.toBatchPayload(request) : jsonRpc.toPayload(request); - + if (isWeb3Provider(provider)) { let response; @@ -292,7 +292,7 @@ export class Web3RequestManager< if (isNullish(response)) { throw new ResponseError( - '' as never, + {} as never, 'Got a "nullish" response from provider.', ); } diff --git a/packages/web3-core/test/unit/formatters.test.ts b/packages/web3-core/test/unit/formatters.test.ts index d1aedd01d71..105fb4fcf45 100644 --- a/packages/web3-core/test/unit/formatters.test.ts +++ b/packages/web3-core/test/unit/formatters.test.ts @@ -23,6 +23,7 @@ import { inputBlockNumberFormatter, inputDefaultBlockNumberFormatter, inputPostFormatter, + inputTopicFormatter, outputBigIntegerFormatter, outputBlockFormatter, outputLogFormatter, @@ -82,6 +83,17 @@ describe('formatters', () => { }); }); + describe('inputTopicFormatter', () => { + it('check params', () => { + expect(inputTopicFormatter('0x09d7bD9E185fbC2d265D8DBe81e5e888E391688b')).toBe( + '0x09d7bD9E185fbC2d265D8DBe81e5e888E391688b', + ); + // @ts-expect-error invalid param + // eslint-disable-next-line no-null/no-null + expect(inputTopicFormatter(null)).toBeNull(); + }); + }); + describe('outputBigIntegerFormatter', () => { it('should convert input to number', () => { const result = outputBigIntegerFormatter(BigInt(12)); @@ -320,6 +332,12 @@ describe('formatters', () => { describe('outputTransactionReceiptFormatter', () => { const validReceipt = { cumulativeGasUsed: '0x1234', gasUsed: '0x4567' }; + it('should be FormatterError', () => { + // @ts-expect-error invalid param + expect(() => outputTransactionReceiptFormatter(1)).toThrow( + `Received receipt is invalid: 1`, + ); + }); it('should convert "blockNumber" from hex to number', () => { const result = outputTransactionReceiptFormatter({ ...validReceipt, @@ -381,6 +399,11 @@ describe('formatters', () => { expect(result.logs).toEqual(['outputLogFormatterResult', 'outputLogFormatterResult']); }); + it('when log doesn`t have id', () => { + const res = formatters.outputLogFormatter({ blockHash: '0x1', logIndex: '0x1' }); + expect(res.id).toBeUndefined(); + }); + it('should convert "contractAddress" to checksum address', () => { const result = outputTransactionReceiptFormatter({ ...validReceipt, diff --git a/packages/web3-core/test/unit/web3_batch_request.test.ts b/packages/web3-core/test/unit/web3_batch_request.test.ts index cc861276a5f..53e12cfe782 100644 --- a/packages/web3-core/test/unit/web3_batch_request.test.ts +++ b/packages/web3-core/test/unit/web3_batch_request.test.ts @@ -39,9 +39,11 @@ describe('Web3BatchRequest', () => { }); describe('constructor', () => { - it('should create batch request object with empty list of requests', () => { + it('should create batch request object with empty list of requests', async () => { expect(batchRequest).toBeInstanceOf(Web3BatchRequest); expect(batchRequest.requests).toEqual([]); + expect(batchRequest.requests).toHaveLength(0); + expect(await batchRequest.execute()).toEqual([]); }); }); diff --git a/packages/web3-core/test/unit/web3_config.test.ts b/packages/web3-core/test/unit/web3_config.test.ts index 121e5cb94cf..32a5fc17ddc 100644 --- a/packages/web3-core/test/unit/web3_config.test.ts +++ b/packages/web3-core/test/unit/web3_config.test.ts @@ -105,6 +105,22 @@ describe('Web3Config', () => { }, ); + it('set default chain error', () => { + const obj = new MyConfigObject(); + + obj.setConfig({ + // @ts-expect-error incorrect object + defaultCommon: { + baseChain: 'mainnet', + }, + }); + expect(() => { + obj.defaultChain = 'test'; + }).toThrow( + 'Web3Config chain doesnt match in defaultHardfork mainnet and common.hardfork test', + ); + }); + it('Updating transactionPollingInterval should update transactionReceiptPollingInterval and transactionConfirmationPollingInterval', () => { const obj = new MyConfigObject(); const configChange = jest.fn(); diff --git a/packages/web3-core/test/unit/web3_promi_event.test.ts b/packages/web3-core/test/unit/web3_promi_event.test.ts index d41372a0377..1f597505939 100644 --- a/packages/web3-core/test/unit/web3_promi_event.test.ts +++ b/packages/web3-core/test/unit/web3_promi_event.test.ts @@ -24,6 +24,7 @@ describe('Web3PromiEvent', () => { }); await expect(p).resolves.toBe('Resolved Value'); + expect(() => p.removeAllListeners()).not.toThrow(); }); it('should initialize and reject promise', async () => { @@ -69,12 +70,16 @@ describe('Web3PromiEvent', () => { }; const p = func(); - - // eslint-disable-next-line no-void - void p.on('data', data => { + const eventFunc = (data: string) => { expect(data).toBe('emitted data'); done(undefined); - }); + expect(() => p.off('data', eventFunc)).not.toThrow(); + }; + // eslint-disable-next-line no-void + void p.on('data', eventFunc); + expect(p.listenerCount('data')).toBe(1); + expect(p.listeners('data')).toHaveLength(1); + expect(p.eventNames()).toEqual(['data']); }); }); @@ -122,4 +127,27 @@ describe('Web3PromiEvent', () => { expect(p.getMaxListeners()).toBe(3); }); + + it('finally', async () => { + const p = new Web3PromiEvent(resolve => { + return resolve('reason'); + }); + + const f = jest.fn(); + p.finally(f); + await p; + expect(f).toHaveBeenCalled(); + }); + it('catch', async () => { + const f = jest.fn(); + const p = new Web3PromiEvent((_, reject) => { + return reject(new Error('reason')); + }); + + p.catch(f); + + await expect(p).rejects.toThrow('reason'); + + expect(f).toHaveBeenCalledWith(new Error('reason')); + }); }); diff --git a/packages/web3-core/test/unit/web3_request_manager.test.ts b/packages/web3-core/test/unit/web3_request_manager.test.ts index bbd6dec6698..21483ef13a2 100644 --- a/packages/web3-core/test/unit/web3_request_manager.test.ts +++ b/packages/web3-core/test/unit/web3_request_manager.test.ts @@ -66,7 +66,31 @@ describe('Web3RequestManager', () => { expect(manager).toBeInstanceOf(Web3RequestManager); }); }); + describe('isMetaMaskProvider', () => { + it('check params', () => { + const request = { + constructor: { + name: 'AsyncFunction', + }, + }; + expect( + utils.isMetaMaskProvider({ + // @ts-expect-error incorrect param + request, + isMetaMask: true, + }), + ).toBe(true); + }); + }); + describe('isSupportSubscriptions', () => { + it('check params', () => { + // @ts-expect-error incorrect param + expect(utils.isSupportSubscriptions({ supportsSubscriptions: () => true })).toBe(true); + // @ts-expect-error incorrect param + expect(utils.isSupportSubscriptions({})).toBe(false); + }); + }); describe('providers', () => { it('should return providers on instance', () => { const manager = new Web3RequestManager(); @@ -97,6 +121,11 @@ describe('Web3RequestManager', () => { }); }); + it('should unset provider', () => { + const manager = new Web3RequestManager(); + manager.setProvider(undefined); + expect(manager.provider).toBeUndefined(); + }); it('should detect and set http provider', () => { const providerString = 'http://mydomain.com'; @@ -235,10 +264,44 @@ describe('Web3RequestManager', () => { it('should throw error if no provider is set', async () => { const manager = new Web3RequestManager(); - await expect(manager.send(request)).rejects.toThrow('Provider not available'); }); + it('promise of legacy provider should be resolved', async () => { + const manager = new Web3RequestManager(undefined, undefined); + const pr = new Promise(resolve => { + resolve('test'); + }); + const myProvider = { + request: jest.fn().mockImplementation(async () => pr), + } as any; + manager.setProvider(myProvider); + await manager.send(request); + expect(myProvider.request).toHaveBeenCalledTimes(1); + expect(await pr).toBe('test'); + }); + it('Got a "nullish" response from provider', async () => { + const manager = new Web3RequestManager(undefined, undefined); + const myProvider = { + send: jest.fn().mockImplementation((_, cb: (error?: any, data?: any) => void) => { + cb(undefined, undefined); + }), + } as any; + manager.setProvider(myProvider); + + await expect(async () => manager.send(request)).rejects.toThrow( + 'Got a "nullish" response from provider', + ); + }); + it('Provider does not have a request or send method to use', async () => { + const manager = new Web3RequestManager(undefined, undefined); + const myProvider = {} as any; + manager.setProvider(myProvider); + + await expect(async () => manager.send(request)).rejects.toThrow( + 'Provider does not have a request or send method to use.', + ); + }); describe('test rpc errors', () => { it('should pass request to provider and reject with a generic rpc error when rpc call specification flag is undefined', async () => { const parseErrorResponse = {