diff --git a/.changeset/little-cherries-judge.md b/.changeset/little-cherries-judge.md new file mode 100644 index 00000000..a845151c --- /dev/null +++ b/.changeset/little-cherries-judge.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/src/verification/EventVerifier.ts b/src/verification/EventVerifier.ts index 81c8269b..19d7a0c0 100644 --- a/src/verification/EventVerifier.ts +++ b/src/verification/EventVerifier.ts @@ -6,6 +6,7 @@ import { ChainMinimumFee } from '@rosen-bridge/minimum-fee'; import EventBoxes from '../event/EventBoxes'; import { ConfirmedEventEntity } from '../db/entities/ConfirmedEventEntity'; import { EventStatus } from '../utils/constants'; +import EventSynchronization from '../synchronization/EventSynchronization'; class EventVerifier { /** @@ -76,7 +77,15 @@ class EventVerifier { type === TransactionType.reward ) return true; - else return false; + else { + if ( + eventEntity.status === EventStatus.pendingPayment && + type === TransactionType.reward + ) { + EventSynchronization.getInstance().addEventToQueue(eventEntity.id); + } + return false; + } }; } diff --git a/tests/synchronization/mocked/EventSynchronization.mock.ts b/tests/synchronization/mocked/EventSynchronization.mock.ts new file mode 100644 index 00000000..ce76e142 --- /dev/null +++ b/tests/synchronization/mocked/EventSynchronization.mock.ts @@ -0,0 +1,46 @@ +import { Mock } from 'vitest'; +import EventSynchronization from '../../../src/synchronization/EventSynchronization'; + +class EventSynchronizationMock { + private static mockedEventSynchronization: Record; + + /** + * resets all mocked functions of EventSynchronization + */ + static resetMock = () => { + this.mockedEventSynchronization = {}; + }; + + /** + * mocks EventSynchronization.getInstance to return mocked object + */ + static mock = () => { + const functionSpy = vi.spyOn(EventSynchronization, 'getInstance'); + functionSpy.mockReturnValue( + this.mockedEventSynchronization as EventSynchronization + ); + }; + + /** + * mocks EventSynchronization.addEventToQueue + */ + static mockAddEventToQueue = () => { + this.mockedEventSynchronization.addEventToQueue = vi.fn(); + const functionSpy = vi.spyOn( + this.mockedEventSynchronization, + 'addEventToQueue' + ); + functionSpy.mockImplementation(() => null); + }; + + /** + * returns vitest mock object of the corresponding function + * @param name function name + * @returns the mock object + */ + static getMockedFunction = (name: string): Mock => { + return this.mockedEventSynchronization[name]; + }; +} + +export default EventSynchronizationMock; diff --git a/tests/verification/EventVerifier.spec.ts b/tests/verification/EventVerifier.spec.ts index 86b69deb..18017f90 100644 --- a/tests/verification/EventVerifier.spec.ts +++ b/tests/verification/EventVerifier.spec.ts @@ -10,6 +10,8 @@ import DatabaseActionMock from '../db/mocked/DatabaseAction.mock'; import { ChainMinimumFee } from '@rosen-bridge/minimum-fee'; import { ConfirmedEventEntity } from '../../src/db/entities/ConfirmedEventEntity'; import { EventStatus } from '../../src/utils/constants'; +import EventSynchronizationMock from '../synchronization/mocked/EventSynchronization.mock'; +import TestUtils from '../testUtils/TestUtils'; describe('EventVerifier', () => { describe('isEventConfirmedEnough', () => { @@ -265,6 +267,11 @@ describe('EventVerifier', () => { }); describe('isEventPendingToType', () => { + beforeEach(async () => { + EventSynchronizationMock.resetMock(); + EventSynchronizationMock.mock(); + }); + /** * @target EventVerifier.isEventPendingToType should return true when * type is payment and event status is pending-payment @@ -331,8 +338,41 @@ describe('EventVerifier', () => { it('should return false when type and event status are not compatible', async () => { // mock an event const mockedEvent = new ConfirmedEventEntity(); + mockedEvent.status = EventStatus.timeout; + + // run test + const result = EventVerifier.isEventPendingToType( + mockedEvent, + TransactionType.reward + ); + + // verify returned value + expect(result).toEqual(false); + }); + + /** + * @target EventVerifier.isEventPendingToType should return false and add + * event to synchronization queue when a reward transaction for a pending-payment + * event is received + * @dependencies + * @scenario + * - mock an event with `pending-payment` status + * - mock EventSynchronization.addEventToQueue + * - run test with `reward` transaction type + * - verify returned value + * @expected + * - returned value should be false + * - `addEventToQueue` should got called with the mocked event id + */ + it('should return false and add event to synchronization queue when a reward transaction for a pending-payment event is received', async () => { + // mock an event + const mockedEvent = new ConfirmedEventEntity(); + mockedEvent.id = TestUtils.generateRandomId(); mockedEvent.status = EventStatus.pendingPayment; + // mock EventSynchronization.addEventToQueue + EventSynchronizationMock.mockAddEventToQueue(); + // run test const result = EventVerifier.isEventPendingToType( mockedEvent, @@ -341,6 +381,11 @@ describe('EventVerifier', () => { // verify returned value expect(result).toEqual(false); + + // `addEventToQueue` should got called + expect( + EventSynchronizationMock.getMockedFunction('addEventToQueue') + ).toHaveBeenCalledWith(mockedEvent.id); }); }); });