[Enterprise Search] Kea mount test helper (#87247)

* Add Kea logic mount helper

* Update existing mount() helpers to use new DRY helper

* Add additional unmount helper + example test update
This commit is contained in:
Constance 2021-01-06 09:48:44 -08:00 committed by GitHub
parent a95fdbdec3
commit b4f3a15458
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 90 additions and 128 deletions

View file

@ -10,7 +10,13 @@ export { mockLicensingValues } from './licensing_logic.mock';
export { mockHttpValues } from './http_logic.mock';
export { mockTelemetryActions } from './telemetry_logic.mock';
export { mockFlashMessagesValues, mockFlashMessagesActions } from './flash_messages_logic.mock';
export { mockAllValues, mockAllActions, setMockValues, setMockActions } from './kea.mock';
export {
mockAllValues,
mockAllActions,
setMockValues,
setMockActions,
LogicMounter,
} from './kea.mock';
export { mountAsync } from './mount_async.mock';
export { mountWithIntl } from './mount_with_i18n.mock';

View file

@ -40,14 +40,18 @@ jest.mock('kea', () => ({
}));
/**
* Call this function to override a specific set of Kea values while retaining all other defaults
* Example usage within a component test:
* React component helpers
*
* import '../../../__mocks__/kea';
* import { setMockValues } from ''../../../__mocks__';
* Call this function to override a specific set of Kea values while retaining all other defaults
*
* Example usage:
*
* import { setMockValues } from '../../../__mocks__/kea.mock';
* import { SomeComponent } from './';
*
* it('some test', () => {
* setMockValues({ someValue: 'hello' });
* shallow(<SomeComponent />);
* });
*/
import { useValues, useActions } from 'kea';
@ -58,3 +62,62 @@ export const setMockValues = (values: object) => {
export const setMockActions = (actions: object) => {
(useActions as jest.Mock).mockImplementation(() => ({ ...mockAllActions, ...actions }));
};
/**
* Kea logic helpers
*
* Call this function to mount a logic file and optionally override default values.
* Automatically DRYs out a lot of cruft for us, such as resetting context, creating the
* nested defaults path obj (see https://kea.js.org/docs/api/context#resetcontext), and
* returning an unmount function
*
* Example usage:
*
* import { LogicMounter } from '../../../__mocks__/kea.mock';
* import { SomeLogic } from './';
*
* const { mount, unmount } = new LogicMounter(SomeLogic);
*
* it('some test', () => {
* mount({ someValue: 'hello' });
* unmount();
* });
*/
import { resetContext, Logic, LogicInput } from 'kea';
interface LogicFile {
inputs: Array<LogicInput<Logic>>;
mount(): Function;
}
export class LogicMounter {
private logicFile: LogicFile;
private unmountFn!: Function;
constructor(logicFile: LogicFile) {
this.logicFile = logicFile;
}
// Reset context with optional default value overrides
public resetContext = (values?: object) => {
if (!values) {
resetContext({});
} else {
const path = this.logicFile.inputs[0].path as string[]; // example: ['x', 'y', 'z']
const defaults = path.reduceRight((value: object, key: string) => ({ [key]: value }), values); // example: { x: { y: { z: values } } }
resetContext({ defaults });
}
};
// Automatically reset context & mount the logic file
public mount = (values?: object) => {
this.resetContext(values);
const unmount = this.logicFile.mount();
this.unmountFn = unmount;
return unmount; // Keep Kea behavior of returning an unmount fn from mount
};
// Also add unmount as a class method that can be destructured on init without becoming stale later
public unmount = () => {
this.unmountFn();
};
}

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { resetContext } from 'kea';
import { LogicMounter } from '../../../__mocks__/kea.mock';
import { mockHttpValues } from '../../../__mocks__';
jest.mock('../../../shared/http', () => ({
@ -57,24 +57,7 @@ describe('CredentialsLogic', () => {
fullEngineAccessChecked: false,
};
const mount = (defaults?: object) => {
if (!defaults) {
resetContext({});
} else {
resetContext({
defaults: {
enterprise_search: {
app_search: {
credentials_logic: {
...defaults,
},
},
},
},
});
}
CredentialsLogic.mount();
};
const { mount } = new LogicMounter(CredentialsLogic);
const newToken = {
id: 1,

View file

@ -4,7 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { resetContext } from 'kea';
import { LogicMounter } from '../../../__mocks__/kea.mock';
import dedent from 'dedent';
jest.mock('./utils', () => ({
@ -39,24 +40,7 @@ describe('DocumentCreationLogic', () => {
};
const mockFile = new File(['mockFile'], 'mockFile.json');
const mount = (defaults?: object) => {
if (!defaults) {
resetContext({});
} else {
resetContext({
defaults: {
enterprise_search: {
app_search: {
document_creation_logic: {
...defaults,
},
},
},
},
});
}
DocumentCreationLogic.mount();
};
const { mount } = new LogicMounter(DocumentCreationLogic);
beforeEach(() => {
jest.clearAllMocks();

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { resetContext } from 'kea';
import { LogicMounter } from '../../../__mocks__/kea.mock';
import { mockHttpValues } from '../../../__mocks__';
jest.mock('../../../shared/http', () => ({
@ -36,24 +36,7 @@ describe('DocumentDetailLogic', () => {
fields: [],
};
const mount = (defaults?: object) => {
if (!defaults) {
resetContext({});
} else {
resetContext({
defaults: {
enterprise_search: {
app_search: {
document_detail_logic: {
...defaults,
},
},
},
},
});
}
DocumentDetailLogic.mount();
};
const { mount } = new LogicMounter(DocumentDetailLogic);
beforeEach(() => {
jest.clearAllMocks();

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { resetContext } from 'kea';
import { LogicMounter } from '../../../__mocks__/kea.mock';
import { DocumentsLogic } from './documents_logic';
@ -13,24 +13,7 @@ describe('DocumentsLogic', () => {
isDocumentCreationOpen: false,
};
const mount = (defaults?: object) => {
if (!defaults) {
resetContext({});
} else {
resetContext({
defaults: {
enterprise_search: {
app_search: {
documents_logic: {
...defaults,
},
},
},
},
});
}
DocumentsLogic.mount();
};
const { mount } = new LogicMounter(DocumentsLogic);
describe('actions', () => {
describe('openDocumentCreation', () => {

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { resetContext } from 'kea';
import { LogicMounter } from '../../../__mocks__/kea.mock';
import { mockHttpValues } from '../../../__mocks__';
jest.mock('../../../shared/http', () => ({
@ -46,24 +46,7 @@ describe('EngineLogic', () => {
engineNotFound: false,
};
const mount = (values?: object) => {
if (!values) {
resetContext({});
} else {
resetContext({
defaults: {
enterprise_search: {
app_search: {
engine_logic: {
...values,
},
},
},
},
});
}
EngineLogic.mount();
};
const { mount } = new LogicMounter(EngineLogic);
beforeEach(() => {
jest.clearAllMocks();

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { resetContext } from 'kea';
import { LogicMounter } from '../../../__mocks__/kea.mock';
import { mockHttpValues } from '../../../__mocks__';
jest.mock('../../../shared/http', () => ({
@ -48,10 +48,7 @@ describe('EngineOverviewLogic', () => {
timeoutId: null,
};
const mount = () => {
resetContext({});
EngineOverviewLogic.mount();
};
const { mount, unmount } = new LogicMounter(EngineOverviewLogic);
beforeEach(() => {
jest.clearAllMocks();
@ -141,12 +138,9 @@ describe('EngineOverviewLogic', () => {
});
describe('unmount', () => {
let unmount: Function;
beforeEach(() => {
jest.useFakeTimers();
resetContext({});
unmount = EngineOverviewLogic.mount();
mount();
});
it('clears existing polling timeouts on unmount', () => {

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { resetContext } from 'kea';
import { LogicMounter } from '../../../../__mocks__/kea.mock';
import { mockHttpValues } from '../../../../__mocks__';
jest.mock('../../../../shared/http', () => ({
@ -53,24 +53,7 @@ describe('LogRetentionLogic', () => {
isLogRetentionUpdating: false,
};
const mount = (defaults?: object) => {
if (!defaults) {
resetContext({});
} else {
resetContext({
defaults: {
enterprise_search: {
app_search: {
log_retention_logic: {
...defaults,
},
},
},
},
});
}
LogRetentionLogic.mount();
};
const { mount } = new LogicMounter(LogRetentionLogic);
beforeEach(() => {
jest.clearAllMocks();