mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[SECURITY] Don't use link for the last breadcrumb in the navigation bar for Security/Spaces management apps (#118117) (#118350)
* fix last breadcrumb item to only be text * commit using @elastic.co * cleaner * tests are coming ;) * used my brain to simplify it * fix types * fix/add jest test * fix lint + jest tests for spaces * fix accessibality Co-authored-by: Xavier Mouligneau <xavier.mouligneau@elastic.co>
This commit is contained in:
parent
7ed19d7696
commit
a09d2a8c38
12 changed files with 245 additions and 161 deletions
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import { coreMock } from 'src/core/public/mocks';
|
||||
|
||||
import { Breadcrumb, BreadcrumbsProvider, createBreadcrumbsChangeHandler } from './breadcrumb';
|
||||
|
||||
describe('security breadcrumbs', () => {
|
||||
const setBreadcrumbs = jest.fn();
|
||||
const { chrome } = coreMock.createStart();
|
||||
|
||||
beforeEach(() => {
|
||||
setBreadcrumbs.mockReset();
|
||||
chrome.docTitle.reset.mockReset();
|
||||
chrome.docTitle.change.mockReset();
|
||||
});
|
||||
|
||||
it('rendering one breadcrumb and it should NOT have an href attributes', async () => {
|
||||
render(
|
||||
<BreadcrumbsProvider onChange={createBreadcrumbsChangeHandler(chrome, setBreadcrumbs)}>
|
||||
<Breadcrumb text={'Find'} href="/">
|
||||
<div>{'Find'}</div>
|
||||
</Breadcrumb>
|
||||
</BreadcrumbsProvider>
|
||||
);
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ text: 'Find' }]);
|
||||
});
|
||||
|
||||
it('rendering two breadcrumb and our last breadcrumb should NOT have an href attributes', async () => {
|
||||
render(
|
||||
<BreadcrumbsProvider onChange={createBreadcrumbsChangeHandler(chrome, setBreadcrumbs)}>
|
||||
<Breadcrumb text={'Find'} href="/">
|
||||
<div>{'Find'}</div>
|
||||
<Breadcrumb text={'Sandy'} href="/sandy">
|
||||
<div>{'Sandy is a sweet dog'}</div>
|
||||
</Breadcrumb>
|
||||
</Breadcrumb>
|
||||
</BreadcrumbsProvider>
|
||||
);
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: '/', text: 'Find' }, { text: 'Sandy' }]);
|
||||
});
|
||||
|
||||
it('rendering three breadcrumb and our last breadcrumb should NOT have an href attributes', async () => {
|
||||
render(
|
||||
<BreadcrumbsProvider onChange={createBreadcrumbsChangeHandler(chrome, setBreadcrumbs)}>
|
||||
<Breadcrumb text={'Find'} href="/">
|
||||
<div>{'Find'}</div>
|
||||
<Breadcrumb text={'Sandy'} href="/sandy">
|
||||
<div>{'Sandy is a sweet dog'}</div>
|
||||
<Breadcrumb text={'Breed'} href="/sandy/breed">
|
||||
<div>{'Sandy is a mutts'}</div>
|
||||
</Breadcrumb>
|
||||
</Breadcrumb>
|
||||
</Breadcrumb>
|
||||
</BreadcrumbsProvider>
|
||||
);
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([
|
||||
{ href: '/', text: 'Find' },
|
||||
{ href: '/sandy', text: 'Sandy' },
|
||||
{ text: 'Breed' },
|
||||
]);
|
||||
});
|
||||
});
|
|
@ -80,11 +80,17 @@ export const BreadcrumbsProvider: FunctionComponent<BreadcrumbsProviderProps> =
|
|||
const breadcrumbsRef = useRef<BreadcrumbProps[]>([]);
|
||||
|
||||
const handleChange = (breadcrumbs: BreadcrumbProps[]) => {
|
||||
const newBreadcrumbs = breadcrumbs.map((item, index) => {
|
||||
if (index === breadcrumbs.length - 1) {
|
||||
return { ...item, href: undefined };
|
||||
}
|
||||
return item;
|
||||
});
|
||||
if (onChange) {
|
||||
onChange(breadcrumbs);
|
||||
onChange(newBreadcrumbs);
|
||||
} else if (services.chrome) {
|
||||
const setBreadcrumbs = createBreadcrumbsChangeHandler(services.chrome);
|
||||
setBreadcrumbs(breadcrumbs);
|
||||
setBreadcrumbs(newBreadcrumbs);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ describe('apiKeysManagementApp', () => {
|
|||
});
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: '/', text: 'API keys' }]);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ text: 'API keys' }]);
|
||||
expect(docTitle.change).toHaveBeenCalledWith(['API keys']);
|
||||
expect(docTitle.reset).not.toHaveBeenCalled();
|
||||
expect(container).toMatchInlineSnapshot(`
|
||||
|
|
|
@ -5,6 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { act } from '@testing-library/react';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import { coreMock, scopedHistoryMock } from 'src/core/public/mocks';
|
||||
import type { Unmount } from 'src/plugins/management/public/types';
|
||||
|
||||
import { roleMappingsManagementApp } from './role_mappings_management_app';
|
||||
|
||||
jest.mock('./role_mappings_grid', () => ({
|
||||
RoleMappingsGridPage: (props: any) =>
|
||||
// `docLinks` object is too big to include into test snapshot, so we just check its existence.
|
||||
|
@ -23,24 +31,23 @@ jest.mock('./edit_role_mapping', () => ({
|
|||
})}`,
|
||||
}));
|
||||
|
||||
import { coreMock, scopedHistoryMock } from 'src/core/public/mocks';
|
||||
|
||||
import { roleMappingsManagementApp } from './role_mappings_management_app';
|
||||
|
||||
async function mountApp(basePath: string, pathname: string) {
|
||||
const container = document.createElement('div');
|
||||
const setBreadcrumbs = jest.fn();
|
||||
|
||||
const startServices = await coreMock.createSetup().getStartServices();
|
||||
|
||||
const unmount = await roleMappingsManagementApp
|
||||
.create({ getStartServices: () => Promise.resolve(startServices) as any })
|
||||
.mount({
|
||||
basePath,
|
||||
element: container,
|
||||
setBreadcrumbs,
|
||||
history: scopedHistoryMock.create({ pathname }),
|
||||
});
|
||||
let unmount: Unmount = noop;
|
||||
await act(async () => {
|
||||
unmount = await roleMappingsManagementApp
|
||||
.create({ getStartServices: () => Promise.resolve(startServices) as any })
|
||||
.mount({
|
||||
basePath,
|
||||
element: container,
|
||||
setBreadcrumbs,
|
||||
history: scopedHistoryMock.create({ pathname }),
|
||||
});
|
||||
});
|
||||
|
||||
return { unmount, container, setBreadcrumbs, docTitle: startServices[0].chrome.docTitle };
|
||||
}
|
||||
|
@ -65,7 +72,7 @@ describe('roleMappingsManagementApp', () => {
|
|||
const { setBreadcrumbs, container, unmount, docTitle } = await mountApp('/', '/');
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Role Mappings' }]);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ text: 'Role Mappings' }]);
|
||||
expect(docTitle.change).toHaveBeenCalledWith('Role Mappings');
|
||||
expect(docTitle.reset).not.toHaveBeenCalled();
|
||||
expect(container).toMatchInlineSnapshot(`
|
||||
|
@ -114,8 +121,8 @@ describe('roleMappingsManagementApp', () => {
|
|||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([
|
||||
{ href: `/`, text: 'Role Mappings' },
|
||||
{ href: `/edit/${encodeURIComponent(roleMappingName)}`, text: roleMappingName },
|
||||
{ href: '/', text: 'Role Mappings' },
|
||||
{ text: roleMappingName },
|
||||
]);
|
||||
expect(docTitle.change).toHaveBeenCalledWith('Role Mappings');
|
||||
expect(docTitle.reset).not.toHaveBeenCalled();
|
||||
|
@ -139,9 +146,8 @@ describe('roleMappingsManagementApp', () => {
|
|||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([
|
||||
{ href: `/`, text: 'Role Mappings' },
|
||||
{ href: '/', text: 'Role Mappings' },
|
||||
{
|
||||
href: '/edit/some%20%E5%AE%89%E5%85%A8%E6%80%A7%20role%20mapping',
|
||||
text: roleMappingName,
|
||||
},
|
||||
]);
|
||||
|
|
|
@ -7,13 +7,18 @@
|
|||
|
||||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { Route, Router, Switch, useParams } from 'react-router-dom';
|
||||
import { Route, Router, useParams } from 'react-router-dom';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { StartServicesAccessor } from 'src/core/public';
|
||||
import type { RegisterManagementAppArgs } from 'src/plugins/management/public';
|
||||
|
||||
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbsProvider,
|
||||
createBreadcrumbsChangeHandler,
|
||||
} from '../../components/breadcrumb';
|
||||
import type { PluginStartDependencies } from '../../plugin';
|
||||
import { tryDecodeURIComponent } from '../url_utils';
|
||||
|
||||
|
@ -27,21 +32,12 @@ export const roleMappingsManagementApp = Object.freeze({
|
|||
const title = i18n.translate('xpack.security.management.roleMappingsTitle', {
|
||||
defaultMessage: 'Role Mappings',
|
||||
});
|
||||
|
||||
return {
|
||||
id: this.id,
|
||||
order: 40,
|
||||
title,
|
||||
async mount({ element, setBreadcrumbs, history }) {
|
||||
const [coreStart] = await getStartServices();
|
||||
const roleMappingsBreadcrumbs = [
|
||||
{
|
||||
text: title,
|
||||
href: `/`,
|
||||
},
|
||||
];
|
||||
|
||||
coreStart.chrome.docTitle.change(title);
|
||||
|
||||
const [
|
||||
[core],
|
||||
{ RoleMappingsGridPage },
|
||||
|
@ -56,20 +52,9 @@ export const roleMappingsManagementApp = Object.freeze({
|
|||
import('../roles'),
|
||||
]);
|
||||
|
||||
core.chrome.docTitle.change(title);
|
||||
|
||||
const roleMappingsAPIClient = new RoleMappingsAPIClient(core.http);
|
||||
const RoleMappingsGridPageWithBreadcrumbs = () => {
|
||||
setBreadcrumbs(roleMappingsBreadcrumbs);
|
||||
return (
|
||||
<RoleMappingsGridPage
|
||||
notifications={core.notifications}
|
||||
rolesAPIClient={new RolesAPIClient(core.http)}
|
||||
roleMappingsAPI={roleMappingsAPIClient}
|
||||
docLinks={core.docLinks}
|
||||
history={history}
|
||||
navigateToApp={coreStart.application.navigateToApp}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const EditRoleMappingsPageWithBreadcrumbs = () => {
|
||||
const { name } = useParams<{ name?: string }>();
|
||||
|
@ -78,26 +63,26 @@ export const roleMappingsManagementApp = Object.freeze({
|
|||
// See https://github.com/elastic/kibana/issues/82440
|
||||
const decodedName = name ? tryDecodeURIComponent(name) : undefined;
|
||||
|
||||
setBreadcrumbs([
|
||||
...roleMappingsBreadcrumbs,
|
||||
name
|
||||
const breadcrumbObj =
|
||||
name && decodedName
|
||||
? { text: decodedName, href: `/edit/${encodeURIComponent(name)}` }
|
||||
: {
|
||||
text: i18n.translate('xpack.security.roleMappings.createBreadcrumb', {
|
||||
defaultMessage: 'Create',
|
||||
}),
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
return (
|
||||
<EditRoleMappingPage
|
||||
name={decodedName}
|
||||
roleMappingsAPI={roleMappingsAPIClient}
|
||||
rolesAPIClient={new RolesAPIClient(core.http)}
|
||||
notifications={core.notifications}
|
||||
docLinks={core.docLinks}
|
||||
history={history}
|
||||
/>
|
||||
<Breadcrumb text={breadcrumbObj.text} href={breadcrumbObj.href}>
|
||||
<EditRoleMappingPage
|
||||
name={decodedName}
|
||||
roleMappingsAPI={roleMappingsAPIClient}
|
||||
rolesAPIClient={new RolesAPIClient(core.http)}
|
||||
notifications={core.notifications}
|
||||
docLinks={core.docLinks}
|
||||
history={history}
|
||||
/>
|
||||
</Breadcrumb>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -105,14 +90,25 @@ export const roleMappingsManagementApp = Object.freeze({
|
|||
<KibanaContextProvider services={core}>
|
||||
<core.i18n.Context>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path={['/', '']} exact={true}>
|
||||
<RoleMappingsGridPageWithBreadcrumbs />
|
||||
</Route>
|
||||
<Route path="/edit/:name?">
|
||||
<EditRoleMappingsPageWithBreadcrumbs />
|
||||
</Route>
|
||||
</Switch>
|
||||
<BreadcrumbsProvider
|
||||
onChange={createBreadcrumbsChangeHandler(core.chrome, setBreadcrumbs)}
|
||||
>
|
||||
<Breadcrumb text={title} href="/">
|
||||
<Route path={['/', '']} exact={true}>
|
||||
<RoleMappingsGridPage
|
||||
notifications={core.notifications}
|
||||
rolesAPIClient={new RolesAPIClient(core.http)}
|
||||
roleMappingsAPI={roleMappingsAPIClient}
|
||||
docLinks={core.docLinks}
|
||||
history={history}
|
||||
navigateToApp={core.application.navigateToApp}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="/edit/:name?">
|
||||
<EditRoleMappingsPageWithBreadcrumbs />
|
||||
</Route>
|
||||
</Breadcrumb>
|
||||
</BreadcrumbsProvider>
|
||||
</Router>
|
||||
</core.i18n.Context>
|
||||
</KibanaContextProvider>,
|
||||
|
@ -120,7 +116,6 @@ export const roleMappingsManagementApp = Object.freeze({
|
|||
);
|
||||
|
||||
return () => {
|
||||
coreStart.chrome.docTitle.reset();
|
||||
unmountComponentAtNode(element);
|
||||
};
|
||||
},
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { act } from '@testing-library/react';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import { coreMock, scopedHistoryMock } from 'src/core/public/mocks';
|
||||
import type { Unmount } from 'src/plugins/management/public/types';
|
||||
|
||||
import { featuresPluginMock } from '../../../../features/public/mocks';
|
||||
import { licenseMock } from '../../../common/licensing/index.mock';
|
||||
|
@ -29,20 +33,23 @@ async function mountApp(basePath: string, pathname: string) {
|
|||
const featuresStart = featuresPluginMock.createStart();
|
||||
const coreStart = coreMock.createStart();
|
||||
|
||||
const unmount = await rolesManagementApp
|
||||
.create({
|
||||
license: licenseMock.create(),
|
||||
fatalErrors,
|
||||
getStartServices: jest
|
||||
.fn()
|
||||
.mockResolvedValue([coreStart, { data: {}, features: featuresStart }]),
|
||||
})
|
||||
.mount({
|
||||
basePath,
|
||||
element: container,
|
||||
setBreadcrumbs,
|
||||
history: scopedHistoryMock.create({ pathname }),
|
||||
});
|
||||
let unmount: Unmount = noop;
|
||||
await act(async () => {
|
||||
unmount = await rolesManagementApp
|
||||
.create({
|
||||
license: licenseMock.create(),
|
||||
fatalErrors,
|
||||
getStartServices: jest
|
||||
.fn()
|
||||
.mockResolvedValue([coreStart, { data: {}, features: featuresStart }]),
|
||||
})
|
||||
.mount({
|
||||
basePath,
|
||||
element: container,
|
||||
setBreadcrumbs,
|
||||
history: scopedHistoryMock.create({ pathname }),
|
||||
});
|
||||
});
|
||||
|
||||
return { unmount, container, setBreadcrumbs, docTitle: coreStart.chrome.docTitle };
|
||||
}
|
||||
|
@ -71,7 +78,7 @@ describe('rolesManagementApp', () => {
|
|||
const { setBreadcrumbs, container, unmount, docTitle } = await mountApp('/', '/');
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Roles' }]);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ text: 'Roles' }]);
|
||||
expect(docTitle.change).toHaveBeenCalledWith('Roles');
|
||||
expect(docTitle.reset).not.toHaveBeenCalled();
|
||||
expect(container).toMatchInlineSnapshot(`
|
||||
|
@ -116,10 +123,7 @@ describe('rolesManagementApp', () => {
|
|||
);
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([
|
||||
{ href: `/`, text: 'Roles' },
|
||||
{ href: `/edit/${encodeURIComponent(roleName)}`, text: roleName },
|
||||
]);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Roles' }, { text: roleName }]);
|
||||
expect(docTitle.change).toHaveBeenCalledWith('Roles');
|
||||
expect(docTitle.reset).not.toHaveBeenCalled();
|
||||
expect(container).toMatchInlineSnapshot(`
|
||||
|
@ -169,7 +173,6 @@ describe('rolesManagementApp', () => {
|
|||
expect(setBreadcrumbs).toHaveBeenCalledWith([
|
||||
{ href: `/`, text: 'Roles' },
|
||||
{
|
||||
href: '/edit/some%20%E5%AE%89%E5%85%A8%E6%80%A7%20role',
|
||||
text: roleName,
|
||||
},
|
||||
]);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { Route, Router, Switch, useParams } from 'react-router-dom';
|
||||
import { Route, Router, useParams } from 'react-router-dom';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { FatalErrorsSetup, StartServicesAccessor } from 'src/core/public';
|
||||
|
@ -15,6 +15,11 @@ import type { RegisterManagementAppArgs } from 'src/plugins/management/public';
|
|||
|
||||
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import type { SecurityLicense } from '../../../common/licensing';
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbsProvider,
|
||||
createBreadcrumbsChangeHandler,
|
||||
} from '../../components/breadcrumb';
|
||||
import type { PluginStartDependencies } from '../../plugin';
|
||||
import { tryDecodeURIComponent } from '../url_utils';
|
||||
|
||||
|
@ -35,13 +40,6 @@ export const rolesManagementApp = Object.freeze({
|
|||
order: 20,
|
||||
title,
|
||||
async mount({ element, setBreadcrumbs, history }) {
|
||||
const rolesBreadcrumbs = [
|
||||
{
|
||||
text: title,
|
||||
href: `/`,
|
||||
},
|
||||
];
|
||||
|
||||
const [
|
||||
[startServices, { data, features, spaces }],
|
||||
{ RolesGridPage },
|
||||
|
@ -72,16 +70,6 @@ export const rolesManagementApp = Object.freeze({
|
|||
chrome.docTitle.change(title);
|
||||
|
||||
const rolesAPIClient = new RolesAPIClient(http);
|
||||
const RolesGridPageWithBreadcrumbs = () => {
|
||||
setBreadcrumbs(rolesBreadcrumbs);
|
||||
return (
|
||||
<RolesGridPage
|
||||
notifications={notifications}
|
||||
rolesAPIClient={rolesAPIClient}
|
||||
history={history}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const EditRolePageWithBreadcrumbs = ({ action }: { action: 'edit' | 'clone' }) => {
|
||||
const { roleName } = useParams<{ roleName?: string }>();
|
||||
|
@ -90,38 +78,38 @@ export const rolesManagementApp = Object.freeze({
|
|||
// See https://github.com/elastic/kibana/issues/82440
|
||||
const decodedRoleName = roleName ? tryDecodeURIComponent(roleName) : undefined;
|
||||
|
||||
setBreadcrumbs([
|
||||
...rolesBreadcrumbs,
|
||||
action === 'edit' && roleName
|
||||
const breadcrumbObj =
|
||||
action === 'edit' && roleName && decodedRoleName
|
||||
? { text: decodedRoleName, href: `/edit/${encodeURIComponent(roleName)}` }
|
||||
: {
|
||||
text: i18n.translate('xpack.security.roles.createBreadcrumb', {
|
||||
defaultMessage: 'Create',
|
||||
}),
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
const spacesApiUi = spaces?.ui;
|
||||
|
||||
return (
|
||||
<EditRolePage
|
||||
action={action}
|
||||
roleName={decodedRoleName}
|
||||
rolesAPIClient={rolesAPIClient}
|
||||
userAPIClient={new UserAPIClient(http)}
|
||||
indicesAPIClient={new IndicesAPIClient(http)}
|
||||
privilegesAPIClient={new PrivilegesAPIClient(http)}
|
||||
getFeatures={features.getFeatures}
|
||||
http={http}
|
||||
notifications={notifications}
|
||||
fatalErrors={fatalErrors}
|
||||
license={license}
|
||||
docLinks={docLinks}
|
||||
uiCapabilities={application.capabilities}
|
||||
indexPatterns={data.indexPatterns}
|
||||
history={history}
|
||||
spacesApiUi={spacesApiUi}
|
||||
/>
|
||||
<Breadcrumb text={breadcrumbObj.text} href={breadcrumbObj.href}>
|
||||
<EditRolePage
|
||||
action={action}
|
||||
roleName={decodedRoleName}
|
||||
rolesAPIClient={rolesAPIClient}
|
||||
userAPIClient={new UserAPIClient(http)}
|
||||
indicesAPIClient={new IndicesAPIClient(http)}
|
||||
privilegesAPIClient={new PrivilegesAPIClient(http)}
|
||||
getFeatures={features.getFeatures}
|
||||
http={http}
|
||||
notifications={notifications}
|
||||
fatalErrors={fatalErrors}
|
||||
license={license}
|
||||
docLinks={docLinks}
|
||||
uiCapabilities={application.capabilities}
|
||||
indexPatterns={data.indexPatterns}
|
||||
history={history}
|
||||
spacesApiUi={spacesApiUi}
|
||||
/>
|
||||
</Breadcrumb>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -129,26 +117,32 @@ export const rolesManagementApp = Object.freeze({
|
|||
<KibanaContextProvider services={startServices}>
|
||||
<i18nStart.Context>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path={['/', '']} exact={true}>
|
||||
<RolesGridPageWithBreadcrumbs />
|
||||
</Route>
|
||||
<Route path="/edit/:roleName?">
|
||||
<EditRolePageWithBreadcrumbs action="edit" />
|
||||
</Route>
|
||||
<Route path="/clone/:roleName">
|
||||
<EditRolePageWithBreadcrumbs action="clone" />
|
||||
</Route>
|
||||
</Switch>
|
||||
<BreadcrumbsProvider
|
||||
onChange={createBreadcrumbsChangeHandler(chrome, setBreadcrumbs)}
|
||||
>
|
||||
<Breadcrumb text={title} href="/">
|
||||
<Route path={['/', '']} exact={true}>
|
||||
<RolesGridPage
|
||||
notifications={notifications}
|
||||
rolesAPIClient={rolesAPIClient}
|
||||
history={history}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="/edit/:roleName?">
|
||||
<EditRolePageWithBreadcrumbs action="edit" />
|
||||
</Route>
|
||||
<Route path="/clone/:roleName">
|
||||
<EditRolePageWithBreadcrumbs action="clone" />
|
||||
</Route>
|
||||
</Breadcrumb>
|
||||
</BreadcrumbsProvider>
|
||||
</Router>
|
||||
</i18nStart.Context>
|
||||
</KibanaContextProvider>,
|
||||
|
||||
element
|
||||
);
|
||||
|
||||
return () => {
|
||||
chrome.docTitle.reset();
|
||||
unmountComponentAtNode(element);
|
||||
};
|
||||
},
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { act } from '@testing-library/react';
|
||||
import { noop } from 'lodash';
|
||||
|
||||
import { coreMock, scopedHistoryMock } from 'src/core/public/mocks';
|
||||
import type { Unmount } from 'src/plugins/management/public/types';
|
||||
|
||||
import { securityMock } from '../../mocks';
|
||||
import { usersManagementApp } from './users_management_app';
|
||||
|
@ -22,16 +26,19 @@ describe('usersManagementApp', () => {
|
|||
const setBreadcrumbs = jest.fn();
|
||||
const history = scopedHistoryMock.create({ pathname: '/create' });
|
||||
|
||||
const unmount = await usersManagementApp.create({ authc, getStartServices }).mount({
|
||||
basePath: '/',
|
||||
element,
|
||||
setBreadcrumbs,
|
||||
history,
|
||||
let unmount: Unmount = noop;
|
||||
await act(async () => {
|
||||
unmount = await usersManagementApp.create({ authc, getStartServices }).mount({
|
||||
basePath: '/',
|
||||
element,
|
||||
setBreadcrumbs,
|
||||
history,
|
||||
});
|
||||
});
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenLastCalledWith([
|
||||
{ href: '/', text: 'Users' },
|
||||
{ href: '/create', text: 'Create' },
|
||||
{ text: 'Create' },
|
||||
]);
|
||||
|
||||
unmount();
|
||||
|
|
|
@ -119,7 +119,6 @@ export const usersManagementApp = Object.freeze({
|
|||
);
|
||||
|
||||
return () => {
|
||||
coreStart.chrome.docTitle.reset();
|
||||
unmountComponentAtNode(element);
|
||||
};
|
||||
},
|
||||
|
|
|
@ -77,7 +77,7 @@ describe('spacesManagementApp', () => {
|
|||
const { setBreadcrumbs, container, unmount, docTitle } = await mountApp('/', '/');
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ href: `/`, text: 'Spaces' }]);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([{ text: 'Spaces' }]);
|
||||
expect(docTitle.change).toHaveBeenCalledWith('Spaces');
|
||||
expect(docTitle.reset).not.toHaveBeenCalled();
|
||||
expect(container).toMatchInlineSnapshot(`
|
||||
|
@ -102,7 +102,7 @@ describe('spacesManagementApp', () => {
|
|||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([
|
||||
{ href: `/`, text: 'Spaces' },
|
||||
{ href: '/create', text: 'Create' },
|
||||
{ text: 'Create' },
|
||||
]);
|
||||
expect(docTitle.change).toHaveBeenCalledWith('Spaces');
|
||||
expect(docTitle.reset).not.toHaveBeenCalled();
|
||||
|
@ -134,7 +134,7 @@ describe('spacesManagementApp', () => {
|
|||
expect(setBreadcrumbs).toHaveBeenCalledTimes(1);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([
|
||||
{ href: `/`, text: 'Spaces' },
|
||||
{ href: `/edit/${spaceId}`, text: `space with id some-space` },
|
||||
{ text: `space with id some-space` },
|
||||
]);
|
||||
expect(docTitle.change).toHaveBeenCalledWith('Spaces');
|
||||
expect(docTitle.reset).not.toHaveBeenCalled();
|
||||
|
|
|
@ -43,18 +43,16 @@ export const spacesManagementApp = Object.freeze({
|
|||
const [[coreStart, { features }], { SpacesGridPage }, { ManageSpacePage }] =
|
||||
await Promise.all([getStartServices(), import('./spaces_grid'), import('./edit_space')]);
|
||||
|
||||
const spacesBreadcrumbs = [
|
||||
{
|
||||
text: title,
|
||||
href: `/`,
|
||||
},
|
||||
];
|
||||
const spacesFirstBreadcrumb = {
|
||||
text: title,
|
||||
href: `/`,
|
||||
};
|
||||
const { notifications, i18n: i18nStart, application, chrome } = coreStart;
|
||||
|
||||
chrome.docTitle.change(title);
|
||||
|
||||
const SpacesGridPageWithBreadcrumbs = () => {
|
||||
setBreadcrumbs(spacesBreadcrumbs);
|
||||
setBreadcrumbs([{ ...spacesFirstBreadcrumb, href: undefined }]);
|
||||
return (
|
||||
<SpacesGridPage
|
||||
capabilities={application.capabilities}
|
||||
|
@ -69,12 +67,11 @@ export const spacesManagementApp = Object.freeze({
|
|||
|
||||
const CreateSpacePageWithBreadcrumbs = () => {
|
||||
setBreadcrumbs([
|
||||
...spacesBreadcrumbs,
|
||||
spacesFirstBreadcrumb,
|
||||
{
|
||||
text: i18n.translate('xpack.spaces.management.createSpaceBreadcrumb', {
|
||||
defaultMessage: 'Create',
|
||||
}),
|
||||
href: '/create',
|
||||
},
|
||||
]);
|
||||
|
||||
|
@ -94,10 +91,9 @@ export const spacesManagementApp = Object.freeze({
|
|||
|
||||
const onLoadSpace = (space: Space) => {
|
||||
setBreadcrumbs([
|
||||
...spacesBreadcrumbs,
|
||||
spacesFirstBreadcrumb,
|
||||
{
|
||||
text: space.name,
|
||||
href: `/edit/${encodeURIComponent(space.id)}`,
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
|
|
@ -88,11 +88,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('a11y test for edit user panel', async () => {
|
||||
await PageObjects.settings.clickLinkText('Users');
|
||||
await PageObjects.settings.clickLinkText('deleteA11y');
|
||||
await a11y.testAppSnapshot();
|
||||
});
|
||||
|
||||
it('a11y test for change password screen', async () => {
|
||||
await PageObjects.settings.clickLinkText('Users');
|
||||
await PageObjects.settings.clickLinkText('deleteA11y');
|
||||
await find.clickByButtonText('Change password');
|
||||
await a11y.testAppSnapshot();
|
||||
|
@ -100,6 +102,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('a11y test for deactivate user screen', async () => {
|
||||
await PageObjects.settings.clickLinkText('Users');
|
||||
await PageObjects.settings.clickLinkText('deleteA11y');
|
||||
await find.clickByButtonText('Deactivate user');
|
||||
await a11y.testAppSnapshot();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue