UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

199 lines (154 loc) • 6.24 kB
import {vi} from 'vitest' import React from 'react' import {fireEvent, render, screen, waitFor} from '@testing-library/react' import runAxeCheck from '@instructure/ui-axe-check' import userEvent from '@testing-library/user-event' import FileUploadTake from '../index' describe('File Upload Take', () => { let props beforeEach(() => { props = { itemBody: 'Give three examples of people', interactionData: { restrictCount: true, filesCount: '3', }, properties: { restrictTypes: true, allowedTypes: ['image/jpeg', 'application/pdf'], }, userResponse: { value: [ { id: 0, name: 'slide-3.jpg', url: 'http://instructure.github.io/images/slide-3.jpg', size: 49067, }, { id: 1, name: 'maxresdefault.jpg', url: 'https://i.ytimg.com/vi/LgkAebhJ7iE/maxresdefault.jpg', size: 30437, }, ], }, handleResponseUpdate: vi.fn(), mediaUpload: vi.fn(), cancelMediaUpload: vi.fn(), } }) describe('Response mods', () => { it('Handles response removal', async () => { render(<FileUploadTake {...props} />) const removeButton = screen.getByText('Remove File Named slide-3.jpg') userEvent.click(removeButton) expect(props.handleResponseUpdate).toHaveBeenCalledWith([props.userResponse.value[1]]) }) it('Uploads a dropped file', async () => { const userResponse = { value: [], } const file = new File([''], 'fake.png', {type: 'image/png'}) render(<FileUploadTake {...props} userResponse={userResponse} />) const dropLabel = screen.getByLabelText(/Drag and Drop here or Browse/i) userEvent.upload(dropLabel, file) expect(dropLabel.files[0]).toBe(file) expect(dropLabel.files.item(0)).toBe(file) expect(dropLabel.files).toHaveLength(1) }) // TODO: QUIZ-17438 - FileDrop from @instructure/ui-file-drop does not process // fireEvent.change or userEvent.upload in jsdom; mediaUpload callback is never triggered it.skip('Adds a response on file dropped', async () => { const userResponse = { value: [], } const file = new File([''], 'fake.pdf', {type: 'application/pdf'}) const {container} = render(<FileUploadTake {...props} userResponse={userResponse} />) const fileInput = container.querySelector('input[type="file"]') fireEvent.change(fileInput, {target: {files: [file]}}) await waitFor(() => { expect(props.mediaUpload).toHaveBeenCalled() }) expect(props.handleResponseUpdate).not.toHaveBeenCalled() const callback = props.mediaUpload.mock.calls[0][2] const fakeFilename = 'fake.pdf' callback(fakeFilename) const newResponseValue = props.handleResponseUpdate.mock.calls[0][0] expect(newResponseValue.length).toBe(1) }) }) describe('rendering', () => { it('has title', async () => { render(<FileUploadTake {...props} />) const title = screen.getByText(props.itemBody) expect(title).toBeInTheDocument() }) it('renders the list of existing files', async () => { render(<FileUploadTake {...props} />) const firstFile = screen.getByText(props.userResponse.value[0].name) const secondFile = screen.getByText(props.userResponse.value[1].name) expect(firstFile).toBeInTheDocument() expect(secondFile).toBeInTheDocument() }) // TODO: QUIZ-17438 - FileDrop from @instructure/ui-file-drop does not process // fireEvent.change in jsdom; rejection path is never triggered it.skip('renders errors if attempted to upload invalid file type', async () => { const file = new File([''], 'fake.png', {type: 'image/png'}) const {container} = render(<FileUploadTake {...props} />) const fileInput = container.querySelector('input[type="file"]') fireEvent.change(fileInput, {target: {files: [file]}}) await waitFor(() => { expect(screen.getByText('Invalid file type')).toBeInTheDocument() }) }) it('renders a FileDrop if the max files limit has not been reached', async () => { render(<FileUploadTake {...props} />) const dropLabel = screen.getByLabelText(/Drag and Drop here or Browse/i) expect(dropLabel).toBeInTheDocument() }) it("always renders a FileDrop if there's no max file limit", async () => { const interactionData = { restrictCount: false, filesCount: '2', } render(<FileUploadTake {...props} interactionData={interactionData} />) const dropLabel = screen.getByLabelText(/Drag and Drop here or Browse/i) expect(dropLabel).toBeInTheDocument() }) it('does not render a FileDrop if the max file limit has been reached', async () => { const interactionData = { restrictCount: true, filesCount: '2', } render(<FileUploadTake {...props} interactionData={interactionData} />) const dropLabel = screen.queryByText( (content, element) => content.includes('Drag and Drop here') && content.includes('Browse'), ) expect(dropLabel).not.toBeInTheDocument() }) }) describe('a11y tests', () => { it('should meet a11y standards', async () => { render(<FileUploadTake {...props} />) expect( await runAxeCheck(document.body, { ignores: ['region'], }), ).toBe(true) }) }) it('should prevent dropping a file when in read only mode', async () => { const file = new File([''], 'fake.pdf', {type: 'application/pdf'}) render(<FileUploadTake {...props} readOnly />) const dropLabel = screen.getByLabelText(/Drag and Drop here or Browse/i) userEvent.upload(dropLabel, file) expect(props.mediaUpload).not.toHaveBeenCalled() }) it('should disable the remove button(s) when in read only mode', async () => { render(<FileUploadTake {...props} readOnly />) const removeButton = screen.getByText('Remove File Named slide-3.jpg') removeButton.click() expect(props.handleResponseUpdate).not.toHaveBeenCalled() }) })