From b9a5a15d312d883099ade635a56e5504701d104e Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Fri, 22 Jan 2021 09:02:30 -0800 Subject: [PATCH 1/2] Add getListeners to Kea test helpers --- .../public/applications/__mocks__/kea.mock.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts index 78ffbcfa3526f..5ac8cce04181e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts @@ -120,4 +120,29 @@ export class LogicMounter { public unmount = () => { this.unmountFn(); }; + + /** + * Some tests (e.g. async tests, tests that expect thrown errors) need to access + * listener functions directly instead of calling `SomeLogic.actions.someListener`, + * due to how Kea invokes/wraps action fns by design. + * + * Example usage: + * + * const { mount, getListeners } = new LogicMounter(SomeLogic); + * + * it('some test', async () => { + * mount(); + * const { someListener } = getListeners({ values: { someMockValue: false } }); + * + * const mockBreakpoint = jest.fn(); + * await someListener({ someMockArgument: true }, mockBreakpoint); + * }); + */ + public getListeners = (listenersArgs: object = {}) => { + const { listeners } = this.logicFile.inputs[0]; + + return typeof listeners === 'function' + ? (listeners as Function)(listenersArgs) // e.g., listeners({ values, actions, props }) => ({ ... }) + : listeners; // handles simpler logic files that just define listeners: { ... } + }; } From f18af000195f23fd0a740752e75329db90e67637 Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Fri, 22 Jan 2021 09:11:04 -0800 Subject: [PATCH 2/2] Update TelemetryLogic to use new getListeners helper --- .../shared/telemetry/telemetry_logic.test.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts index 6d4e4f4fe649c..770dcf074f163 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts @@ -4,20 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; - import { JSON_HEADER as headers } from '../../../../common/constants'; -import { mockHttpValues } from '../../__mocks__/http_logic.mock'; +import { LogicMounter, mockHttpValues } from '../../__mocks__'; -import { TelemetryLogic } from './'; +import { TelemetryLogic } from './telemetry_logic'; describe('Telemetry logic', () => { + const { mount, getListeners } = new LogicMounter(TelemetryLogic); const { http } = mockHttpValues; beforeEach(() => { jest.clearAllMocks(); - resetContext({}); - TelemetryLogic.mount(); + mount(); }); describe('sendTelemetry', () => { @@ -36,11 +34,7 @@ describe('Telemetry logic', () => { it('throws an error if the telemetry endpoint fails', async () => { http.put.mockImplementationOnce(() => Promise.reject()); - - // To capture thrown errors, we have to call the listener fn directly - // instead of using `TelemetryLogic.actions.sendTelemetry` - this is - // due to how Kea invokes/wraps action fns by design. - const { sendTelemetry } = (TelemetryLogic.inputs[0] as any).listeners({ actions: {} }); + const { sendTelemetry } = getListeners(); await expect(sendTelemetry({ action: '', metric: '', product: '' })).rejects.toThrow( 'Unable to send telemetry'