[App Search] Move generateEnginePath out from EngineLogic values to its own helper (#89022)

* [Feedback] Move generateEnginePath to its own standalone helper

- instead of living inside EngineLogic.values
- I forgot Kea lets us do this now!

* Update all components using generateEngineRouter to import helper directly
This commit is contained in:
Constance 2021-01-21 14:39:14 -08:00 committed by GitHub
parent cacce7a866
commit c495093f76
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 65 additions and 70 deletions

View file

@ -8,16 +8,14 @@ import { generatePath } from 'react-router-dom';
export const mockEngineValues = {
engineName: 'some-engine',
// Note: using getters allows us to use `this`, which lets tests
// override engineName and still generate correct engine names
get generateEnginePath() {
return jest.fn((path, pathParams = {}) =>
generatePath(path, { engineName: this.engineName, ...pathParams })
);
},
engine: {},
};
export const mockGenerateEnginePath = jest.fn((path, pathParams = {}) =>
generatePath(path, { engineName: mockEngineValues.engineName, ...pathParams })
);
jest.mock('../components/engine', () => ({
EngineLogic: { values: mockEngineValues },
generateEnginePath: mockGenerateEnginePath,
}));

View file

@ -4,8 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { setMockValues } from '../../../__mocks__';
import { mockEngineValues } from '../../__mocks__';
import '../../__mocks__/engine_logic.mock';
import React from 'react';
import { shallow } from 'enzyme';
@ -16,7 +15,6 @@ import { AnalyticsRouter } from './';
describe('AnalyticsRouter', () => {
// Detailed route testing is better done via E2E tests
it('renders', () => {
setMockValues(mockEngineValues);
const wrapper = shallow(<AnalyticsRouter engineBreadcrumb={['Engines', 'some-engine']} />);
expect(wrapper.find(Switch)).toHaveLength(1);

View file

@ -6,7 +6,6 @@
import React from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import { useValues } from 'kea';
import { APP_SEARCH_PLUGIN } from '../../../../../common/constants';
import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
@ -22,7 +21,7 @@ import {
ENGINE_ANALYTICS_QUERY_DETAILS_PATH,
ENGINE_ANALYTICS_QUERY_DETAIL_PATH,
} from '../../routes';
import { EngineLogic } from '../engine';
import { generateEnginePath } from '../engine';
import {
ANALYTICS_TITLE,
@ -46,8 +45,6 @@ interface Props {
engineBreadcrumb: BreadcrumbTrail;
}
export const AnalyticsRouter: React.FC<Props> = ({ engineBreadcrumb }) => {
const { generateEnginePath } = useValues(EngineLogic);
const ANALYTICS_BREADCRUMB = [...engineBreadcrumb, ANALYTICS_TITLE];
return (

View file

@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock';
import { mockEngineValues } from '../../__mocks__';
import { setMockActions } from '../../../__mocks__/kea.mock';
import '../../__mocks__/engine_logic.mock';
import React from 'react';
import { shallow } from 'enzyme';
@ -21,7 +21,6 @@ describe('DocumentCreationButtons', () => {
beforeEach(() => {
jest.clearAllMocks();
setMockValues(mockEngineValues);
setMockActions(actions);
});

View file

@ -5,7 +5,7 @@
*/
import React from 'react';
import { useActions, useValues } from 'kea';
import { useActions } from 'kea';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
@ -22,7 +22,7 @@ import {
import { EuiCardTo } from '../../../shared/react_router_helpers';
import { DOCS_PREFIX, ENGINE_CRAWLER_PATH } from '../../routes';
import { EngineLogic } from '../engine';
import { generateEnginePath } from '../engine';
import { DocumentCreationLogic } from './';
@ -33,7 +33,6 @@ interface Props {
export const DocumentCreationButtons: React.FC<Props> = ({ disabled = false }) => {
const { openDocumentCreation } = useActions(DocumentCreationLogic);
const { generateEnginePath } = useValues(EngineLogic);
const crawlerLink = generateEnginePath(ENGINE_CRAWLER_PATH);
return (

View file

@ -12,7 +12,7 @@ import { KibanaLogic } from '../../../shared/kibana';
import { HttpLogic } from '../../../shared/http';
import { ENGINE_DOCUMENTS_PATH } from '../../routes';
import { EngineLogic } from '../engine';
import { EngineLogic, generateEnginePath } from '../engine';
import { FieldDetails } from './types';
@ -52,7 +52,7 @@ export const DocumentDetailLogic = kea<DocumentDetailLogicType>({
}),
listeners: ({ actions }) => ({
getDocumentDetails: async ({ documentId }) => {
const { engineName, generateEnginePath } = EngineLogic.values;
const { engineName } = EngineLogic.values;
const { navigateToUrl } = KibanaLogic.values;
try {
@ -70,7 +70,7 @@ export const DocumentDetailLogic = kea<DocumentDetailLogicType>({
}
},
deleteDocument: async ({ documentId }) => {
const { engineName, generateEnginePath } = EngineLogic.values;
const { engineName } = EngineLogic.values;
const { navigateToUrl } = KibanaLogic.values;
const CONFIRM_DELETE = i18n.translate(

View file

@ -36,7 +36,6 @@ describe('EngineLogic', () => {
dataLoading: true,
engine: {},
engineName: '',
generateEnginePath: expect.any(Function),
isMetaEngine: false,
isSampleEngine: false,
hasSchemaConflicts: false,
@ -198,28 +197,6 @@ describe('EngineLogic', () => {
});
describe('selectors', () => {
describe('generateEnginePath', () => {
it('returns helper function that generates paths with engineName prefilled', () => {
mount({ engineName: 'hello-world' });
const generatedPath = EngineLogic.values.generateEnginePath('/engines/:engineName/example');
expect(generatedPath).toEqual('/engines/hello-world/example');
});
it('allows overriding engineName and filling other params', () => {
mount({ engineName: 'lorem-ipsum' });
const generatedPath = EngineLogic.values.generateEnginePath(
'/engines/:engineName/foo/:bar',
{
engineName: 'dolor-sit',
bar: 'baz',
}
);
expect(generatedPath).toEqual('/engines/dolor-sit/foo/baz');
});
});
describe('isSampleEngine', () => {
it('should be set based on engine.sample', () => {
const mockSampleEngine = { ...mockEngineData, sample: true };

View file

@ -5,7 +5,6 @@
*/
import { kea, MakeLogicType } from 'kea';
import { generatePath } from 'react-router-dom';
import { HttpLogic } from '../../../shared/http';
@ -16,7 +15,6 @@ interface EngineValues {
dataLoading: boolean;
engine: Partial<EngineDetails>;
engineName: string;
generateEnginePath: Function;
isMetaEngine: boolean;
isSampleEngine: boolean;
hasSchemaConflicts: boolean;
@ -78,15 +76,6 @@ export const EngineLogic = kea<MakeLogicType<EngineValues, EngineActions>>({
],
},
selectors: ({ selectors }) => ({
generateEnginePath: [
() => [selectors.engineName],
(engineName) => {
const generateEnginePath = (path: string, pathParams: object = {}) => {
return generatePath(path, { engineName, ...pathParams });
};
return generateEnginePath;
},
],
isMetaEngine: [() => [selectors.engine], (engine) => engine?.type === 'meta'],
isSampleEngine: [() => [selectors.engine], (engine) => !!engine?.sample],
hasSchemaConflicts: [

View file

@ -40,7 +40,7 @@ import { RESULT_SETTINGS_TITLE } from '../result_settings';
import { SEARCH_UI_TITLE } from '../search_ui';
import { API_LOGS_TITLE } from '../api_logs';
import { EngineLogic } from './';
import { EngineLogic, generateEnginePath } from './';
import { EngineDetails } from './types';
import './engine_nav.scss';
@ -64,7 +64,6 @@ export const EngineNav: React.FC = () => {
const {
engineName,
generateEnginePath,
dataLoading,
isSampleEngine,
isMetaEngine,

View file

@ -7,3 +7,4 @@
export { EngineRouter } from './engine_router';
export { EngineNav } from './engine_nav';
export { EngineLogic } from './engine_logic';
export { generateEnginePath } from './utils';

View file

@ -0,0 +1,28 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { mockEngineValues } from '../../__mocks__';
import { generateEnginePath } from './utils';
describe('generateEnginePath', () => {
mockEngineValues.engineName = 'hello-world';
it('generates paths with engineName filled from state', () => {
expect(generateEnginePath('/engines/:engineName/example')).toEqual(
'/engines/hello-world/example'
);
});
it('allows overriding engineName and filling other params', () => {
expect(
generateEnginePath('/engines/:engineName/foo/:bar', {
engineName: 'override',
bar: 'baz',
})
).toEqual('/engines/override/foo/baz');
});
});

View file

@ -0,0 +1,17 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { generatePath } from 'react-router-dom';
import { EngineLogic } from './';
/**
* Generate a path with engineName automatically filled from EngineLogic state
*/
export const generateEnginePath = (path: string, pathParams: object = {}) => {
const { engineName } = EngineLogic.values;
return generatePath(path, { engineName, ...pathParams });
};

View file

@ -4,8 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { setMockValues } from '../../../../__mocks__/kea.mock';
import { mockEngineValues } from '../../../__mocks__';
import '../../../__mocks__/engine_logic.mock';
import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
@ -19,7 +18,6 @@ describe('RecentApiLogs', () => {
beforeAll(() => {
jest.clearAllMocks();
setMockValues(mockEngineValues);
wrapper = shallow(<RecentApiLogs />);
});

View file

@ -5,7 +5,6 @@
*/
import React from 'react';
import { useValues } from 'kea';
import {
EuiPageContent,
@ -17,14 +16,12 @@ import {
import { EuiButtonTo } from '../../../../shared/react_router_helpers';
import { ENGINE_API_LOGS_PATH } from '../../../routes';
import { EngineLogic } from '../../engine';
import { generateEnginePath } from '../../engine';
import { RECENT_API_EVENTS } from '../../api_logs/constants';
import { VIEW_API_LOGS } from '../constants';
export const RecentApiLogs: React.FC = () => {
const { generateEnginePath } = useValues(EngineLogic);
return (
<EuiPageContent>
<EuiPageContentHeader responsive={false}>

View file

@ -5,7 +5,7 @@
*/
import { setMockValues } from '../../../../__mocks__/kea.mock';
import { mockEngineValues } from '../../../__mocks__';
import '../../../__mocks__/engine_logic.mock';
import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
@ -21,7 +21,6 @@ describe('TotalCharts', () => {
beforeAll(() => {
jest.clearAllMocks();
setMockValues({
...mockEngineValues,
startDate: '1970-01-01',
queriesPerDay: [0, 1, 2, 3, 5, 10, 50],
operationsPerDay: [0, 0, 0, 0, 0, 0, 0],

View file

@ -20,7 +20,7 @@ import {
import { EuiButtonTo } from '../../../../shared/react_router_helpers';
import { ENGINE_ANALYTICS_PATH, ENGINE_API_LOGS_PATH } from '../../../routes';
import { EngineLogic } from '../../engine';
import { generateEnginePath } from '../../engine';
import { TOTAL_QUERIES, TOTAL_API_OPERATIONS } from '../../analytics/constants';
import { VIEW_ANALYTICS, VIEW_API_LOGS, LAST_7_DAYS } from '../constants';
@ -28,7 +28,6 @@ import { AnalyticsChart, convertToChartData } from '../../analytics';
import { EngineOverviewLogic } from '../';
export const TotalCharts: React.FC = () => {
const { generateEnginePath } = useValues(EngineLogic);
const { startDate, queriesPerDay, operationsPerDay } = useValues(EngineOverviewLogic);
return (