test: deprecate react-unit-test-utils part-2 (#428)

This commit is contained in:
Victor Navarro
2025-06-11 06:28:54 -06:00
committed by GitHub
parent 5a383479ff
commit b54e8ffc85
10 changed files with 153 additions and 227 deletions

View File

@@ -1,10 +1,10 @@
import React from 'react';
import { shallow } from '@edx/react-unit-test-utils';
import { render, screen } from '@testing-library/react';
import ErrorBanner from './ErrorBanner';
import messages from '../messages';
jest.unmock('@openedx/paragon');
jest.unmock('react');
describe('Error Banner component', () => {
const children = <p>Abitary Child</p>;
@@ -25,39 +25,29 @@ describe('Error Banner component', () => {
children,
};
let el;
beforeEach(() => {
el = shallow(<ErrorBanner {...props} />);
});
test('snapshot', () => {
expect(el.snapshot).toMatchSnapshot();
});
describe('component', () => {
test('children node', () => {
const childElement = el.instance.children[1];
const child = shallow(children);
expect(childElement.type).toEqual(child.type);
expect(childElement.children[0].el).toEqual(child.children[0].el);
describe('behavior', () => {
it('renders children content', () => {
render(<ErrorBanner {...props} />);
const childText = screen.getByText('Abitary Child');
expect(childText).toBeInTheDocument();
});
test('verify actions', () => {
const { actions } = el.instance.findByType('Alert')[0].props;
expect(actions).toHaveLength(props.actions.length);
actions.forEach((action, index) => {
expect(action.type).toEqual('Button');
expect(action.props.onClick).toEqual(props.actions[index].onClick);
// action message
expect(action.props.children.props).toEqual(props.actions[index].message);
});
it('renders the correct number of action buttons', () => {
render(<ErrorBanner {...props} />);
const buttons = screen.getAllByText('FormattedMessage');
expect(buttons).toHaveLength(3);
});
test('verify heading', () => {
const heading = el.instance.findByType('FormattedMessage')[0];
expect(heading.props).toEqual(props.headingMessage);
it('renders error heading with correct message', () => {
render(<ErrorBanner {...props} />);
const heading = screen.getAllByText('FormattedMessage')[0];
expect(heading).toBeInTheDocument();
});
it('renders with danger variant', () => {
render(<ErrorBanner {...props} />);
const alert = screen.getByRole('alert');
expect(alert).toHaveClass('alert-danger');
});
});
});

View File

@@ -1,11 +1,22 @@
import React from 'react';
import { shallow } from '@edx/react-unit-test-utils';
import { render, screen } from '@testing-library/react';
import LoadingBanner from './LoadingBanner';
jest.unmock('@openedx/paragon');
jest.unmock('react');
describe('Loading Banner component', () => {
test('snapshot', () => {
const el = shallow(<LoadingBanner />);
expect(el.snapshot).toMatchSnapshot();
describe('behavior', () => {
it('renders an info alert', () => {
render(<LoadingBanner />);
const alert = screen.getByRole('alert');
expect(alert).toHaveClass('alert-info');
});
it('renders a spinner', () => {
const { container } = render(<LoadingBanner />);
const spinner = container.querySelector('.pgn__spinner');
expect(spinner).toBeInTheDocument();
expect(spinner).toHaveClass('spinner-border');
});
});
});

View File

@@ -1,42 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Error Banner component snapshot 1`] = `
<Alert
actions={
[
<Button
onClick={[MockFunction action1.onClick]}
variant="outline-primary"
>
<FormattedMessage
defaultMessage="Retry"
description="Retry button for error in file renderer"
id="ora-grading.ResponseDisplay.FileRenderer.retryButton"
/>
</Button>,
<Button
onClick={[MockFunction action2.onClick]}
variant="outline-primary"
>
<FormattedMessage
defaultMessage="Retry"
description="Retry button for error in file renderer"
id="ora-grading.ResponseDisplay.FileRenderer.retryButton"
/>
</Button>,
]
}
variant="danger"
>
<Alert.Heading>
<FormattedMessage
defaultMessage="Unknown errors"
description="Unknown errors message"
id="ora-grading.ResponseDisplay.FileRenderer.unknownError"
/>
</Alert.Heading>
<p>
Abitary Child
</p>
</Alert>
`;

View File

@@ -1,12 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Loading Banner component snapshot 1`] = `
<Alert
variant="info"
>
<Spinner
animation="border"
className="d-flex m-auto"
/>
</Alert>
`;

View File

@@ -1,21 +1,43 @@
import React from 'react';
import { shallow } from '@edx/react-unit-test-utils';
import { render, screen } from '@testing-library/react';
import ImageRenderer from './ImageRenderer';
jest.unmock('@openedx/paragon');
jest.unmock('react');
describe('Image Renderer Component', () => {
const props = {
url: 'some_url.jpg',
fileName: 'test-image.jpg',
onError: jest.fn().mockName('this.props.onError'),
onSuccess: jest.fn().mockName('this.props.onSuccess'),
};
props.onError = jest.fn().mockName('this.props.onError');
props.onSuccess = jest.fn().mockName('this.props.onSuccess');
let el;
beforeEach(() => {
el = shallow(<ImageRenderer {...props} />);
it('renders an image with the correct src and alt attributes', () => {
render(<ImageRenderer {...props} />);
const imgElement = screen.getByRole('img');
expect(imgElement).toBeInTheDocument();
expect(imgElement).toHaveAttribute('src', props.url);
expect(imgElement).toHaveAttribute('alt', props.fileName);
expect(imgElement).toHaveClass('image-renderer');
});
test('snapshot', () => {
expect(el.snapshot).toMatchSnapshot();
it('calls onSuccess when image loads successfully', () => {
render(<ImageRenderer {...props} />);
const imgElement = screen.getByRole('img');
imgElement.dispatchEvent(new Event('load'));
expect(props.onSuccess).toHaveBeenCalled();
});
it('calls onError when image fails to load', () => {
render(<ImageRenderer {...props} />);
const imgElement = screen.getByRole('img');
imgElement.dispatchEvent(new Event('error'));
expect(props.onError).toHaveBeenCalled();
});
});

View File

@@ -1,11 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Image Renderer Component snapshot 1`] = `
<img
alt=""
className="image-renderer"
onError={[MockFunction this.props.onError]}
onLoad={[MockFunction this.props.onSuccess]}
src="some_url.jpg"
/>
`;

View File

@@ -1,25 +1,30 @@
import React from 'react';
import { shallow } from '@edx/react-unit-test-utils';
import { Popover } from '@openedx/paragon';
import { render, screen, fireEvent } from '@testing-library/react';
import FileInfo from './FileInfo';
describe('File Preview Card component', () => {
jest.unmock('@openedx/paragon');
jest.unmock('react');
describe('FileInfo component', () => {
const children = (<h1>some Children</h1>);
const props = { onClick: jest.fn().mockName('this.props.onClick') };
let el;
beforeEach(() => {
el = shallow(<FileInfo {...props}>{children}</FileInfo>);
jest.clearAllMocks();
});
test('snapshot', () => {
expect(el.snapshot).toMatchSnapshot();
});
describe('Component', () => {
test('overlay with passed children', () => {
const { overlay } = el.instance.props;
expect(overlay.type).toEqual(Popover);
expect(overlay.props.children).toEqual(<Popover.Content>{children}</Popover.Content>);
describe('Component rendering', () => {
it('renders the FileInfo button with correct text', () => {
render(<FileInfo {...props}>{children}</FileInfo>);
expect(screen.getByText('FormattedMessage')).toBeInTheDocument();
});
it('calls onClick when button is clicked', () => {
render(<FileInfo {...props}>{children}</FileInfo>);
fireEvent.click(screen.getByText('FormattedMessage'));
expect(props.onClick).toHaveBeenCalledTimes(1);
});
});
});

View File

@@ -1,18 +1,12 @@
import React from 'react';
import { shallow } from '@edx/react-unit-test-utils';
import { render, screen } from '@testing-library/react';
import { formatMessage } from 'testUtils';
import { keyStore } from 'utils';
import { ErrorStatuses } from 'data/constants/requests';
import { FileRenderer } from './FileRenderer';
import * as hooks from './hooks';
jest.mock('./FileCard', () => 'FileCard');
jest.mock('./Banners', () => ({
ErrorBanner: () => 'ErrorBanner',
LoadingBanner: () => 'LoadingBanner',
}));
jest.unmock('@openedx/paragon');
jest.unmock('react');
const hookKeys = keyStore(hooks);
@@ -20,34 +14,70 @@ const props = {
file: {
downloadUrl: 'file download url',
name: 'filename.txt',
description: 'A text file',
},
intl: { formatMessage },
};
describe('FileRenderer', () => {
describe('component', () => {
describe('snapshot', () => {
test('isLoading, no Error', () => {
const hookProps = {
Renderer: () => 'Renderer',
isloading: true,
errorStatus: null,
error: null,
rendererProps: { prop: 'hooks.rendererProps' },
};
jest.spyOn(hooks, hookKeys.renderHooks).mockReturnValueOnce(hookProps);
expect(shallow(<FileRenderer {...props} />).snapshot).toMatchSnapshot();
});
test('is not loading, with error', () => {
const hookProps = {
Renderer: () => 'Renderer',
isloading: false,
errorStatus: ErrorStatuses.serverError,
error: { prop: 'hooks.errorProps' },
rendererProps: { prop: 'hooks.rendererProps' },
};
jest.spyOn(hooks, hookKeys.renderHooks).mockReturnValueOnce(hookProps);
expect(shallow(<FileRenderer {...props} />).snapshot).toMatchSnapshot();
});
it('renders loading banner when isLoading is true', () => {
const hookProps = {
Renderer: () => <div data-testid="mock-renderer">Renderer Component</div>,
isLoading: true,
errorStatus: null,
error: null,
rendererProps: { prop: 'hooks.rendererProps' },
};
jest.spyOn(hooks, hookKeys.renderHooks).mockReturnValueOnce(hookProps);
render(<FileRenderer {...props} />);
expect(screen.getByText('filename.txt')).toBeInTheDocument();
expect(screen.getByTestId('mock-renderer')).toBeInTheDocument();
const spinner = document.querySelector('.spinner-border');
expect(spinner).toBeInTheDocument();
});
it('renders error banner when there is an error status', () => {
const errorProps = {
headingMessage: { id: 'error.heading', defaultMessage: 'Error Heading' },
children: 'Error Message',
actions: [{ id: 'retry', onClick: jest.fn(), message: { id: 'retry', defaultMessage: 'Retry' } }],
};
const hookProps = {
Renderer: () => <div data-testid="mock-renderer">Renderer Component</div>,
isLoading: false,
errorStatus: ErrorStatuses.serverError,
error: errorProps,
rendererProps: { prop: 'hooks.rendererProps' },
};
jest.spyOn(hooks, hookKeys.renderHooks).mockReturnValueOnce(hookProps);
render(<FileRenderer {...props} />);
expect(screen.getByText('filename.txt')).toBeInTheDocument();
expect(screen.getByText('Error Message')).toBeInTheDocument();
expect(document.querySelector('.alert-heading')).toBeInTheDocument();
expect(document.querySelector('.btn.btn-outline-primary')).toBeInTheDocument();
});
it('renders renderer component when not loading and no error', () => {
const hookProps = {
Renderer: () => <div data-testid="mock-renderer">Renderer Component</div>,
isLoading: false,
errorStatus: null,
error: null,
rendererProps: { prop: 'hooks.rendererProps' },
};
jest.spyOn(hooks, hookKeys.renderHooks).mockReturnValueOnce(hookProps);
render(<FileRenderer {...props} />);
expect(screen.getByText('filename.txt')).toBeInTheDocument();
expect(screen.getByTestId('mock-renderer')).toBeInTheDocument();
expect(screen.getByText('Renderer Component')).toBeInTheDocument();
const spinner = document.querySelector('.spinner-border');
expect(spinner).not.toBeInTheDocument();
});
});
});

View File

@@ -1,34 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`File Preview Card component snapshot 1`] = `
<OverlayTrigger
flip={true}
overlay={
<Popover
className="overlay-help-popover"
id="file-popover"
>
<Popover.Content>
<h1>
some Children
</h1>
</Popover.Content>
</Popover>
}
placement="right-end"
trigger="focus"
>
<Button
iconAfter={[MockFunction icons.InfoOutline]}
onClick={[MockFunction this.props.onClick]}
size="sm"
variant="tertiary"
>
<FormattedMessage
defaultMessage="File info"
description="Popover trigger button text for file preview card"
id="ora-grading.InfoPopover.fileInfo"
/>
</Button>
</OverlayTrigger>
`;

View File

@@ -1,33 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FileRenderer component snapshot is not loading, with error 1`] = `
<FileCard
file={
{
"downloadUrl": "file download url",
"name": "filename.txt",
}
}
key="file download url"
>
<ErrorBanner
prop="hooks.errorProps"
/>
</FileCard>
`;
exports[`FileRenderer component snapshot isLoading, no Error 1`] = `
<FileCard
file={
{
"downloadUrl": "file download url",
"name": "filename.txt",
}
}
key="file download url"
>
<Renderer
prop="hooks.rendererProps"
/>
</FileCard>
`;