Skip to content
This repository has been archived by the owner on Oct 27, 2022. It is now read-only.

Commit

Permalink
refactor: additional unit tests for multi-project tokens - (#863)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Tymek authored Apr 8, 2022
1 parent 6326d78 commit 554eba9
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 24 deletions.
6 changes: 3 additions & 3 deletions src/component/admin/apiToken/ApiTokenForm/ApiTokenForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down Expand Up @@ -100,6 +100,7 @@ export const SelectProjectInput: VFC<ISelectProjectInputProps> = ({
label="Projects"
placeholder="Select one or more projects"
onFocus={onFocus}
data-testid="select-input"
/>
);

Expand All @@ -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}
Expand Down
4 changes: 4 additions & 0 deletions src/component/admin/apiToken/hooks/useApiTokenForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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>>
Expand All @@ -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);
}
};
Expand Down
19 changes: 7 additions & 12 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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>
Expand Down
12 changes: 12 additions & 0 deletions src/themes/MainThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -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>
);
15 changes: 7 additions & 8 deletions src/utils/testRenderer.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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>
);
};

0 comments on commit 554eba9

Please sign in to comment.