kafka-ui/kafka-ui-react-app/src/lib/testHelpers.tsx
Roman Zabaluev 5c723d9b44
Role based access control (#2790)
* Role based access control

* Fix build + checkstyle

* Refactoring, some bug fixes, review fixes

* Compile permission value patterns

* Make the resource a enum instead of a string

* Refactoring

* Make clusters required

* Fix formatting

* switch the switch case to a smart switch case

* Get rid of topic analysis actions

* Rename endpoints, fix an issue

* Return a flag indicating if rbac is on and a username

* Fix yaml indent in editorconfig

* Fix github & cognito role name fetching

* Fix case matching for actions

* Update readme

* Add an endpoint to determine if a user can create a resource

* Fix tests (I hope so)

* Fix tests

* Use spring configs instead of a separate file, rename endpoints

* Add "ALL" action
Get rid of unnecessary cache, save groups into spring auth
Review fixes

* Make "all" action case-insensitive

* Role based access control / FrontEnd  (#2933)

* Initial modifications and mocking the For the RoleAccess

* fix the Suspense issue in the components , comment the Tests to implement later

* minor test comment

* Roles and configuration and santization of data

* initialize RoleCheck hook

* make the App test file visible + minor modification in the permission hook

* Structure the data so the Burger header toggle does not rerender the whole application

* add tests to the NavBar and the Page container , add tests

* NavBar and PageContainer bug fixes

* Roles Testing code modification

* covering Topics create button Actions, and Schema create button Actions

* minor typescript code modifications for the cluster required parameter in the rolesHelper

* minor typescript code modifications for the cluster required parameter in the rolesHelper

* minor code modification to describe the Permission tests more clearly

* Produce message Permissions with Tests Suites for Topic

* Add Schema Edit Permission with tests

* Minor role changes

* Add ActionButton Component to handle the Button with tooltip

* Add ActionButton Component to handle the Button with tooltip

* Add Action Button to every Button create Action

* ActionButton add test suites

* usePermission code modification to include regular expressions

* Abstract Actions Component for code repetition, add Configs Edit button Permission + add the tests suites to it.

* Schema Remove functionality Permission and Test Suites + creation of the ActionDropdownItem for Actions

* Topic Edit Clear and delete Topic , Permissions with test suites

* ActionsCell For Topic Message Overview for permissions with tests suites

* Connector Delete , Consumer Groups Permission + writing test suites

* Add Permissions to the Topics ActionCell

* Topic Table Permissions Tests Suites

* Headless Logic for the Permission Part

* add documentation for the headless Part of the permission + add modification of the data version 2 for efficient algorithmic lookup

* replace modify data logic and isPermitted function to have faster access to the data

* Add Permission helpers tests suites

* usePermission hook test suites

* BatchActionsBar add Permissions + minor modification in TopicTable tests suites

* Statistics and Metrics code Permission + add test suites

* Recreate Topic Permissions in the Topic page, add tests suites

* Actions for the Connector components

* Messages NavLink View Permission

* Test suites messages code modifications

* Permissions comment code modifications

* Replacing the Mock Data With the actual code

* Add ActionNavLink test suites

* BatchActionsBar code smell modifications

* maximizing the permissions tests suites

* maximizing the permissions tests suites

* maximizing the permissions tests suites

* Tooltip code refactoring and fix the positions issue

* permissions increase the tests coverage

* add user info at the navigation header and tests suites

* Add Global Schema Selector Permissions with test suites

* Roles minor code removal

* Change the Action Component form hook mixin approach to declarative props approach

* add isPermitted function for multiple Actions , adding tests suites for this particular case

* remove redundant Permissions test blocks from the components

* remove redundant Permissions test blocks from the components

* Action Buttons test suites' coverage + generalizing the code of the Actions

* add invalid Permission check in Action Components tests suites

* Modularization of Actions Components

* Modularization of Actions Components by adding DropDownAction to it.

* Reflect the BE Changes to the UI , by changing the default behavior or the testing of roles.

* Reflect the BE Changes to the UI , by changing the default behavior or the testing of roles.

* Get rid of not necessary usePermission mocks

* Modifications in the UserInfo data , to consider the UI without any login functionality

* minor code modifications in the BatchActionBar component

* change the Query key for the user info

* change the default message for the tooltip

* Fix the Create Role Access for Topics and Schemas

* ListPage Connector create permissions

* add Headless logic for Create Permission with test suites. + add react hook render-er

* Create Button ActionButton logic implementation

* Remove Code smells , by removing the duplications

* increase the test suites for isPermittedToCreate logic

* increase the test suites for isPermittedToCreate logic

* Change the UserResourceType Enum with the new value

* Apply New Resource Creation validation, for Topic, Schema, Connector

* Apply New Resource Creation validation, for Topic, Schema, Connector

* minor code refactor modifications

* minor code modification in the topics useCreate hook

* Async Validation for all the Create Pages

* caching test for optimal performance in async validation schemas

* Reverting the Front End Validation

* Reverting the Front End Validation

* Authorization API minor syntax modifications

* fix SmokeTests

Co-authored-by: Roman Zabaluev <rzabaluev@provectus.com>
Co-authored-by: VladSenyuta <vlad.senyuta@gmail.com>

Co-authored-by: Mgrdich <46796009+Mgrdich@users.noreply.github.com>
Co-authored-by: VladSenyuta <vlad.senyuta@gmail.com>
2022-12-22 17:05:53 +04:00

169 lines
4.6 KiB
TypeScript

import React, { PropsWithChildren, ReactElement, useMemo } from 'react';
import {
MemoryRouter,
MemoryRouterProps,
Route,
Routes,
} from 'react-router-dom';
import fetchMock from 'fetch-mock';
import { Provider } from 'react-redux';
import { ThemeProvider } from 'styled-components';
import theme from 'theme/theme';
import {
render,
renderHook,
RenderOptions,
waitFor,
} from '@testing-library/react';
import { AnyAction, Store } from 'redux';
import { RootState } from 'redux/interfaces';
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from 'redux/reducers';
import {
QueryClient,
QueryClientProvider,
UseQueryResult,
} from '@tanstack/react-query';
import { ConfirmContextProvider } from 'components/contexts/ConfirmContext';
import ConfirmationModal from 'components/common/ConfirmationModal/ConfirmationModal';
import {
defaultGlobalSettingsValue,
GlobalSettingsContext,
} from 'components/contexts/GlobalSettingsContext';
import { UserInfoRolesAccessContext } from 'components/contexts/UserInfoRolesAccessContext';
import { RolesType, modifyRolesData } from './permissions';
interface CustomRenderOptions extends Omit<RenderOptions, 'wrapper'> {
preloadedState?: Partial<RootState>;
store?: Store<Partial<RootState>, AnyAction>;
initialEntries?: MemoryRouterProps['initialEntries'];
userInfo?: {
roles?: RolesType;
rbacFlag: boolean;
};
}
interface WithRouteProps {
children: React.ReactNode;
path: string;
}
export const expectQueryWorks = async (
mock: fetchMock.FetchMockStatic,
result: { current: UseQueryResult<unknown, unknown> }
) => {
await waitFor(() => expect(result.current.isFetched).toBeTruthy());
expect(mock.calls()).toHaveLength(1);
expect(result.current.data).toBeDefined();
};
export const WithRoute: React.FC<WithRouteProps> = ({ children, path }) => {
return (
<Routes>
<Route path={path} element={children} />
</Routes>
);
};
export const TestQueryClientProvider: React.FC<PropsWithChildren<unknown>> = ({
children,
}) => {
// use new QueryClient instance for each test run to avoid issues with cache
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
};
/**
* @description it will create a UserInfo Provider that will actually
* disable the rbacFlag , to user if you can pass it as an argument
* */
export const TestUserInfoProvider: React.FC<
PropsWithChildren<{ data?: { roles?: RolesType; rbacFlag: boolean } }>
> = ({ children, data }) => {
const contextValue = useMemo(() => {
const roles = modifyRolesData(data?.roles);
return {
username: 'test',
rbacFlag: !!(typeof data?.rbacFlag === 'undefined'
? false
: data?.rbacFlag),
roles,
};
}, [data]);
return (
<UserInfoRolesAccessContext.Provider value={contextValue}>
{children}
</UserInfoRolesAccessContext.Provider>
);
};
const customRender = (
ui: ReactElement,
{
preloadedState,
store = configureStore<RootState>({
reducer: rootReducer,
preloadedState,
}),
initialEntries,
userInfo,
...renderOptions
}: CustomRenderOptions = {}
) => {
// overrides @testing-library/react render.
const AllTheProviders: React.FC<PropsWithChildren<unknown>> = ({
children,
}) => (
<TestQueryClientProvider>
<GlobalSettingsContext.Provider value={defaultGlobalSettingsValue}>
<ThemeProvider theme={theme}>
<TestUserInfoProvider data={userInfo}>
<ConfirmContextProvider>
<Provider store={store}>
<MemoryRouter initialEntries={initialEntries}>
<div>
{children}
<ConfirmationModal />
</div>
</MemoryRouter>
</Provider>
</ConfirmContextProvider>
</TestUserInfoProvider>
</ThemeProvider>
</GlobalSettingsContext.Provider>
</TestQueryClientProvider>
);
return render(ui, { wrapper: AllTheProviders, ...renderOptions });
};
const customRenderHook = (hook: () => UseQueryResult<unknown, unknown>) =>
renderHook(hook, { wrapper: TestQueryClientProvider });
export { customRender as render, customRenderHook as renderQueryHook };
export class EventSourceMock {
url: string;
close: () => void;
open: () => void;
error: () => void;
onmessage: () => void;
constructor(url: string) {
this.url = url;
this.open = jest.fn();
this.error = jest.fn();
this.onmessage = jest.fn();
this.close = jest.fn();
}
}