1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-22 01:16:07 +02:00

refactor: additional unit tests for multi-project tokens - (#863)

* refactor: add theme to test renderer

* feat: add tests to token list

* projects list for multi-project tokens

* refactor: api token form available projects map

* update variable name

* fix: restore selected project on token type change

* fix: select project input code formatting

* fix: improve code formatting after review
This commit is contained in:
Tymoteusz Czech 2022-04-08 16:01:43 +02:00 committed by GitHub
parent edf69d171d
commit 9dd88b488f
7 changed files with 98 additions and 24 deletions

View File

@ -49,9 +49,9 @@ const ApiTokenForm: React.FC<IApiTokenFormProps> = ({
{ key: 'ADMIN', label: 'Admin', title: 'Admin API token' },
];
const selectableProjects = availableProjects.map(i => ({
value: i.id,
label: i.name,
const selectableProjects = availableProjects.map(project => ({
value: project.id,
label: project.name,
}));
const selectableEnvs =

View File

@ -0,0 +1,62 @@
import React from 'react';
import { screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { render } from 'utils/testRenderer';
import {
ISelectProjectInputProps,
SelectProjectInput,
} from './SelectProjectInput';
const onChange = jest.fn();
const onFocus = jest.fn();
const mockProps: ISelectProjectInputProps = {
options: [
{ label: 'Project1', value: 'project1' },
{ label: 'Project2', value: 'project2' },
],
defaultValue: ['*'],
onChange,
onFocus,
};
describe('SelectProjectInput', () => {
beforeEach(() => {
onChange.mockClear();
onFocus.mockClear();
});
it('renders with default state', () => {
render(<SelectProjectInput {...mockProps} />);
const checkbox = screen.getByLabelText(
/all current and future projects/i
);
expect(checkbox).toBeChecked();
const selectInputContainer = screen.getByTestId('select-input');
const input = within(selectInputContainer).getByRole('textbox');
expect(input).toBeDisabled();
});
it('can toggle "ALL" checkbox', async () => {
const user = userEvent.setup();
render(<SelectProjectInput {...mockProps} />);
await user.click(screen.getByTestId('select-all-projects'));
expect(
screen.getByLabelText(/all current and future projects/i)
).not.toBeChecked();
expect(screen.getByLabelText('Projects')).toBeEnabled();
await user.click(screen.getByTestId('select-all-projects'));
expect(
screen.getByLabelText(/all current and future projects/i)
).toBeChecked();
expect(screen.getByLabelText('Projects')).toBeDisabled();
});
});

View File

@ -23,7 +23,7 @@ const ALL_PROJECTS = '*';
// Fix for shadow under Autocomplete - match with Select input
const CustomPaper = ({ ...props }) => <Paper elevation={8} {...props} />;
interface ISelectProjectInputProps {
export interface ISelectProjectInputProps {
disabled?: boolean;
options: IAutocompleteBoxOption[];
defaultValue: string[];
@ -100,6 +100,7 @@ export const SelectProjectInput: VFC<ISelectProjectInputProps> = ({
label="Projects"
placeholder="Select one or more projects"
onFocus={onFocus}
data-testid="select-input"
/>
);
@ -108,6 +109,7 @@ export const SelectProjectInput: VFC<ISelectProjectInputProps> = ({
<Box sx={{ mt: 1, mb: 0.25, ml: 1.5 }}>
<FormControlLabel
disabled={disabled}
data-testid="select-all-projects"
control={
<Checkbox
checked={disabled || isWildcardSelected}

View File

@ -11,6 +11,8 @@ export const useApiTokenForm = () => {
const [username, setUsername] = useState('');
const [type, setType] = useState('CLIENT');
const [projects, setProjects] = useState<string[]>(['*']);
const [memorizedProjects, setMemorizedProjects] =
useState<string[]>(projects);
const [environment, setEnvironment] = useState<string>();
const [errors, setErrors] = useState<
Partial<Record<ApiTokenFormErrorType, string>>
@ -23,10 +25,12 @@ export const useApiTokenForm = () => {
const setTokenType = (value: string) => {
if (value === 'ADMIN') {
setType(value);
setMemorizedProjects(projects);
setProjects(['*']);
setEnvironment('*');
} else {
setType(value);
setProjects(memorizedProjects);
setEnvironment(initialEnvironment);
}
};

View File

@ -3,11 +3,9 @@ import 'themes/app.css';
import ReactDOM from 'react-dom';
import { Route, BrowserRouter as Router } from 'react-router-dom';
import { ThemeProvider, CssBaseline } from '@material-ui/core';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { StylesProvider } from '@material-ui/core/styles';
import mainTheme from 'themes/mainTheme';
import { MainThemeProvider } from 'themes/MainThemeProvider';
import { App } from 'component/App';
import { ScrollTop } from 'component/common/ScrollTop/ScrollTop';
import AccessProvider from 'component/providers/AccessProvider/AccessProvider';
@ -20,15 +18,12 @@ ReactDOM.render(
<UIProvider>
<AccessProvider>
<Router basename={`${getBasePath()}`}>
<ThemeProvider theme={mainTheme}>
<StylesProvider injectFirst>
<FeedbackCESProvider>
<CssBaseline />
<ScrollTop />
<Route path="/" component={App} />
</FeedbackCESProvider>
</StylesProvider>
</ThemeProvider>
<MainThemeProvider>
<FeedbackCESProvider>
<ScrollTop />
<Route path="/" component={App} />
</FeedbackCESProvider>
</MainThemeProvider>
</Router>
</AccessProvider>
</UIProvider>

View File

@ -0,0 +1,12 @@
import React, { FC } from 'react';
import { CssBaseline, StylesProvider, ThemeProvider } from '@material-ui/core';
import mainTheme from './mainTheme';
export const MainThemeProvider: FC = ({ children }) => (
<ThemeProvider theme={mainTheme}>
<StylesProvider injectFirst>
<CssBaseline />
{children}
</StylesProvider>
</ThemeProvider>
);

View File

@ -1,9 +1,8 @@
import React, { FC } from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { render as rtlRender, RenderOptions } from '@testing-library/react';
import { SWRConfig } from 'swr';
import { ThemeProvider } from '@material-ui/core/styles';
import theme from 'themes/mainTheme';
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import { MainThemeProvider } from 'themes/MainThemeProvider';
export const render = (
ui: JSX.Element,
@ -20,12 +19,12 @@ export const render = (
});
};
const Wrapper: React.FC = ({ children }) => {
const Wrapper: FC = ({ children }) => {
return (
<SWRConfig value={{ provider: () => new Map() }}>
<BrowserRouter>
<ThemeProvider theme={theme}>{children}</ThemeProvider>
</BrowserRouter>
<MainThemeProvider>
<Router>{children}</Router>
</MainThemeProvider>
</SWRConfig>
);
};