Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test/area coordinates #264

Merged
merged 6 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/components/AreaCoordinates/AreaCoordinates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ModelAreaTypeDto,
} from '../../api/generated';
import Img from '../../features/ModelView/image.png';
import { useFetchCases } from '../../hooks/useFetchCases';
import { useFetchModel } from '../../hooks/useFetchModel';
import { useFetchModelAreas } from '../../hooks/useFetchModelAreas';
import { useMutateAreaCoordinates } from '../../hooks/useMutateAreaCoordinates';
Expand Down Expand Up @@ -85,7 +86,11 @@ export const AreaCoordinates = ({
useState<AreaCoordinateType>();
const { modelId } = useParams();
const { data, isLoading } = useFetchModel(modelId);
const { activeAreaResultList } = useModelResults(activeArea.name);
const cases = useFetchCases();
const { activeAreaResultList } = useModelResults(
activeArea.name,
cases.data?.data,
);
const modelAreas = useFetchModelAreas();
const mutateAreaCoordinates = useMutateAreaCoordinates();

Expand Down Expand Up @@ -282,7 +287,7 @@ export const AreaCoordinates = ({
></Autocomplete>
</Styled.CoordinateGroup>

{activeArea.modelAreaTypeId !== '' && (
{activeArea.name !== '' && (
<Styled.CoordinateFields>
<Styled.CoordinateGroup>
<Typography variant="h6">Top Left Corner</Typography>
Expand Down
13 changes: 7 additions & 6 deletions src/components/AreaCoordinates/hooks/useModelResults.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useFetchCases } from '../../../hooks/useFetchCases';

export const useModelResults = (activeArea: string) => {
const cases = useFetchCases();
import { ComputeCaseDto } from '../../../api/generated';

export const useModelResults = (
activeArea: string,
cases: ComputeCaseDto[] | undefined,
) => {
const activeAreaResultList =
cases.data &&
cases.data.data
cases &&
cases
.filter((c) => c.modelArea !== null)
.filter((ca) => ca.modelArea.name === activeArea);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* eslint-disable max-lines-per-function */
import { MsalProvider } from '@azure/msal-react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
import { MsalReactTester } from 'msal-react-tester';
import { AreaCoordinates } from '../AreaCoordinates';

import { useFetchCases } from '../../../hooks/useFetchCases';
import { useFetchModel } from '../../../hooks/useFetchModel';
import { useFetchModelAreas } from '../../../hooks/useFetchModelAreas';
import { useModelResults } from '../hooks/useModelResults';

import {
mockAnalogueModelDetail,
mockedActiveComputeCase,
mockedComputeCase,
mockedModelAreaType,
} from './mockedData';

let msalTester: MsalReactTester;

beforeEach(() => {
// new instance of msal tester for each test
msalTester = new MsalReactTester();
// spy all required msal things
msalTester.spyMsal();
});

afterEach(() => {
cleanup();
msalTester.resetSpyMsal();
jest.clearAllMocks();
});

jest.mock('../../../hooks/useFetchCases');
jest.mock('../../../hooks/useFetchModel');
jest.mock('../../../hooks/useFetchModelAreas');
jest.mock('../hooks/useModelResults');

const Render = () => {
const testQueryClient = new QueryClient();

// @ts-ignore because of error
useFetchCases.mockReturnValue({
data: mockedComputeCase,
success: true,
isLoading: false,
isSuccess: true,
isError: false,
});

// @ts-ignore because of error
useFetchModel.mockReturnValue({
data: mockAnalogueModelDetail,
success: true,
isLoading: false,
isSuccess: true,
isError: false,
});

// @ts-ignore because of error
useFetchModelAreas.mockReturnValue({
data: mockedModelAreaType,
success: true,
isLoading: false,
isSuccess: true,
isError: false,
});

// @ts-ignore because of error
useModelResults.mockReturnValue(mockedActiveComputeCase);

return (
<MsalProvider instance={msalTester.client}>
<QueryClientProvider client={testQueryClient}>
<AreaCoordinates setSaveAlert={jest.fn()} />
</QueryClientProvider>
</MsalProvider>
);
};

test('renders Area Coordinates component after loading in an empty state', async () => {
render(<Render />);

const nameLable = screen.getByLabelText('Select area', {
selector: 'input',
});
expect(nameLable).toBeInTheDocument();
expect(nameLable).toHaveValue('');

expect(screen.queryByText('Top Left Corner')).not.toBeInTheDocument();
expect(screen.queryByText('Edit coordinates')).not.toBeInTheDocument();
});

test('Select area Autocomplete updates correct on model area select', async () => {
render(<Render />);

const nameLable = screen.getByLabelText('Select area', {
selector: 'input',
});

expect(nameLable).toHaveValue('');

fireEvent.change(nameLable, {
target: {
value: mockedModelAreaType[0].name,
},
});
fireEvent.keyDown(nameLable, { key: 'Enter', code: 'Enter' });
expect(nameLable).toHaveValue(mockedModelAreaType[0].name);

fireEvent.change(nameLable, {
target: {
value: mockedModelAreaType[1].name,
},
});
fireEvent.keyDown(nameLable, { key: 'Enter', code: 'Enter' });
expect(nameLable).toHaveValue(mockedModelAreaType[1].name);
});
122 changes: 122 additions & 0 deletions src/components/AreaCoordinates/tests/AreaCoordinates.hooks.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/* eslint-disable testing-library/render-result-naming-convention */
/* eslint-disable max-lines-per-function */
import { MsalProvider } from '@azure/msal-react';
import * as ReactQuery from '@tanstack/react-query';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { cleanup, renderHook, screen, waitFor } from '@testing-library/react';
import { MsalReactTester } from 'msal-react-tester';
import { useFetchCases } from '../../../hooks/useFetchCases';
import { useFetchModel } from '../../../hooks/useFetchModel';
import { useFetchModelAreas } from '../../../hooks/useFetchModelAreas';
import { AreaCoordinates } from '../AreaCoordinates';
import { useModelResults } from '../hooks/useModelResults';
import {
defaultArea,
mockAnalogueModelDetail,
mockedComputeCase,
mockedModelAreaType,
modelId,
} from './mockedData';

let msalTester: MsalReactTester;

function wrapper(props: { children: React.ReactNode }) {
const testQueryClient = new QueryClient();
return (
<MsalProvider instance={msalTester.client}>
<QueryClientProvider client={testQueryClient}>
{props.children}
<AreaCoordinates setSaveAlert={jest.fn()} />
</QueryClientProvider>
</MsalProvider>
);
}

const mockGetData = async (data: any) => {
const mock = jest.spyOn(ReactQuery, 'useQuery');

// @ts-ignore because of error
mock.mockImplementation(() => {
return data
? Promise.resolve({
data: data,
isLoading: false,
isSuccess: true,
isError: false,
})
: Promise.reject('error');
});

return mock;
};

beforeEach(() => {
// new instance of msal tester for each test
msalTester = new MsalReactTester();

// spy all required msal things
msalTester.spyMsal();
});

afterEach(() => {
cleanup();
msalTester.resetSpyMsal();
jest.clearAllMocks();
});

test('Calls fetchModel api with mock data', async () => {
const mock = await mockGetData(mockAnalogueModelDetail);

const { result } = renderHook(() => useFetchModel(modelId), { wrapper });

const res = await result.current;

await waitFor(() => expect(mock).toHaveBeenCalled());
await waitFor(() => expect(res.data).toBe(mockAnalogueModelDetail));
});

test('Calls fetchCases api with mock data', async () => {
const mock = await mockGetData(mockedComputeCase);

const { result } = renderHook(() => useFetchCases(), { wrapper });

const res = await result.current;

await waitFor(() => expect(mock).toHaveBeenCalled());
await waitFor(() => expect(res.data).toBe(mockedComputeCase));
});

test('Calls useModelResult hook with mock data', async () => {
const mock = await mockGetData(mockedComputeCase);

const { result } = renderHook(
() => useModelResults(defaultArea.name, [mockedComputeCase]),
{ wrapper },
);

const res = await result.current;

await waitFor(() => expect(mock).toHaveBeenCalled());
await waitFor(() => expect(res.activeAreaResultList).toHaveLength(1));
});

test('Calls useFetchModelAreas hook with mock data', async () => {
const mock = await mockGetData(mockedModelAreaType);

const { result } = renderHook(() => useFetchModelAreas(), { wrapper });

const res = await result.current;

await waitFor(() => expect(mock).toHaveBeenCalled());
await waitFor(() => expect(res.data).toBe(mockedModelAreaType));
});

test('renders AreaCoordinates component in loading state', async () => {
await mockGetData(mockAnalogueModelDetail);

const { result } = renderHook(() => useFetchModel(modelId), { wrapper });
await result.current;

const loading = screen.getByText('Loading.....');
expect(loading).toBeVisible();
});
Loading
Loading