|
23 | 23 | */ |
24 | 24 | import React from 'react' |
25 | 25 | import { render, waitFor, screen } from '@testing-library/react' |
| 26 | +import { runAxeCheck } from '@instructure/ui-axe-check' |
| 27 | +import { vi, expect } from 'vitest' |
| 28 | +import type { MockInstance } from 'vitest' |
26 | 29 |
|
27 | 30 | import '@testing-library/jest-dom' |
| 31 | +import { View } from '@instructure/ui-view' |
28 | 32 | import Spinner from '../index' |
| 33 | +import type { SpinnerProps } from '../props' |
29 | 34 |
|
30 | 35 | describe('<Spinner />', () => { |
| 36 | + let consoleErrorMock: ReturnType<typeof vi.spyOn> |
| 37 | + |
| 38 | + beforeEach(() => { |
| 39 | + // Mocking console to prevent test output pollution and expect for messages |
| 40 | + consoleErrorMock = vi |
| 41 | + .spyOn(console, 'error') |
| 42 | + .mockImplementation(() => {}) as MockInstance |
| 43 | + }) |
| 44 | + |
| 45 | + afterEach(() => { |
| 46 | + consoleErrorMock.mockRestore() |
| 47 | + }) |
| 48 | + |
| 49 | + it('should render', async () => { |
| 50 | + const { container } = render(<Spinner renderTitle="Loading" size="small" />) |
| 51 | + const spinner = container.querySelector('div[class$="-spinner"]') |
| 52 | + |
| 53 | + expect(spinner).toBeInTheDocument() |
| 54 | + }) |
| 55 | + |
| 56 | + it('should render the title prop text in the SVG element title', async () => { |
| 57 | + const { container } = render(<Spinner renderTitle="Loading" size="large" />) |
| 58 | + const spinner = container.querySelector('div[class$="-spinner"]') |
| 59 | + |
| 60 | + expect(spinner).toHaveTextContent('Loading') |
| 61 | + }) |
| 62 | + |
| 63 | + it('should meet a11y standards', async () => { |
| 64 | + const { container } = render(<Spinner renderTitle="Loading" size="small" />) |
| 65 | + const axeCheck = await runAxeCheck(container) |
| 66 | + expect(axeCheck).toBe(true) |
| 67 | + }) |
| 68 | + |
| 69 | + it('should render the contents of a component used in renderTitle', async () => { |
| 70 | + const Translation = ({ children }: SpinnerProps) => ( |
| 71 | + <span>I have translated {children}.</span> |
| 72 | + ) |
| 73 | + |
| 74 | + const { container } = render( |
| 75 | + <Spinner renderTitle={<Translation>Loading</Translation>} size="small" /> |
| 76 | + ) |
| 77 | + |
| 78 | + const spinner = container.querySelector('div[class$="-spinner"]') |
| 79 | + const axeCheck = await runAxeCheck(container) |
| 80 | + |
| 81 | + expect(axeCheck).toBe(true) |
| 82 | + expect(spinner).toHaveTextContent('I have translated Loading') |
| 83 | + }) |
| 84 | + |
| 85 | + describe('when passing down props to View', () => { |
| 86 | + const allowedProps: { [key: string]: any } = { |
| 87 | + margin: 'small', |
| 88 | + elementRef: () => {}, |
| 89 | + as: 'div' |
| 90 | + } |
| 91 | + |
| 92 | + View.allowedProps |
| 93 | + .filter((prop) => prop !== 'children') |
| 94 | + .forEach((prop) => { |
| 95 | + if (Object.keys(allowedProps).indexOf(prop) < 0) { |
| 96 | + it(`should NOT allow the '${prop}' prop`, async () => { |
| 97 | + const props = { |
| 98 | + [prop]: 'foo' |
| 99 | + } |
| 100 | + const expectedErrorMessage = `prop '${prop}' is not allowed.` |
| 101 | + |
| 102 | + render(<Spinner renderTitle="Loading" {...props} />) |
| 103 | + |
| 104 | + expect(consoleErrorMock).toHaveBeenCalledWith( |
| 105 | + expect.stringContaining(expectedErrorMessage), |
| 106 | + expect.any(String) |
| 107 | + ) |
| 108 | + }) |
| 109 | + } else { |
| 110 | + it(`should allow the '${prop}' prop`, async () => { |
| 111 | + const props = { [prop]: allowedProps[prop] } |
| 112 | + render(<Spinner renderTitle="Loading" {...props} />) |
| 113 | + |
| 114 | + expect(consoleErrorMock).not.toHaveBeenCalled() |
| 115 | + }) |
| 116 | + } |
| 117 | + }) |
| 118 | + }) |
| 119 | + |
31 | 120 | describe('with the delay prop', () => { |
32 | 121 | it('should delay rendering', async () => { |
33 | 122 | render(<Spinner renderTitle="Loading" delay={300} />) |
|
0 commit comments