/** * Testkit for testing dealer BI events. * * Provides a singleton-style API similar to biTestkit from @wix/bex-core/bi/testkit. * Captures dealer reportEvent HTTP calls and provides utilities to assert on events. * * @example * ```typescript * import dealerBITestkit from '../test-utils/DealerBIMock'; * * describe('MyComponent', () => { * const setup = () => { * const driver = new MyDriver({ * httpMocks: [ * // ... other mocks * dealerBITestkit.httpMock, * ], * }); * return { driver }; * }; * * it('sends view event', async () => { * setup(); * // ... trigger the view event * * expect(dealerBITestkit.view.last()).toEqual( * expect.objectContaining({ * offerId: 'offer-1', * }), * ); * }); * }); * ``` */ import { whenRequest } from '@wix/yoshi-flow-bm/testkit/http-client'; import { reportEvent } from '@wix/bex-utils/@wix/ambassador-dealer-v1-offer-event/http'; import type { AnyScenario } from '@wix/http-client-testkit'; // Re-export EventType for convenience export { EventType } from '@wix/bex-utils/@wix/ambassador-dealer-v1-offer-event/types'; interface ReportEventData { event?: { type?: string; offerId?: string; realEstateId?: string; [key: string]: unknown; }; [key: string]: unknown; } interface EventTypeAccessor { /** Get all events of this type */ all: () => ReportEventData[]; /** Get the last event of this type */ last: () => ReportEventData | undefined; /** Get event count of this type */ count: () => number; } interface DealerBITestkit { /** The HTTP mock - add this to your driver's httpMocks array */ httpMock: AnyScenario; /** Access VIEW events */ view: EventTypeAccessor; /** Access MAIN_CTA_CLICK events */ mainCtaClick: EventTypeAccessor; /** Get all captured events (any type) */ all: () => ReportEventData[]; /** Get the last captured event (any type) */ last: () => ReportEventData | undefined; /** Clear all captured events - call in beforeEach for test isolation */ clear: () => void; } // Singleton spy to capture all events const eventsSpy = jest.fn(); // Create HTTP mock once const httpMock = whenRequest(reportEvent) .reply(async (data) => { eventsSpy(data); return { status: 200, data: {} }; }) .persist() as AnyScenario; const _getAllEventsOfType = (type?: string): ReportEventData[] => type ? eventsSpy.mock.calls .filter((call) => call[0]?.event?.type === type) .map((call) => call[0]) : eventsSpy.mock.calls.map((call) => call[0]); const createEventTypeAccessor = (type: string): EventTypeAccessor => ({ all: () => _getAllEventsOfType(type), last: () => { const events = _getAllEventsOfType(type); return events.length > 0 ? events[events.length - 1] : undefined; }, count: () => _getAllEventsOfType(type).length, }); const dealerBITestkit: DealerBITestkit = { httpMock, view: createEventTypeAccessor('VIEW'), mainCtaClick: createEventTypeAccessor('MAIN_CTA_CLICK'), all: _getAllEventsOfType, last: () => { const events = _getAllEventsOfType(); return events.length > 0 ? events[events.length - 1] : undefined; }, clear: () => eventsSpy.mockClear(), }; export default dealerBITestkit; // Also export named for flexibility export { dealerBITestkit };