[Search] [Playground] Fix connectors broken page (#191852)

- Fix load connector page on edit route
- Fix showing documentation and create connectors button on edit
connector page
- Add unit tests
- Add ftr test
This commit is contained in:
Yan Savitski 2024-09-06 11:13:25 +02:00 committed by GitHub
parent b9319a6ad4
commit 426eb898f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 105 additions and 26 deletions

View file

@ -143,6 +143,39 @@ describe('ActionsConnectorsHome', () => {
expect(documentationButton).toBeEnabled();
});
it('show "Create connector" and "Documentation" buttons when on Connectors Edit tab', async () => {
const props: RouteComponentProps<MatchParams> = {
history: createMemoryHistory({
initialEntries: ['/connectors/1'],
}),
location: createLocation('/connectors/1'),
match: {
isExact: true,
path: '/connectors/1',
url: '',
params: {
section: 'connectors',
},
},
};
render(
<IntlProvider locale="en">
<Router history={props.history}>
<QueryClientProvider client={queryClient}>
<ActionsConnectorsHome {...props} />
</QueryClientProvider>
</Router>
</IntlProvider>
);
const createConnectorButton = await screen.findByRole('button', { name: 'Create connector' });
expect(createConnectorButton).toBeEnabled();
const documentationButton = await screen.findByRole('link', { name: 'Documentation' });
expect(documentationButton).toBeEnabled();
});
it('hide "Create connector" button when on Logs tab', async () => {
const props: RouteComponentProps<MatchParams> = {
history: createMemoryHistory({

View file

@ -8,7 +8,7 @@
import React, { lazy, useCallback, useEffect, useState } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { Routes, Route } from '@kbn/shared-ux-router';
import { useLocation } from 'react-router-dom';
import { useLocation, matchPath } from 'react-router-dom';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { EuiPageTemplate, EuiSpacer, EuiPageHeader, EuiButton, EuiButtonEmpty } from '@elastic/eui';
@ -54,9 +54,12 @@ export const ActionsConnectorsHome: React.FunctionComponent<RouteComponentProps<
const [actions, setActions] = useState<ActionConnector[]>([]);
const [isLoadingActions, setIsLoadingActions] = useState<boolean>(true);
const editItem = (actionConnector: ActionConnector, tab: EditConnectorTabs, isFix?: boolean) => {
setEditConnectorProps({ initialConnector: actionConnector, tab, isFix: isFix ?? false });
};
const editItem = useCallback(
(actionConnector: ActionConnector, tab: EditConnectorTabs, isFix?: boolean) => {
setEditConnectorProps({ initialConnector: actionConnector, tab, isFix: isFix ?? false });
},
[setEditConnectorProps]
);
const loadActions = useCallback(async () => {
setIsLoadingActions(true);
@ -176,16 +179,19 @@ export const ActionsConnectorsHome: React.FunctionComponent<RouteComponentProps<
);
let topRightSideButtons: React.ReactNode[] = [];
switch (location.pathname) {
case '/connectors':
topRightSideButtons = [createConnectorButton, documentationButton];
break;
case '/logs':
topRightSideButtons = [documentationButton];
break;
default:
topRightSideButtons = [];
if (
matchPath(location.pathname, {
path: routeToConnectors,
exact: true,
}) ||
matchPath(location.pathname, { path: routeToConnectorEdit, exact: true })
) {
topRightSideButtons = [createConnectorButton, documentationButton];
} else if (matchPath(location.pathname, { path: routeToLogs, exact: true })) {
topRightSideButtons = [documentationButton];
}
return (
<>
<EuiPageHeader

View file

@ -18,28 +18,27 @@ import { act } from 'react-dom/test-utils';
import { actionTypeRegistryMock } from '../../../action_type_registry.mock';
import { useKibana } from '../../../../common/lib/kibana';
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
import { ActionConnector, EditConnectorTabs, GenericValidationResult } from '../../../../types';
import { times } from 'lodash';
import { useHistory, useParams } from 'react-router-dom';
jest.mock('../../../../common/lib/kibana');
import { ActionConnector, GenericValidationResult } from '../../../../types';
import { times } from 'lodash';
jest.mock('../../../lib/action_connector_api', () => ({
loadAllActions: jest.fn(),
loadActionTypes: jest.fn(),
}));
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: jest.fn().mockReturnValue({}),
useLocation: jest.fn().mockReturnValue({ search: '' }),
useHistory: jest.fn().mockReturnValue({ push: jest.fn(), createHref: jest.fn() }),
}));
const useKibanaMock = useKibana as jest.Mocked<typeof useKibana>;
const actionTypeRegistry = actionTypeRegistryMock.create();
const mocks = coreMock.createSetup();
const { loadActionTypes } = jest.requireMock('../../../lib/action_connector_api');
const mockGetParams = jest.fn().mockReturnValue({});
const mockGetLocation = jest.fn().mockReturnValue({ search: '' });
const mockGetHistory = jest.fn().mockReturnValue({ push: jest.fn(), createHref: jest.fn() });
jest.mock('react-router-dom', () => ({
useParams: () => mockGetParams(),
useLocation: () => mockGetLocation(),
useHistory: () => mockGetHistory(),
}));
describe('actions_connectors_list', () => {
describe('component empty', () => {
@ -173,6 +172,15 @@ describe('actions_connectors_list', () => {
config: {},
},
] as ActionConnector[];
let mockedEditItem: jest.Mock;
afterEach(() => {
mockedEditItem.mockReset();
});
afterAll(() => {
jest.clearAllMocks();
});
async function setup(actionConnectors = mockedActions) {
loadActionTypes.mockResolvedValueOnce([
@ -237,13 +245,13 @@ describe('actions_connectors_list', () => {
},
};
const editItem = jest.fn();
mockedEditItem = jest.fn();
wrapper = mountWithIntl(
<ActionsConnectorsList
setAddFlyoutVisibility={() => {}}
loadActions={async () => {}}
editItem={editItem}
editItem={mockedEditItem}
isLoadingActions={false}
actions={actionConnectors}
setActions={() => {}}
@ -379,6 +387,21 @@ describe('actions_connectors_list', () => {
.includes('This connector is used in a rule')
);
});
it('call editItem when connectorId presented in url', async () => {
const selectedConnector = mockedActions[3];
const mockedCreateHref = jest.fn(({ pathname }) => pathname);
const replaceStateSpy = jest.spyOn(window.history, 'replaceState');
(useParams as jest.Mock).mockReturnValue({ connectorId: selectedConnector.id });
(useHistory as jest.Mock).mockReturnValue({ createHref: mockedCreateHref });
await setup();
expect(mockedEditItem).toBeCalledWith(selectedConnector, EditConnectorTabs.Configuration);
expect(mockedCreateHref).toHaveBeenCalledWith({ pathname: '/connectors' });
expect(replaceStateSpy).toHaveBeenCalledWith(null, '', '/connectors');
replaceStateSpy.mockRestore();
});
});
describe('check EditConnectorFlyout will open on edit connector', () => {

View file

@ -171,6 +171,10 @@ export default function (ftrContext: FtrProviderContext) {
it('save selected fields between modes', async () => {
await pageObjects.searchPlayground.PlaygroundChatPage.expectSaveFieldsBetweenModes();
});
it('click on manage connector button', async () => {
await pageObjects.searchPlayground.PlaygroundChatPage.clickManageButton();
});
});
after(async () => {

View file

@ -231,6 +231,15 @@ export function SearchPlaygroundPageProvider({ getService }: FtrProviderContext)
await testSubjects.click('queryMode');
await testSubjects.existOrFail('field-baz-false');
},
async clickManageButton() {
await testSubjects.click('manageConnectorsLink');
await testSubjects.existOrFail('manageConnectorsLink');
await browser.switchTab(1);
await testSubjects.existOrFail('edit-connector-flyout');
await browser.closeCurrentWindow();
await browser.switchTab(0);
},
},
};
}

View file

@ -207,6 +207,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await pageObjects.searchPlayground.session.expectInSession('prompt', "You're a doctor");
await pageObjects.searchPlayground.session.expectInSession('question', undefined);
});
it('click on manage connector button', async () => {
await pageObjects.searchPlayground.PlaygroundChatPage.clickManageButton();
});
});
after(async () => {