mirror of https://github.com/portainer/portainer
refactor(tests): wrap tests explicitly with provider [EE-6686] (#11090)
parent
27aaf322b2
commit
f8e3d75797
|
@ -45,6 +45,12 @@ rules:
|
|||
pathGroupsExcludedImportTypes: ['internal'],
|
||||
},
|
||||
]
|
||||
no-restricted-imports:
|
||||
- error
|
||||
- patterns:
|
||||
- group:
|
||||
- '@/react/test-utils/*'
|
||||
message: 'These utils are just for test files'
|
||||
|
||||
settings:
|
||||
'import/resolver':
|
||||
|
@ -113,6 +119,12 @@ overrides:
|
|||
'no-await-in-loop': 'off'
|
||||
'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }]
|
||||
'regex/invalid': ['error', [{ 'regex': '<Icon icon="(.*)"', 'message': 'Please directly import the `lucide-react` icon instead of using the string' }]]
|
||||
'@typescript-eslint/no-restricted-imports':
|
||||
- error
|
||||
- patterns:
|
||||
- group:
|
||||
- '@/react/test-utils/*'
|
||||
message: 'These utils are just for test files'
|
||||
overrides: # allow props spreading for hoc files
|
||||
- files:
|
||||
- app/**/with*.ts{,x}
|
||||
|
@ -126,7 +138,11 @@ overrides:
|
|||
'vitest/env': true
|
||||
rules:
|
||||
'react/jsx-no-constructed-context-values': off
|
||||
'@typescript-eslint/no-restricted-imports': off
|
||||
no-restricted-imports: off
|
||||
- files:
|
||||
- app/**/*.stories.*
|
||||
rules:
|
||||
'no-alert': off
|
||||
'@typescript-eslint/no-restricted-imports': off
|
||||
no-restricted-imports: off
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
import 'vitest-dom/extend-expect';
|
||||
import { render, RenderOptions } from '@testing-library/react';
|
||||
import { UIRouter, pushStateLocationPlugin } from '@uirouter/react';
|
||||
import { PropsWithChildren, ReactElement } from 'react';
|
||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
|
||||
function Provider({ children }: PropsWithChildren<unknown>) {
|
||||
return <UIRouter plugins={[pushStateLocationPlugin]}>{children}</UIRouter>;
|
||||
}
|
||||
|
||||
function customRender(ui: ReactElement, options?: RenderOptions) {
|
||||
return render(ui, { wrapper: Provider, ...options });
|
||||
}
|
||||
|
||||
// re-export everything
|
||||
export * from '@testing-library/react';
|
||||
|
||||
// override render method
|
||||
export { customRender as render };
|
||||
|
||||
export function renderWithQueryClient(ui: React.ReactElement) {
|
||||
const testQueryClient = new QueryClient({
|
||||
defaultOptions: { queries: { retry: false } },
|
||||
});
|
||||
const { rerender, ...result } = customRender(
|
||||
<QueryClientProvider client={testQueryClient}>{ui}</QueryClientProvider>
|
||||
);
|
||||
return {
|
||||
...result,
|
||||
rerender: (rerenderUi: React.ReactElement) =>
|
||||
rerender(
|
||||
<QueryClientProvider client={testQueryClient}>
|
||||
{rerenderUi}
|
||||
</QueryClientProvider>
|
||||
),
|
||||
};
|
||||
}
|
|
@ -1,13 +1,15 @@
|
|||
import { http, HttpResponse } from 'msw';
|
||||
import { render, within } from '@testing-library/react';
|
||||
|
||||
import { renderWithQueryClient, within } from '@/react-tools/test-utils';
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { server } from '@/setup-tests/server';
|
||||
import {
|
||||
createMockResourceGroups,
|
||||
createMockSubscriptions,
|
||||
} from '@/react-tools/test-mocks';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { DashboardView } from './DashboardView';
|
||||
|
||||
|
@ -105,7 +107,6 @@ async function renderComponent(
|
|||
resourceGroupsStatus = 200
|
||||
) {
|
||||
const user = new UserViewModel({ Username: 'user' });
|
||||
const state = { user };
|
||||
|
||||
server.use(
|
||||
http.get('/api/endpoints/1', () => HttpResponse.json({})),
|
||||
|
@ -135,12 +136,13 @@ async function renderComponent(
|
|||
}
|
||||
)
|
||||
);
|
||||
const renderResult = renderWithQueryClient(
|
||||
<UserContext.Provider value={state}>
|
||||
<DashboardView />
|
||||
</UserContext.Provider>
|
||||
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withUserProvider(withTestRouter(DashboardView), user)
|
||||
);
|
||||
|
||||
const renderResult = render(<Wrapped />);
|
||||
|
||||
await expect(renderResult.findByText(/Home/)).resolves.toBeVisible();
|
||||
|
||||
return renderResult;
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import userEvent from '@testing-library/user-event';
|
||||
import { HttpResponse } from 'msw';
|
||||
import { HttpResponse, http } from 'msw';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { http, server } from '@/setup-tests/server';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
import { server } from '@/setup-tests/server';
|
||||
|
||||
import { CreateContainerInstanceForm } from './CreateContainerInstanceForm';
|
||||
|
||||
|
@ -19,12 +21,10 @@ test('submit button should be disabled when name or image is missing', async ()
|
|||
server.use(http.get('/api/endpoints/5', () => HttpResponse.json({})));
|
||||
|
||||
const user = new UserViewModel({ Username: 'user' });
|
||||
|
||||
const { findByText, getByText, getByLabelText } = renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<CreateContainerInstanceForm />
|
||||
</UserContext.Provider>
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withUserProvider(withTestRouter(CreateContainerInstanceForm), user)
|
||||
);
|
||||
const { findByText, getByText, getByLabelText } = render(<Wrapped />);
|
||||
|
||||
await expect(findByText(/Azure settings/)).resolves.toBeVisible();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { render } from '@/react-tools/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { Badge } from './Badge';
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Rocket } from 'lucide-react';
|
||||
|
||||
import { render, fireEvent } from '@/react-tools/test-utils';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
|
||||
import { BoxSelector } from './BoxSelector';
|
||||
import { BoxSelectorOption, Value } from './types';
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { User } from 'lucide-react';
|
||||
|
||||
import { render } from '@/react-tools/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { DashboardItem } from './DashboardItem';
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { render } from '@/react-tools/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { DetailsTable } from './index';
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import { render } from '@testing-library/react';
|
||||
|
||||
import { createMockEnvironment } from '@/react-tools/test-mocks';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
|
||||
import { withTestQueryProvider } from '../test-utils/withTestQuery';
|
||||
|
||||
import { EdgeIndicator } from './EdgeIndicator';
|
||||
|
||||
|
@ -31,8 +34,10 @@ async function renderComponent(
|
|||
environment.EdgeCheckinInterval = checkInInterval;
|
||||
environment.QueryDate = queryDate;
|
||||
|
||||
const queries = renderWithQueryClient(
|
||||
<EdgeIndicator environment={environment} showLastCheckInDate />
|
||||
const Wrapped = withTestQueryProvider(EdgeIndicator);
|
||||
|
||||
const queries = render(
|
||||
<Wrapped environment={environment} showLastCheckInDate />
|
||||
);
|
||||
|
||||
await expect(queries.findByRole('status')).resolves.toBeVisible();
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { FormikErrors } from 'formik';
|
||||
import { ComponentProps } from 'react';
|
||||
import { HttpResponse } from 'msw';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
|
||||
import { renderWithQueryClient, fireEvent } from '@/react-tools/test-utils';
|
||||
import { http, server } from '@/setup-tests/server';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { ImageConfigFieldset } from './ImageConfigFieldset';
|
||||
import { Values } from './types';
|
||||
|
@ -16,20 +17,20 @@ vi.mock('@uirouter/react', async (importOriginal: () => Promise<object>) => ({
|
|||
}));
|
||||
|
||||
it('should render SimpleForm when useRegistry is true', () => {
|
||||
const { getByText } = render({ values: { useRegistry: true } });
|
||||
const { getByText } = renderComponent({ values: { useRegistry: true } });
|
||||
|
||||
expect(getByText('Advanced mode')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render AdvancedForm when useRegistry is false', () => {
|
||||
const { getByText } = render({ values: { useRegistry: false } });
|
||||
const { getByText } = renderComponent({ values: { useRegistry: false } });
|
||||
|
||||
expect(getByText('Simple mode')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should call setFieldValue with useRegistry set to false when "Advanced mode" button is clicked', () => {
|
||||
const setFieldValue = vi.fn();
|
||||
const { getByText } = render({
|
||||
const { getByText } = renderComponent({
|
||||
values: { useRegistry: true },
|
||||
setFieldValue,
|
||||
});
|
||||
|
@ -41,7 +42,7 @@ it('should call setFieldValue with useRegistry set to false when "Advanced mode"
|
|||
|
||||
it('should call setFieldValue with useRegistry set to true when "Simple mode" button is clicked', () => {
|
||||
const setFieldValue = vi.fn();
|
||||
const { getByText } = render({
|
||||
const { getByText } = renderComponent({
|
||||
values: { useRegistry: false },
|
||||
setFieldValue,
|
||||
});
|
||||
|
@ -51,7 +52,7 @@ it('should call setFieldValue with useRegistry set to true when "Simple mode" bu
|
|||
expect(setFieldValue).toHaveBeenCalledWith('useRegistry', true);
|
||||
});
|
||||
|
||||
function render({
|
||||
function renderComponent({
|
||||
values = {
|
||||
useRegistry: true,
|
||||
registryId: 123,
|
||||
|
@ -73,8 +74,10 @@ function render({
|
|||
http.get('/api/endpoints/:id', () => HttpResponse.json({}))
|
||||
);
|
||||
|
||||
return renderWithQueryClient(
|
||||
<ImageConfigFieldset
|
||||
const Wrapped = withTestQueryProvider(ImageConfigFieldset);
|
||||
|
||||
return render(
|
||||
<Wrapped
|
||||
values={{
|
||||
useRegistry: true,
|
||||
registryId: 123,
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { render } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
|
||||
import { NavTabs, Option } from './NavTabs';
|
||||
|
||||
|
@ -32,6 +34,7 @@ test('should show selected id content', async () => {
|
|||
});
|
||||
|
||||
test('should call onSelect when clicked with id', async () => {
|
||||
const user = userEvent.setup();
|
||||
const options = [
|
||||
{ children: 'Content 1', id: 'option1', label: 'Option 1' },
|
||||
{ children: 'Content 2', id: 'option2', label: 'Option 2' },
|
||||
|
@ -42,7 +45,7 @@ test('should call onSelect when clicked with id', async () => {
|
|||
const { findByText } = renderComponent(options, options[1].id, onSelect);
|
||||
|
||||
const heading = await findByText(options[0].label);
|
||||
await userEvent.click(heading);
|
||||
await user.click(heading);
|
||||
|
||||
expect(onSelect).toHaveBeenCalledWith(options[0].id);
|
||||
});
|
||||
|
@ -52,7 +55,9 @@ function renderComponent(
|
|||
selectedId?: string | number,
|
||||
onSelect?: (id: string | number) => void
|
||||
) {
|
||||
const Wrapped = withTestRouter(NavTabs);
|
||||
|
||||
return render(
|
||||
<NavTabs options={options} selectedId={selectedId} onSelect={onSelect} />
|
||||
<Wrapped options={options} selectedId={selectedId} onSelect={onSelect} />
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { render } from '@/react-tools/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { Breadcrumbs } from './Breadcrumbs';
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { render } from '@/react-tools/test-utils';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { HeaderContainer } from './HeaderContainer';
|
||||
import { HeaderTitle } from './HeaderTitle';
|
||||
|
@ -14,7 +15,8 @@ test('should not render without a wrapping HeaderContainer', async () => {
|
|||
|
||||
const title = 'title';
|
||||
function renderComponent() {
|
||||
return render(<HeaderTitle title={title} />);
|
||||
const Wrapped = withTestQueryProvider(HeaderTitle);
|
||||
return render(<Wrapped title={title} />);
|
||||
}
|
||||
|
||||
expect(renderComponent).toThrowErrorMatchingSnapshot();
|
||||
|
@ -25,19 +27,22 @@ test('should not render without a wrapping HeaderContainer', async () => {
|
|||
test('should display a HeaderTitle', async () => {
|
||||
const username = 'username';
|
||||
const user = new UserViewModel({ Username: username });
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
const title = 'title';
|
||||
const { queryByText } = render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<UserContext.Provider value={{ user }}>
|
||||
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withUserProvider(
|
||||
withTestRouter(() => (
|
||||
<HeaderContainer>
|
||||
<HeaderTitle title={title} />
|
||||
</HeaderContainer>
|
||||
</UserContext.Provider>
|
||||
</QueryClientProvider>
|
||||
)),
|
||||
user
|
||||
)
|
||||
);
|
||||
|
||||
const { queryByText } = render(<Wrapped />);
|
||||
|
||||
const heading = queryByText(title);
|
||||
expect(heading).toBeVisible();
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { PageHeader } from './PageHeader';
|
||||
|
||||
|
@ -8,13 +11,13 @@ test('should display a PageHeader', async () => {
|
|||
const username = 'username';
|
||||
const user = new UserViewModel({ Username: username });
|
||||
|
||||
const title = 'title';
|
||||
const { queryByText } = renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<PageHeader title={title} />
|
||||
</UserContext.Provider>
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withUserProvider(withTestRouter(PageHeader), user)
|
||||
);
|
||||
|
||||
const title = 'title';
|
||||
const { queryByText } = render(<Wrapped title={title} />);
|
||||
|
||||
const heading = queryByText(title);
|
||||
expect(heading).toBeVisible();
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { http, HttpResponse } from 'msw';
|
||||
import { Mock } from 'vitest';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { Tag, TagId } from '@/portainer/tags/types';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { server } from '@/setup-tests/server';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { TagSelector } from './TagSelector';
|
||||
|
||||
|
@ -54,8 +56,10 @@ async function renderComponent(
|
|||
) {
|
||||
server.use(http.get('/api/tags', () => HttpResponse.json(tags)));
|
||||
|
||||
const queries = renderWithQueryClient(
|
||||
<TagSelector value={value} allowCreate={allowCreate} onChange={onChange} />
|
||||
const Wrapped = withTestQueryProvider(withTestRouter(TagSelector));
|
||||
|
||||
const queries = render(
|
||||
<Wrapped value={value} allowCreate={allowCreate} onChange={onChange} />
|
||||
);
|
||||
|
||||
const tagElement = await queries.findAllByText('tags', { exact: false });
|
||||
|
|
|
@ -1,11 +1,34 @@
|
|||
import { render } from '@/react-tools/test-utils';
|
||||
import { UIView } from '@uirouter/react';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
|
||||
import { AddButton } from './AddButton';
|
||||
|
||||
function renderDefault({
|
||||
label = 'default label',
|
||||
}: Partial<{ label: string }> = {}) {
|
||||
return render(<AddButton to="">{label}</AddButton>);
|
||||
const Wrapped = withTestRouter(AddButton, {
|
||||
stateConfig: [
|
||||
{
|
||||
name: 'root',
|
||||
url: '/',
|
||||
|
||||
component: () => (
|
||||
<>
|
||||
<div>Root</div>
|
||||
<UIView />
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'root.new',
|
||||
url: 'new',
|
||||
},
|
||||
],
|
||||
route: 'root',
|
||||
});
|
||||
return render(<Wrapped to="">{label}</Wrapped>);
|
||||
}
|
||||
|
||||
test('should display a AddButton component', async () => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { fireEvent, render } from '@testing-library/react';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
|
||||
import { Button, Props } from './Button';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { render } from '@testing-library/react';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { ButtonGroup, Props } from './ButtonGroup';
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { render } from '@/react-tools/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { LoadingButton } from './LoadingButton';
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { fireEvent, render } from '@/react-tools/test-utils';
|
||||
import { fireEvent, render } from '@testing-library/react';
|
||||
|
||||
import { FileUploadField } from './FileUploadField';
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { render } from '@/react-tools/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { FileUploadForm } from './FileUploadForm';
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { render } from '@/react-tools/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { Slider, Props } from './Slider';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { render } from '@testing-library/react';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { Switch, Props } from './Switch';
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { render, fireEvent } from '@/react-tools/test-utils';
|
||||
import { render, fireEvent } from '@testing-library/react';
|
||||
|
||||
import { SwitchField, Props } from './SwitchField';
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import { UISref, UIView } from '@uirouter/react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
|
||||
function RelativePathLink() {
|
||||
return (
|
||||
<UISref to=".custom">
|
||||
<span>Link</span>
|
||||
</UISref>
|
||||
);
|
||||
}
|
||||
|
||||
test.todo('should render a link with relative path', () => {
|
||||
const WrappedComponent = withTestRouter(RelativePathLink, {
|
||||
stateConfig: [
|
||||
{
|
||||
name: 'parent',
|
||||
url: '/',
|
||||
|
||||
component: () => (
|
||||
<>
|
||||
<div>parent</div>
|
||||
<UIView />
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'parent.custom',
|
||||
url: 'custom',
|
||||
},
|
||||
],
|
||||
route: 'parent',
|
||||
});
|
||||
|
||||
render(<WrappedComponent />);
|
||||
|
||||
expect(screen.getByText('Link')).toBeInTheDocument();
|
||||
});
|
|
@ -1,9 +1,11 @@
|
|||
import { HttpResponse } from 'msw';
|
||||
import { render } from '@testing-library/react';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { http, server } from '@/setup-tests/server';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
import { server } from '@/setup-tests/server';
|
||||
|
||||
import { NetworkContainer } from '../types';
|
||||
|
||||
|
@ -32,15 +34,18 @@ test('Network container values should be visible and the link should be valid',
|
|||
server.use(http.get('/api/endpoints/1', () => HttpResponse.json({})));
|
||||
|
||||
const user = new UserViewModel({ Username: 'test', Role: 1 });
|
||||
const { findByText } = renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<NetworkContainersTable
|
||||
networkContainers={networkContainers}
|
||||
nodeName=""
|
||||
environmentId={1}
|
||||
networkId="pc8xc9s6ot043vl1q5iz4zhfs"
|
||||
/>
|
||||
</UserContext.Provider>
|
||||
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withUserProvider(withTestRouter(NetworkContainersTable), user)
|
||||
);
|
||||
|
||||
const { findByText } = render(
|
||||
<Wrapped
|
||||
networkContainers={networkContainers}
|
||||
nodeName=""
|
||||
environmentId={1}
|
||||
networkId="pc8xc9s6ot043vl1q5iz4zhfs"
|
||||
/>
|
||||
);
|
||||
|
||||
await expect(findByText('Containers in network')).resolves.toBeVisible();
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { HttpResponse, http } from 'msw';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { server } from '@/setup-tests/server';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { DockerNetwork } from '../types';
|
||||
|
||||
|
@ -26,7 +27,9 @@ test('Network details values should be visible', async () => {
|
|||
await expect(findByText(network.Driver)).resolves.toBeVisible();
|
||||
await expect(findByText(network.Scope)).resolves.toBeVisible();
|
||||
await expect(
|
||||
findByText(network.IPAM?.Config[0].Gateway || 'not found', { exact: false })
|
||||
findByText(network.IPAM?.Config[0].Gateway || 'not found', {
|
||||
exact: false,
|
||||
})
|
||||
).resolves.toBeVisible();
|
||||
await expect(
|
||||
findByText(network.IPAM?.Config[0].Subnet || 'not found', { exact: false })
|
||||
|
@ -55,13 +58,12 @@ async function renderComponent(isAdmin: boolean, network: DockerNetwork) {
|
|||
|
||||
const user = new UserViewModel({ Username: 'test', Role: isAdmin ? 1 : 2 });
|
||||
|
||||
const queries = renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<NetworkDetailsTable
|
||||
network={network}
|
||||
onRemoveNetworkClicked={() => {}}
|
||||
/>
|
||||
</UserContext.Provider>
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withUserProvider(NetworkDetailsTable, user)
|
||||
);
|
||||
|
||||
const queries = render(
|
||||
<Wrapped network={network} onRemoveNetworkClicked={() => {}} />
|
||||
);
|
||||
|
||||
await expect(queries.findByText('Network details')).resolves.toBeVisible();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { render } from '@/react-tools/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { NetworkOptions } from '../types';
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { render, screen } from '@/react-tools/test-utils';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import {
|
||||
EnvVarType,
|
||||
TemplateViewModel,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { vi } from 'vitest';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { render, screen } from '@/react-tools/test-utils';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import {
|
||||
EnvVarsFieldset,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { vi } from 'vitest';
|
||||
|
||||
import { render, screen } from '@/react-tools/test-utils';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { TemplateNote } from './TemplateNote';
|
||||
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
import { vi } from 'vitest';
|
||||
import { HttpResponse, http } from 'msw';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { renderWithQueryClient, screen } from '@/react-tools/test-utils';
|
||||
import { AppTemplate } from '@/react/portainer/templates/app-templates/types';
|
||||
import { CustomTemplate } from '@/react/portainer/templates/custom-templates/types';
|
||||
import { server } from '@/setup-tests/server';
|
||||
import selectEvent from '@/react/test-utils/react-select';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { SelectedTemplateValue } from './types';
|
||||
import { TemplateSelector } from './TemplateSelector';
|
||||
|
||||
test('renders TemplateSelector component', async () => {
|
||||
render();
|
||||
renderComponent();
|
||||
|
||||
const templateSelectorElement = screen.getByLabelText('Template');
|
||||
expect(templateSelectorElement).toBeInTheDocument();
|
||||
|
@ -30,7 +31,7 @@ test.skip('selects an edge app template', async () => {
|
|||
categories: ['edge'],
|
||||
};
|
||||
|
||||
const { select } = render({
|
||||
const { select } = renderComponent({
|
||||
onChange,
|
||||
appTemplates: [
|
||||
{
|
||||
|
@ -59,7 +60,7 @@ test.skip('selects an edge custom template', async () => {
|
|||
Id: 2,
|
||||
};
|
||||
|
||||
const { select } = render({
|
||||
const { select } = renderComponent({
|
||||
onChange,
|
||||
customTemplates: [
|
||||
{
|
||||
|
@ -75,7 +76,7 @@ test.skip('selects an edge custom template', async () => {
|
|||
});
|
||||
|
||||
test('renders with error', async () => {
|
||||
render({
|
||||
renderComponent({
|
||||
error: 'Invalid template',
|
||||
});
|
||||
|
||||
|
@ -87,7 +88,7 @@ test('renders with error', async () => {
|
|||
});
|
||||
|
||||
test.skip('renders TemplateSelector component with no custom templates available', async () => {
|
||||
render({
|
||||
renderComponent({
|
||||
customTemplates: [],
|
||||
});
|
||||
|
||||
|
@ -102,7 +103,7 @@ test.skip('renders TemplateSelector component with no custom templates available
|
|||
expect(noCustomTemplatesElement).toBeInTheDocument();
|
||||
});
|
||||
|
||||
function render({
|
||||
function renderComponent({
|
||||
onChange = vi.fn(),
|
||||
appTemplates = [],
|
||||
customTemplates = [],
|
||||
|
@ -123,8 +124,10 @@ function render({
|
|||
)
|
||||
);
|
||||
|
||||
renderWithQueryClient(
|
||||
<TemplateSelector
|
||||
const Wrapped = withTestQueryProvider(TemplateSelector);
|
||||
|
||||
render(
|
||||
<Wrapped
|
||||
value={{ template: undefined, type: undefined }}
|
||||
onChange={onChange}
|
||||
error={error}
|
||||
|
|
|
@ -1,20 +1,17 @@
|
|||
import { http, HttpResponse } from 'msw';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { server } from '@/setup-tests/server';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { isoDate } from '@/portainer/filters/filters';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { BackupFailedPanel } from './BackupFailedPanel';
|
||||
|
||||
test('when backup failed, should show message', async () => {
|
||||
const timestamp = 1500;
|
||||
server.use(
|
||||
http.get('/api/backup/s3/status', () =>
|
||||
HttpResponse.json({ Failed: true, TimestampUTC: timestamp })
|
||||
)
|
||||
);
|
||||
|
||||
const { findByText } = renderWithQueryClient(<BackupFailedPanel />);
|
||||
const { findByText } = renderComponent({ failed: true, timestamp });
|
||||
|
||||
await expect(
|
||||
findByText(
|
||||
|
@ -27,14 +24,27 @@ test('when backup failed, should show message', async () => {
|
|||
});
|
||||
|
||||
test("when user is using less nodes then allowed he shouldn't see message", async () => {
|
||||
server.use(
|
||||
http.get('/api/backup/s3/status', () =>
|
||||
HttpResponse.json({ Failed: false })
|
||||
)
|
||||
);
|
||||
const { findByText } = renderWithQueryClient(<BackupFailedPanel />);
|
||||
const { findByText } = renderComponent({ failed: false });
|
||||
|
||||
await expect(
|
||||
findByText('The latest automated backup has failed at', { exact: false })
|
||||
).rejects.toBeTruthy();
|
||||
});
|
||||
|
||||
function renderComponent({
|
||||
failed,
|
||||
timestamp,
|
||||
}: {
|
||||
failed: boolean;
|
||||
timestamp?: number;
|
||||
}) {
|
||||
server.use(
|
||||
http.get('/api/backup/s3/status', () =>
|
||||
HttpResponse.json({ Failed: failed, TimestampUTC: timestamp })
|
||||
)
|
||||
);
|
||||
|
||||
const Wrapped = withTestQueryProvider(withTestRouter(BackupFailedPanel));
|
||||
|
||||
return render(<Wrapped />);
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import { http, HttpResponse } from 'msw';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import {
|
||||
EnvironmentGroup,
|
||||
EnvironmentGroupId,
|
||||
} from '@/react/portainer/environments/environment-groups/types';
|
||||
import { Environment } from '@/react/portainer/environments/types';
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { Tag } from '@/portainer/tags/types';
|
||||
import { createMockEnvironment } from '@/react-tools/test-mocks';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { server } from '@/setup-tests/server';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { EnvironmentItem } from './EnvironmentItem';
|
||||
|
||||
|
@ -43,15 +45,17 @@ function renderComponent(
|
|||
|
||||
server.use(http.get('/api/tags', () => HttpResponse.json(tags)));
|
||||
|
||||
return renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<EnvironmentItem
|
||||
isActive={false}
|
||||
onClickBrowse={() => {}}
|
||||
onClickDisconnect={() => {}}
|
||||
environment={env}
|
||||
groupName={group.Name}
|
||||
/>
|
||||
</UserContext.Provider>
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withTestRouter(withUserProvider(EnvironmentItem, user))
|
||||
);
|
||||
|
||||
return render(
|
||||
<Wrapped
|
||||
isActive={false}
|
||||
onClickBrowse={() => {}}
|
||||
onClickDisconnect={() => {}}
|
||||
environment={env}
|
||||
groupName={group.Name}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import { http, HttpResponse } from 'msw';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { Environment } from '@/react/portainer/environments/types';
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { server } from '@/setup-tests/server';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { EnvironmentList } from './EnvironmentList';
|
||||
|
||||
|
@ -49,10 +51,12 @@ async function renderComponent(
|
|||
)
|
||||
);
|
||||
|
||||
const queries = renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<EnvironmentList onClickBrowse={vi.fn()} onRefresh={vi.fn()} />
|
||||
</UserContext.Provider>
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withUserProvider(withTestRouter(EnvironmentList), user)
|
||||
);
|
||||
|
||||
const queries = render(
|
||||
<Wrapped onClickBrowse={vi.fn()} onRefresh={vi.fn()} />
|
||||
);
|
||||
|
||||
await expect(queries.findByText('Environments')).resolves.toBeVisible();
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { http, HttpResponse } from 'msw';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { server } from '@/setup-tests/server';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { LicenseType } from '../licenses/types';
|
||||
|
||||
|
@ -17,7 +18,7 @@ test('when user is using more nodes then allowed he should see message', async (
|
|||
http.get('/api/system/nodes', () => HttpResponse.json({ nodes: used }))
|
||||
);
|
||||
|
||||
const { findByText } = renderWithQueryClient(<LicenseNodePanel />);
|
||||
const { findByText } = renderComponent();
|
||||
|
||||
await expect(
|
||||
findByText(
|
||||
|
@ -36,7 +37,7 @@ test("when user is using less nodes then allowed he shouldn't see message", asyn
|
|||
http.get('/api/system/nodes', () => HttpResponse.json({ nodes: used }))
|
||||
);
|
||||
|
||||
const { findByText } = renderWithQueryClient(<LicenseNodePanel />);
|
||||
const { findByText } = renderComponent();
|
||||
|
||||
await expect(
|
||||
findByText(
|
||||
|
@ -44,3 +45,9 @@ test("when user is using less nodes then allowed he shouldn't see message", asyn
|
|||
)
|
||||
).rejects.toBeTruthy();
|
||||
});
|
||||
|
||||
function renderComponent() {
|
||||
const Wrapped = withTestQueryProvider(LicenseNodePanel);
|
||||
|
||||
return render(<Wrapped />);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import { Meta, Story } from '@storybook/react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { Role, User } from '@/portainer/users/types';
|
||||
import { isPureAdmin } from '@/portainer/users/user.helpers';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
|
||||
import { parseAccessControlFormData } from '../utils';
|
||||
|
||||
|
@ -16,41 +17,25 @@ const meta: Meta = {
|
|||
|
||||
export default meta;
|
||||
|
||||
enum Role {
|
||||
Admin = 1,
|
||||
User,
|
||||
}
|
||||
|
||||
const testQueryClient = new QueryClient({
|
||||
defaultOptions: { queries: { retry: false } },
|
||||
});
|
||||
|
||||
interface Args {
|
||||
userRole: Role;
|
||||
}
|
||||
|
||||
function Template({ userRole }: Args) {
|
||||
const isAdmin = userRole === Role.Admin;
|
||||
const defaults = parseAccessControlFormData(isAdmin, 0);
|
||||
const defaults = parseAccessControlFormData(
|
||||
isPureAdmin({ Role: userRole } as User),
|
||||
0
|
||||
);
|
||||
|
||||
const [value, setValue] = useState(defaults);
|
||||
|
||||
const userProviderState = useMemo(
|
||||
() => ({ user: new UserViewModel({ Role: userRole }) }),
|
||||
[userRole]
|
||||
const Wrapped = withUserProvider(
|
||||
AccessControlForm,
|
||||
new UserViewModel({ Role: userRole })
|
||||
);
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={testQueryClient}>
|
||||
<UserContext.Provider value={userProviderState}>
|
||||
<AccessControlForm
|
||||
values={value}
|
||||
onChange={setValue}
|
||||
errors={{}}
|
||||
environmentId={1}
|
||||
/>
|
||||
</UserContext.Provider>
|
||||
</QueryClientProvider>
|
||||
<Wrapped values={value} onChange={setValue} errors={{}} environmentId={1} />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -61,5 +46,5 @@ AdminAccessControl.args = {
|
|||
|
||||
export const NonAdminAccessControl: Story<Args> = Template.bind({});
|
||||
NonAdminAccessControl.args = {
|
||||
userRole: Role.User,
|
||||
userRole: Role.Standard,
|
||||
};
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import { http, HttpResponse } from 'msw';
|
||||
import { render, within } from '@testing-library/react';
|
||||
|
||||
import { server } from '@/setup-tests/server';
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { renderWithQueryClient, within } from '@/react-tools/test-utils';
|
||||
import { Team, TeamId } from '@/react/portainer/users/teams/types';
|
||||
import { createMockTeams } from '@/react-tools/test-mocks';
|
||||
import { UserId } from '@/portainer/users/types';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
|
||||
import { ResourceControlOwnership, AccessControlFormData } from '../types';
|
||||
import { ResourceControlViewModel } from '../models/ResourceControlViewModel';
|
||||
|
@ -304,7 +306,6 @@ async function renderComponent(
|
|||
{ isAdmin = false, hideTitle = false, teams, users }: AdditionalProps = {}
|
||||
) {
|
||||
const user = new UserViewModel({ Username: 'user', Role: isAdmin ? 1 : 2 });
|
||||
const state = { user };
|
||||
|
||||
if (teams) {
|
||||
server.use(http.get('/api/teams', () => HttpResponse.json(teams)));
|
||||
|
@ -314,16 +315,18 @@ async function renderComponent(
|
|||
server.use(http.get('/api/users', () => HttpResponse.json(users)));
|
||||
}
|
||||
|
||||
const renderResult = renderWithQueryClient(
|
||||
<UserContext.Provider value={state}>
|
||||
<AccessControlForm
|
||||
environmentId={1}
|
||||
errors={{}}
|
||||
values={values}
|
||||
onChange={onChange}
|
||||
hideTitle={hideTitle}
|
||||
/>
|
||||
</UserContext.Provider>
|
||||
const Wrapped = withTestRouter(
|
||||
withTestQueryProvider(withUserProvider(AccessControlForm, user))
|
||||
);
|
||||
|
||||
const renderResult = render(
|
||||
<Wrapped
|
||||
environmentId={1}
|
||||
errors={{}}
|
||||
values={values}
|
||||
onChange={onChange}
|
||||
hideTitle={hideTitle}
|
||||
/>
|
||||
);
|
||||
|
||||
await expect(
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import _ from 'lodash';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { createMockTeams, createMockUsers } from '@/react-tools/test-mocks';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { server } from '@/setup-tests/server';
|
||||
import { Role } from '@/portainer/users/types';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import {
|
||||
ResourceControlOwnership,
|
||||
|
@ -145,9 +147,11 @@ async function renderComponent(
|
|||
resourceType: ResourceControlType = ResourceControlType.Container,
|
||||
resourceControl?: ResourceControlViewModel
|
||||
) {
|
||||
const WithUser = withUserProvider(AccessControlPanelDetails);
|
||||
const queries = renderWithQueryClient(
|
||||
<WithUser resourceControl={resourceControl} resourceType={resourceType} />
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withTestRouter(withUserProvider(AccessControlPanelDetails))
|
||||
);
|
||||
const queries = render(
|
||||
<Wrapped resourceControl={resourceControl} resourceType={resourceType} />
|
||||
);
|
||||
await expect(queries.findByText('Ownership')).resolves.toBeVisible();
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import userEvent from '@testing-library/user-event';
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
|
||||
import { renderWithQueryClient, waitFor } from '@/react-tools/test-utils';
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { CreateUserAccessToken } from './CreateUserAccessToken';
|
||||
|
||||
|
@ -33,9 +35,9 @@ test('the button is disabled when all fields are blank and enabled when all fiel
|
|||
function renderComponent() {
|
||||
const user = new UserViewModel({ Username: 'user' });
|
||||
|
||||
return renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<CreateUserAccessToken />
|
||||
</UserContext.Provider>
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withUserProvider(withTestRouter(CreateUserAccessToken), user)
|
||||
);
|
||||
|
||||
return render(<Wrapped />);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { vi } from 'vitest';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { render, screen } from '@/react-tools/test-utils';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import {
|
||||
CustomTemplatesVariablesField,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { vi } from 'vitest';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { render, screen } from '@/react-tools/test-utils';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { VariableFieldItem } from './VariableFieldItem';
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import userEvent from '@testing-library/user-event';
|
||||
import { PropsWithChildren } from 'react';
|
||||
|
||||
import { render } from '@/react-tools/test-utils';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { AppTemplatesListItem } from './AppTemplatesListItem';
|
||||
import { TemplateViewModel } from './view-model';
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
|
||||
import { TeamAssociationSelector } from './TeamAssociationSelector';
|
||||
|
||||
|
@ -13,9 +15,9 @@ test('renders correctly', () => {
|
|||
function renderComponent() {
|
||||
const user = new UserViewModel({ Username: 'user' });
|
||||
|
||||
return renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<TeamAssociationSelector users={[]} memberships={[]} teamId={3} />
|
||||
</UserContext.Provider>
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withUserProvider(TeamAssociationSelector, user)
|
||||
);
|
||||
|
||||
return render(<Wrapped users={[]} memberships={[]} teamId={3} />);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { TeamMembersList } from './TeamMembersList';
|
||||
|
||||
|
@ -13,11 +15,11 @@ test('renders correctly', () => {
|
|||
function renderComponent() {
|
||||
const user = new UserViewModel({ Username: 'user' });
|
||||
|
||||
return renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<TeamMembersList users={[]} roles={{}} teamId={3} />
|
||||
</UserContext.Provider>
|
||||
const Wrapped = withTestQueryProvider(
|
||||
withUserProvider(TeamMembersList, user)
|
||||
);
|
||||
|
||||
return render(<Wrapped users={[]} roles={{}} teamId={3} />);
|
||||
}
|
||||
|
||||
test.todo('when users list is empty, add all users button is disabled');
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { renderWithQueryClient } from '@/react-tools/test-utils';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
|
||||
import { UsersList } from './UsersList';
|
||||
|
||||
|
@ -12,11 +14,10 @@ test('renders correctly', () => {
|
|||
|
||||
function renderComponent() {
|
||||
const user = new UserViewModel({ Username: 'user' });
|
||||
return renderWithQueryClient(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<UsersList users={[]} teamId={3} />
|
||||
</UserContext.Provider>
|
||||
);
|
||||
|
||||
const Wrapped = withTestQueryProvider(withUserProvider(UsersList, user));
|
||||
|
||||
return render(<Wrapped users={[]} teamId={3} />);
|
||||
}
|
||||
|
||||
test.todo('when users list is empty, add all users button is disabled');
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
import userEvent from '@testing-library/user-event';
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
|
||||
import { renderWithQueryClient, waitFor } from '@/react-tools/test-utils';
|
||||
import { withTestQueryProvider } from '@/react/test-utils/withTestQuery';
|
||||
|
||||
import { CreateTeamForm } from './CreateTeamForm';
|
||||
|
||||
test('filling the name should make the submit button clickable and emptying it should make it disabled', async () => {
|
||||
const { findByLabelText, findByText } = renderWithQueryClient(
|
||||
<CreateTeamForm users={[]} teams={[]} />
|
||||
const Wrapped = withTestQueryProvider(CreateTeamForm);
|
||||
|
||||
const { findByLabelText, findByText } = render(
|
||||
<Wrapped users={[]} teams={[]} />
|
||||
);
|
||||
|
||||
const button = await findByText('Create team');
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { UserContext } from '@/react/hooks/useUser';
|
||||
import { render, within } from '@testing-library/react';
|
||||
|
||||
import { UserViewModel } from '@/portainer/models/user';
|
||||
import { render, within } from '@/react-tools/test-utils';
|
||||
import { withUserProvider } from '@/react/test-utils/withUserProvider';
|
||||
import { withTestRouter } from '@/react/test-utils/withRouter';
|
||||
|
||||
import { TestSidebarProvider } from '../useSidebarState';
|
||||
|
||||
|
@ -30,11 +32,11 @@ test('dashboard items should render correctly', () => {
|
|||
function renderComponent() {
|
||||
const user = new UserViewModel({ Username: 'user' });
|
||||
|
||||
const Wrapped = withUserProvider(withTestRouter(AzureSidebar), user);
|
||||
|
||||
return render(
|
||||
<UserContext.Provider value={{ user }}>
|
||||
<TestSidebarProvider>
|
||||
<AzureSidebar environmentId={1} />
|
||||
</TestSidebarProvider>
|
||||
</UserContext.Provider>
|
||||
<TestSidebarProvider>
|
||||
<Wrapped environmentId={1} />
|
||||
</TestSidebarProvider>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import { ComponentType } from 'react';
|
||||
import {
|
||||
ReactStateDeclaration,
|
||||
UIRouter,
|
||||
UIRouterReact,
|
||||
UIView,
|
||||
hashLocationPlugin,
|
||||
servicesPlugin,
|
||||
} from '@uirouter/react';
|
||||
|
||||
/**
|
||||
* A helper function to wrap a component with a UIRouter Provider.
|
||||
*
|
||||
* should only be used in tests
|
||||
*/
|
||||
export function withTestRouter<T>(
|
||||
WrappedComponent: ComponentType<T>,
|
||||
{
|
||||
route = '/',
|
||||
stateConfig = [],
|
||||
}: { route?: string; stateConfig?: Array<ReactStateDeclaration> } = {}
|
||||
): ComponentType<T> {
|
||||
const router = new UIRouterReact();
|
||||
|
||||
// router.trace.enable(Category.TRANSITION);
|
||||
router.plugin(servicesPlugin);
|
||||
router.plugin(hashLocationPlugin);
|
||||
|
||||
// Set up your custom state configuration
|
||||
stateConfig.forEach((state) => router.stateRegistry.register(state));
|
||||
router.urlService.rules.initial({ state: route });
|
||||
|
||||
// Try to create a nice displayName for React Dev Tools.
|
||||
const displayName =
|
||||
WrappedComponent.displayName || WrappedComponent.name || 'Component';
|
||||
|
||||
function WrapperComponent(props: T & JSX.IntrinsicAttributes) {
|
||||
return (
|
||||
<UIRouter router={router}>
|
||||
<UIView />
|
||||
<WrappedComponent {...props} />
|
||||
</UIRouter>
|
||||
);
|
||||
}
|
||||
|
||||
WrapperComponent.displayName = `withTestRouter(${displayName})`;
|
||||
|
||||
return WrapperComponent;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { ComponentType } from 'react';
|
||||
import { QueryClient } from 'react-query';
|
||||
|
||||
import { withReactQuery } from '@/react-tools/withReactQuery';
|
||||
|
||||
export function withTestQueryProvider<T>(
|
||||
WrappedComponent: ComponentType<T & JSX.IntrinsicAttributes>
|
||||
) {
|
||||
const testQueryClient = new QueryClient({
|
||||
defaultOptions: { queries: { retry: false } },
|
||||
});
|
||||
|
||||
return withReactQuery(WrappedComponent, testQueryClient);
|
||||
}
|
|
@ -11,6 +11,7 @@ import { StatusResponse } from '@/react/portainer/system/useSystemStatus';
|
|||
import { createMockTeams } from '@/react-tools/test-mocks';
|
||||
import { PublicSettingsResponse } from '@/react/portainer/settings/types';
|
||||
import { UserId } from '@/portainer/users/types';
|
||||
import { VersionResponse } from '@/react/portainer/system/useSystemVersion';
|
||||
|
||||
import { azureHandlers } from './setup-handlers/azure';
|
||||
import { dockerHandlers } from './setup-handlers/docker';
|
||||
|
@ -85,6 +86,9 @@ export const handlers = [
|
|||
http.get<never, never, Partial<StatusResponse>>('/api/status', () =>
|
||||
HttpResponse.json({})
|
||||
),
|
||||
http.get<never, never, Partial<VersionResponse>>('/api/system/version', () =>
|
||||
HttpResponse.json({ ServerVersion: 'v2.10.0' })
|
||||
),
|
||||
http.get('/api/teams/:id/memberships', () => HttpResponse.json([])),
|
||||
http.get('/api/endpoints/agent_versions', () => HttpResponse.json([])),
|
||||
];
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
import 'vitest-dom/extend-expect';
|
|
@ -7,7 +7,7 @@ export default defineConfig({
|
|||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
setupFiles: ['./app/setup-tests/setup-msw.ts', './app/setup-tests/stub-modules.ts'],
|
||||
setupFiles: ['./app/setup-tests/setup-msw.ts', './app/setup-tests/stub-modules.ts', './app/setup-tests/setup.ts'],
|
||||
coverage: {
|
||||
reporter: ['text', 'html'],
|
||||
exclude: ['node_modules/', 'app/setup-tests/global-setup.js'],
|
||||
|
|
Loading…
Reference in New Issue