diff --git a/packages/web3-eth-abi/src/AbiCoder.js b/packages/web3-eth-abi/src/AbiCoder.js index d8021a95f2d..60eefe63b23 100644 --- a/packages/web3-eth-abi/src/AbiCoder.js +++ b/packages/web3-eth-abi/src/AbiCoder.js @@ -296,14 +296,16 @@ export default class AbiCoder { const nonIndexedData = data; - const notIndexedParams = nonIndexedData ? this.decodeParameters(notIndexedInputs.filter(Boolean), nonIndexedData) : []; + const notIndexedParams = nonIndexedData + ? this.decodeParameters(notIndexedInputs.filter(Boolean), nonIndexedData) + : []; let notIndexedOffset = 0; const returnValues = {}; inputs.forEach((res, i) => { if (res.indexed) notIndexedOffset++; - + returnValues[i] = res.type === 'string' ? '' : null; if (!res.indexed && typeof notIndexedParams[i - notIndexedOffset] !== 'undefined') { diff --git a/packages/web3-eth-contract/src/AbstractContract.js b/packages/web3-eth-contract/src/AbstractContract.js index a2d2ada1652..7204fa8410a 100644 --- a/packages/web3-eth-contract/src/AbstractContract.js +++ b/packages/web3-eth-contract/src/AbstractContract.js @@ -159,16 +159,22 @@ export default class AbstractContract extends AbstractWeb3Module { */ getPastEvents(eventName, options, callback) { return new Promise(async (resolve, reject) => { - if (!this.abiModel.hasEvent(eventName)) { - reject(new Error(`Event with name "${eventName}" does not exists.`)); - } + let method; + + if (eventName !== 'allEvents') { + if (!this.abiModel.hasEvent(eventName)) { + reject(new Error(`Event with name "${eventName}" does not exists.`)); + } - const pastEventLogsMethod = this.methodFactory.createPastEventLogsMethod(this.abiModel.getEvent(eventName)); + method = this.methodFactory.createPastEventLogsMethod(this.abiModel.getEvent(eventName)); + } else { + method = this.methodFactory.createAllPastEventLogsMethod(this.abiModel); + } - pastEventLogsMethod.parameters = [options]; - pastEventLogsMethod.callback = callback; + method.parameters = [options]; + method.callback = callback; - return resolve(await pastEventLogsMethod.execute(this)); + return resolve(await method.execute(this)); }); } diff --git a/packages/web3-eth-contract/src/factories/MethodFactory.js b/packages/web3-eth-contract/src/factories/MethodFactory.js index f0662ee76f7..4a045f25202 100644 --- a/packages/web3-eth-contract/src/factories/MethodFactory.js +++ b/packages/web3-eth-contract/src/factories/MethodFactory.js @@ -23,6 +23,7 @@ import CallContractMethod from '../methods/CallContractMethod'; import ContractDeployMethod from '../methods/ContractDeployMethod'; import PastEventLogsMethod from '../methods/PastEventLogsMethod'; +import AllPastEventLogsMethod from '../methods/AllPastEventLogsMethod'; import SendContractMethod from '../methods/SendContractMethod'; import {EstimateGasMethod} from 'web3-core-method'; @@ -100,6 +101,24 @@ export default class MethodFactory { ); } + /** + * Returns an object of type PastEventLogsMethod + * + * @method createPastEventLogsMethod + * + * @param {AbiModel} abiModel + * + * @returns {AllPastEventLogsMethod} + */ + createAllPastEventLogsMethod(abiModel) { + return new AllPastEventLogsMethod( + this.utils, + this.formatters, + this.contractModuleFactory.createAllEventsLogDecoder(), + abiModel + ); + } + /** * Returns an object of type CallContractMethod * diff --git a/packages/web3-eth-contract/src/methods/AllPastEventLogsMethod.js b/packages/web3-eth-contract/src/methods/AllPastEventLogsMethod.js new file mode 100644 index 00000000000..07108f9621c --- /dev/null +++ b/packages/web3-eth-contract/src/methods/AllPastEventLogsMethod.js @@ -0,0 +1,56 @@ +/* + This file is part of web3.js. + + web3.js is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + web3.js is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with web3.js. If not, see . +*/ +/** + * @file AllPastEventLogsMethod.js + * @author Samuel Furter + * @date 2018 + */ + +import {GetPastLogsMethod} from 'web3-core-method'; + +export default class AllPastEventLogsMethod extends GetPastLogsMethod { + /** + * @param {Utils} utils + * @param {Object} formatters + * @param {AllEventsLogDecoder} eventLogDecoder + * @param {AbiModel} abiModel + * + * @constructor + */ + constructor(utils, formatters, allEventsLogDecoder, abiModel) { + super(utils, formatters); + this.abiModel = abiModel; + this.allEventsLogDecoder = allEventsLogDecoder; + } + + /** + * This method will be executed after the RPC request. + * + * @method afterExecution + * + * @param {Array} response + * + * @returns {Array} + */ + afterExecution(response) { + const formattedLogs = super.afterExecution(response); + + return formattedLogs.map((logItem) => { + return this.allEventsLogDecoder.decode(this.abiModel, logItem); + }); + } +} diff --git a/packages/web3-eth-contract/tests/src/AbstractContractTest.js b/packages/web3-eth-contract/tests/src/AbstractContractTest.js index 2920fbc6570..817e8b3422d 100644 --- a/packages/web3-eth-contract/tests/src/AbstractContractTest.js +++ b/packages/web3-eth-contract/tests/src/AbstractContractTest.js @@ -236,6 +236,25 @@ describe('AbstractContractTest', () => { expect(getPastLogsMethodMock.callback).toBeInstanceOf(Function); }); + it('calls getPastEvents with "allEvents" and returns a resolved promise', async () => { + new GetPastLogsMethod(); + const getPastLogsMethodMock = GetPastLogsMethod.mock.instances[0]; + + getPastLogsMethodMock.execute.mockReturnValueOnce(Promise.resolve(true)); + + methodFactoryMock.createAllPastEventLogsMethod.mockReturnValueOnce(getPastLogsMethodMock); + + await expect(abstractContract.getPastEvents('allEvents', {}, () => {})).resolves.toEqual(true); + + expect(getPastLogsMethodMock.execute).toHaveBeenCalledWith(abstractContract); + + expect(methodFactoryMock.createAllPastEventLogsMethod).toHaveBeenCalledWith(abiModelMock); + + expect(getPastLogsMethodMock.parameters).toEqual([{}]); + + expect(getPastLogsMethodMock.callback).toBeInstanceOf(Function); + }); + it('calls getPastEvents and returns a rejected promise', async () => { abiModelMock.hasEvent.mockReturnValueOnce(false); diff --git a/packages/web3-eth-contract/tests/src/factories/MethodFactoryTest.js b/packages/web3-eth-contract/tests/src/factories/MethodFactoryTest.js index adfd64f2e33..a81f56413a8 100644 --- a/packages/web3-eth-contract/tests/src/factories/MethodFactoryTest.js +++ b/packages/web3-eth-contract/tests/src/factories/MethodFactoryTest.js @@ -10,6 +10,7 @@ import CallContractMethod from '../../../src/methods/CallContractMethod'; import SendContractMethod from '../../../src/methods/SendContractMethod'; import ContractDeployMethod from '../../../src/methods/ContractDeployMethod'; import PastEventLogsMethod from '../../../src/methods/PastEventLogsMethod'; +import AllPastEventLogsMethod from '../../../src/methods/AllPastEventLogsMethod'; // Mocks jest.mock('Accounts'); @@ -23,6 +24,7 @@ jest.mock('../../../src/methods/CallContractMethod'); jest.mock('../../../src/methods/SendContractMethod'); jest.mock('../../../src/methods/ContractDeployMethod'); jest.mock('../../../src/methods/PastEventLogsMethod'); +jest.mock('../../../src/methods/AllPastEventLogsMethod'); /** * MethodFactory test @@ -97,6 +99,12 @@ describe('MethodFactoryTest', () => { expect(contractModuleFactoryMock.createEventLogDecoder).toHaveBeenCalled(); }); + it('calls createAllPastEventLogsMethod and returns PastEventLogsMethod object', () => { + expect(methodFactory.createAllPastEventLogsMethod({})).toBeInstanceOf(AllPastEventLogsMethod); + + expect(contractModuleFactoryMock.createAllEventsLogDecoder).toHaveBeenCalled(); + }); + it('calls createCallContractMethod and returns CallContractMethod object', () => { expect(methodFactory.createCallContractMethod({})).toBeInstanceOf(CallContractMethod); }); diff --git a/packages/web3-eth-contract/tests/src/methods/AllPastEventLogsMethodTest.js b/packages/web3-eth-contract/tests/src/methods/AllPastEventLogsMethodTest.js new file mode 100644 index 00000000000..d1025d405af --- /dev/null +++ b/packages/web3-eth-contract/tests/src/methods/AllPastEventLogsMethodTest.js @@ -0,0 +1,59 @@ +import * as Utils from 'web3-utils'; +import {formatters} from 'web3-core-helpers'; +import {GetPastLogsMethod} from 'web3-core-method'; +import AllEventsLogDecoder from '../../../src/decoders/AllEventsLogDecoder'; +import AbiModel from '../../../src/models/AbiModel'; +import AllPastEventLogsMethod from '../../../src/methods/AllPastEventLogsMethod'; + +// Mocks +jest.mock('Utils'); +jest.mock('formatters'); +jest.mock('../../../src/decoders/AllEventsLogDecoder'); +jest.mock('../../../src/models/AbiModel'); + +/** + * AllPastEventLogsMethod test + */ +describe('AllPastEventLogsMethodTest', () => { + let allPastEventLogsMethod, allEventsLogDecoderMock, abiModelMock; + + beforeEach(() => { + new AllEventsLogDecoder(); + allEventsLogDecoderMock = AllEventsLogDecoder.mock.instances[0]; + + new AbiModel(); + abiModelMock = AbiModel.mock.instances[0]; + + allPastEventLogsMethod = new AllPastEventLogsMethod(Utils, formatters, allEventsLogDecoderMock, abiModelMock); + }); + + it('constructor check', () => { + expect(allPastEventLogsMethod.utils).toEqual(Utils); + + expect(allPastEventLogsMethod.formatters).toEqual(formatters); + + expect(allPastEventLogsMethod.allEventsLogDecoder).toEqual(allEventsLogDecoderMock); + + expect(allPastEventLogsMethod.abiModel).toEqual(abiModelMock); + + expect(allPastEventLogsMethod).toBeInstanceOf(GetPastLogsMethod); + }); + + it('calls afterExecution and returns the expected result', () => { + const response = [false, false, false]; + + formatters.outputLogFormatter.mockReturnValue(true); + + allEventsLogDecoderMock.decode.mockReturnValue('decoded'); + + const mappedResponse = allPastEventLogsMethod.afterExecution(response); + + expect(mappedResponse).toEqual(['decoded', 'decoded', 'decoded']); + + expect(formatters.outputLogFormatter).toHaveBeenCalledTimes(3); + + expect(allEventsLogDecoderMock.decode).toHaveBeenCalledTimes(3); + + expect(allEventsLogDecoderMock.decode).toHaveBeenCalledWith(abiModelMock, true); + }); +});