123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- import {act, render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
- import {
- addErrorMessage,
- addMessage,
- addSuccessMessage,
- clearIndicators,
- } from 'sentry/actionCreators/indicator';
- import Indicators from 'sentry/components/indicators';
- import IndicatorStore from 'sentry/stores/indicatorStore';
- // Make sure we use `duration: null` to test add/remove
- jest.useFakeTimers();
- jest.mock('framer-motion', () => ({
- ...jest.requireActual('framer-motion'),
- AnimatePresence: jest.fn(({children}) => children),
- }));
- describe('Indicators', function () {
- beforeEach(function () {
- clearIndicators();
- act(jest.runAllTimers);
- });
- it('renders nothing by default', function () {
- const {container} = render(<Indicators />);
- expect(container).toHaveTextContent('');
- });
- it('has a loading indicator by default', function () {
- const {container} = render(<Indicators />);
- // when "type" is empty, we should treat it as loading state
- act(() => void IndicatorStore.add('Loading'));
- expect(screen.getByTestId('loading-indicator')).toBeInTheDocument();
- expect(container).toHaveTextContent('Loading');
- });
- it('adds and removes a toast by calling IndicatorStore directly', function () {
- const {container} = render(<Indicators />);
- // when "type" is empty, we should treat it as loading state
- let indicator;
- act(() => {
- indicator = IndicatorStore.add('Loading');
- });
- expect(container).toHaveTextContent('Loading');
- // Old indicator gets replaced when a new one is added
- act(() => IndicatorStore.remove(indicator));
- expect(container).toHaveTextContent('');
- });
- // This is a common pattern used throughout the code for API calls
- it('adds and replaces toast by calling IndicatorStore directly', function () {
- const {container} = render(<Indicators />);
- act(() => void IndicatorStore.add('Loading'));
- expect(container).toHaveTextContent('Loading');
- // Old indicator gets replaced when a new one is added
- act(() => void IndicatorStore.add('success', 'success'));
- expect(container).toHaveTextContent('success');
- });
- it('does not have loading indicator when "type" is empty (default)', function () {
- const {container} = render(<Indicators />);
- addMessage('Loading', '', {duration: null});
- act(jest.runAllTimers);
- expect(container).toHaveTextContent('Loading');
- expect(screen.queryByTestId('loading-indicator')).not.toBeInTheDocument();
- });
- it('has a loading indicator when type is "loading"', function () {
- const {container} = render(<Indicators />);
- addMessage('Loading', 'loading', {duration: null});
- act(jest.runAllTimers);
- expect(container).toHaveTextContent('Loading');
- expect(screen.getByTestId('loading-indicator')).toBeInTheDocument();
- });
- it('adds and removes toast by calling action creators', function () {
- const {container} = render(<Indicators />);
- // action creators don't return anything
- addMessage('Loading', '', {duration: null});
- act(jest.runAllTimers);
- expect(container).toHaveTextContent('Loading');
- // If no indicator is specified, will remove all indicators
- clearIndicators();
- act(jest.runAllTimers);
- expect(container).toHaveTextContent('');
- expect(screen.queryByTestId('loading-indicator')).not.toBeInTheDocument();
- });
- it('adds and replaces toast by calling action creators', function () {
- const {container} = render(<Indicators />);
- addMessage('Loading', '', {duration: null});
- act(jest.runAllTimers);
- expect(container).toHaveTextContent('Loading');
- // Old indicator gets replaced when a new one is added
- addMessage('success', 'success', {duration: null});
- act(jest.runAllTimers);
- expect(container).toHaveTextContent('success');
- expect(screen.queryByTestId('loading-indicator')).not.toBeInTheDocument();
- });
- it('adds and replaces toasts by calling action creators helpers', async function () {
- const {container} = render(<Indicators />);
- // Old indicator gets replaced when a new one is added
- addSuccessMessage('success');
- await waitFor(() => {
- expect(container).toHaveTextContent('success');
- });
- clearIndicators();
- addErrorMessage('error');
- await waitFor(() => {
- expect(container).toHaveTextContent('error');
- });
- });
- it('appends toasts', function () {
- const {container} = render(<Indicators />);
- addMessage('Loading', '', {append: true, duration: null});
- act(jest.runAllTimers);
- expect(screen.getByTestId('toast')).toHaveTextContent('Loading');
- addMessage('Success', 'success', {append: true, duration: null});
- act(jest.runAllTimers);
- // Toasts get appended to the end
- expect(screen.getByTestId('toast')).toHaveTextContent('Loading');
- expect(screen.getByTestId('toast-success')).toHaveTextContent('Success');
- addMessage('Error', 'error', {append: true, duration: null});
- act(jest.runAllTimers);
- // Toasts get appended to the end
- expect(screen.getByTestId('toast')).toHaveTextContent('Loading');
- expect(screen.getByTestId('toast-success')).toHaveTextContent('Success');
- expect(screen.getByTestId('toast-error')).toHaveTextContent('Error');
- // clears all toasts
- clearIndicators();
- act(jest.runAllTimers);
- expect(container).toHaveTextContent('');
- expect(screen.queryByTestId('loading-indicator')).not.toBeInTheDocument();
- });
- it('dismisses on click', function () {
- const {container} = render(<Indicators />);
- addMessage('Loading', '', {append: true, duration: null});
- act(jest.runAllTimers);
- expect(screen.getByTestId('toast')).toHaveTextContent('Loading');
- userEvent.click(screen.getByTestId('toast'));
- act(jest.runAllTimers);
- expect(container).toHaveTextContent('');
- expect(screen.queryByTestId('toast')).not.toBeInTheDocument();
- });
- it('hides after 10s', function () {
- const {container} = render(<Indicators />);
- addMessage('Duration', '', {append: true, duration: 10000});
- act(() => jest.advanceTimersByTime(9000));
- expect(screen.getByTestId('toast')).toHaveTextContent('Duration');
- // Still visible
- act(() => jest.advanceTimersByTime(999));
- expect(screen.getByTestId('toast')).toHaveTextContent('Duration');
- act(() => jest.advanceTimersByTime(2));
- expect(container).toHaveTextContent('');
- expect(screen.queryByTestId('toast')).not.toBeInTheDocument();
- });
- });
|