UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

118 lines (104 loc) 4.11 kB
import {vi} from 'vitest' import React from 'react' import {v4 as uuid} from 'uuid' import {render, screen, fireEvent} from '@testing-library/react' import runAxeCheck from '@instructure/ui-axe-check' import MultipleChoiceTake from '../index' describe('Multiple Choice Item Take', () => { const firstChoiceID = uuid() const secondChoiceID = uuid() const props = { allowClearMcSelection: false, choiceElimination: false, itemBody: 'STEM', scoringData: {value: firstChoiceID}, itemId: '1', interactionData: { choices: [ {id: firstChoiceID, itemBody: 'hey', position: 1}, {id: secondChoiceID, itemBody: 'ho', position: 2}, ], }, handleResponseUpdate: () => {}, userResponse: {value: firstChoiceID}, } describe('responding', () => { it('should call editResponse with correct choiceId on radioInput click', () => { const handleResponseUpdateStub = vi.fn() render(<MultipleChoiceTake {...props} handleResponseUpdate={handleResponseUpdateStub} />) const radioInputs = screen.getAllByRole('radio') const radioInput = radioInputs.find(n => n.value === secondChoiceID) fireEvent.click(radioInput) expect(handleResponseUpdateStub).toHaveBeenCalled() expect(handleResponseUpdateStub.mock.calls[0][0]).toBe(secondChoiceID) }) }) describe('when allowClearMcSelection is true', () => { it('should render a button to clear selection', () => { render(<MultipleChoiceTake {...props} allowClearMcSelection />) expect(screen.getByText('Clear my selection')).toBeInTheDocument() }) it('clearing the selection sets response to null', () => { const handleResponseUpdateStub = vi.fn() render( <MultipleChoiceTake {...props} allowClearMcSelection handleResponseUpdate={handleResponseUpdateStub} />, ) const clearButton = screen.getByRole('button', {name: /clear my selection/i}) expect(clearButton.textContent).toBe('Clear my selection') fireEvent.click(clearButton) expect(handleResponseUpdateStub).toHaveBeenCalledWith(null) }) }) describe('when choiceElimination is true', () => { it('should render buttons to eliminate choices', () => { render(<MultipleChoiceTake {...props} choiceElimination />) expect(screen.getAllByText(/Eliminate answer/).length).toBeGreaterThan(0) }) it('eliminating a choice updates user response data', () => { const handleResponseUpdateStub = vi.fn() render( <MultipleChoiceTake {...props} choiceElimination handleResponseUpdate={handleResponseUpdateStub} />, ) const eliminateButton = screen.getByRole('button', {name: /Eliminate answer hey/}) fireEvent.click(eliminateButton) expect(handleResponseUpdateStub).toHaveBeenCalledWith(firstChoiceID, { eliminated: [firstChoiceID], }) }) it('uneliminating a choice removes it from user response data', () => { const handleResponseUpdateStub = vi.fn() render( <MultipleChoiceTake {...props} choiceElimination userResponse={{value: firstChoiceID, properties: {eliminated: [firstChoiceID]}}} handleResponseUpdate={handleResponseUpdateStub} />, ) const eliminateButton = screen.getByRole('button', {name: /Undo elimination of answer hey/}) fireEvent.click(eliminateButton) expect(handleResponseUpdateStub).toHaveBeenCalledWith(firstChoiceID, {eliminated: []}) }) }) it('should meet a11y standards', async () => { // Note: In this component's context, we don't render any landmarks, so we wrap it in a <main> // tag to satisfy the Axe check const {container} = render( <main> <MultipleChoiceTake {...props} /> </main>, ) const result = await runAxeCheck(container, { ignores: ['scrollable-region-focusable'], // we conditionally make rceRenderer focusable when we detect content overflow }) expect(result).toBe(true) }) })