UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

273 lines (231 loc) • 8.02 kB
import React from 'react' import {vi} from 'vitest' import {render, screen, fireEvent} from '@testing-library/react' import runAxeCheck from '@instructure/ui-axe-check' import FileUploadEdit from '../index' describe('File Upload Edit', () => { const changeItemStateStub = vi.fn() const setOneQuestionAtATimeStub = vi.fn() const props = { itemBody: 'STEM', interactionData: { restrictCount: true, filesCount: '2', }, properties: { restrictTypes: true, allowedTypes: 'media/*', }, changeItemState: changeItemStateStub, openImportModal: () => {}, setOneQuestionAtATime: setOneQuestionAtATimeStub, } afterEach(() => { changeItemStateStub.mockClear() setOneQuestionAtATimeStub.mockClear() }) it('should render', () => { render(<FileUploadEdit {...props} />) expect(document.body.textContent).toBeDefined() }) it('includes validation errors in changeItemState', () => { render( <FileUploadEdit {...props} interactionData={{restrictCount: true, filesCount: 'invalid'}} />, ) expect(changeItemStateStub).toHaveBeenCalledWith( expect.objectContaining({errors: expect.any(Object)}), ) }) it('renders RCE by default', () => { const {container} = render(<FileUploadEdit {...props} />) expect(container.querySelectorAll('[data-automation^="sdk-rce"]').length).toBeGreaterThan(0) }) it('does not render RCE when disabled', () => { const {container} = render(<FileUploadEdit {...props} enableRichContentEditor={false} />) expect(container.querySelectorAll('[data-automation^="sdk-rce"]')).toHaveLength(0) }) it('handles changes of restrictCount', () => { render(<FileUploadEdit {...props} />) document.body.querySelectorAll('input[type=checkbox]')[1].click() expect(changeItemStateStub.mock.calls[0][0]).toEqual( expect.objectContaining({ interactionData: { restrictCount: false, filesCount: '2', }, }), ) }) it('handles changes of filesCount', () => { render(<FileUploadEdit {...props} />) const inputElement = screen.getAllByRole('spinbutton')[0] fireEvent.change(inputElement, {target: {value: '4'}}) expect(changeItemStateStub.mock.calls[0][0]).toEqual( expect.objectContaining({ interactionData: { restrictCount: true, filesCount: '4', }, }), ) }) it('handles changes of restrictTypes', () => { render(<FileUploadEdit {...props} />) document.body.querySelectorAll('input[type=checkbox]')[2].click() expect(changeItemStateStub.mock.calls[0][0]).toEqual( expect.objectContaining({ properties: { restrictTypes: false, allowedTypes: 'media/*', }, }), ) }) it('handles changes of allowedTypes', () => { render(<FileUploadEdit {...props} />) const inputElement = screen.getAllByRole('textbox')[1] fireEvent.change(inputElement, {target: {value: '.jpeg'}}) expect(changeItemStateStub.mock.calls[0][0]).toEqual( expect.objectContaining({ properties: { restrictTypes: true, allowedTypes: '.jpeg', }, }), ) }) it('should show Errors if errorsAreShowing is true and there are itemBody errors', () => { const errorMsg = "I'm sorry Dave" render( <FileUploadEdit {...props} errorsAreShowing={true} errors={{ itemBody: [errorMsg], }} />, ) expect(document.body.textContent).toContain(errorMsg) }) it('should show Errors if errorsAreShowing is true and there are properties errors', () => { const errorMsg = "I'm afraid" render( <FileUploadEdit {...props} errorsAreShowing={true} errors={{ properties: { allowedTypes: [errorMsg], }, }} />, ) expect(document.body.textContent).toContain(errorMsg) }) it('should show Errors if errorsAreShowing is true and there are interactionData errors', () => { const errorMsg = "I can't do that" render( <FileUploadEdit {...props} errorsAreShowing={true} errors={{ interactionData: { filesCount: [errorMsg], }, }} />, ) expect(document.body.textContent).toContain(errorMsg) }) it('should not render allowedTypes TextInput inside an QuestionSettingsContainer when restrictTypes is false', () => { render( <FileUploadEdit {...props} properties={{ restrictTypes: false, allowedTypes: 'media/*', }} />, ) const input = screen.queryByPlaceholderText(/file extensions/i) expect(input).toBeNull() }) it('should render allowedTypes TextInput inside an QuestionSettingsContainer when restrictTypes is true', () => { const allowedTypes = 'comma, separated, values' render( <FileUploadEdit {...props} properties={{ restrictTypes: true, allowedTypes, }} />, ) const input = screen.getByPlaceholderText(/file extensions/i) expect(input.value).toBe(allowedTypes) }) describe('overrideEditableForRegrading', () => { it('disables text input', () => { render(<FileUploadEdit {...props} overrideEditableForRegrading={true} />) expect(document.body.querySelector('input[type=checkbox]').disabled).toBe(true) }) it('disables number input', () => { render(<FileUploadEdit {...props} overrideEditableForRegrading={true} />) expect(document.body.querySelector('input[inputMode=decimal]').disabled).toBe(true) }) it('disables checkbox inputs', () => { render(<FileUploadEdit {...props} overrideEditableForRegrading={true} />) document.body .querySelectorAll('input[type=checkbox]') .forEach(cb => expect(cb.disabled).toBe(true)) }) it('disables the calculator option', () => { render(<FileUploadEdit {...props} overrideEditableForRegrading={true} />) expect(screen.getByRole('checkbox', {name: /show on-screen calculator/i}).disabled).toBe(true) }) }) describe('a11y tests', () => { it('should meet a11y standards', async () => { render(<FileUploadEdit {...props} />) expect( await runAxeCheck(document.body, { ignores: ['label', 'region'], }), ).toBe(true) }) }) describe('calculator per question option', () => { it('does not render the calculator checkbox if showCalculatorOption is false', () => { render(<FileUploadEdit {...props} showCalculatorOption={false} />) expect(screen.queryByRole('checkbox', {name: /show on-screen calculator/i})).toBeNull() }) it('renders the calculator per question option', () => { render(<FileUploadEdit {...props} />) expect(screen.queryAllByRole('checkbox', {name: /show on-screen calculator/i})).toHaveLength( 1, ) }) it('calls the correct callback function with the correct data when the calculator type is changed', () => { render(<FileUploadEdit {...props} />) const calculatorCheckbox = screen.getByRole('checkbox', { name: /show on-screen calculator/i, }) // Clicking the checkbox toggles from 'none' to 'basic' fireEvent.click(calculatorCheckbox) expect(changeItemStateStub).toHaveBeenCalledWith( expect.objectContaining({ calculatorType: 'basic', }), ) }) it('calls the correct callback function with the correct data when OQAAT is changed', () => { // Need calculatorType != 'none' for OQAAT toggle to appear render(<FileUploadEdit {...props} calculatorType="basic" />) const toggle = screen.getByRole('checkbox', { name: /enable one question at a time/i, }) fireEvent.click(toggle) expect(setOneQuestionAtATimeStub).toHaveBeenCalledTimes(1) }) }) })