UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

206 lines (169 loc) • 6.83 kB
import {vi} from 'vitest' import React from 'react' import {render, screen} from '@testing-library/react' import userEvent from '@testing-library/user-event' import TrueFalseEdit from '../index' import { verifyAtLeastOneRichContentEditorExists, verifyNoRichContentEditorsExist, } from '../../../../../tests/util/enableRichContentEditorChecks' import {verifyItemChangesAreValidated} from '../../../../../tests/util/shouldValidateItemChanges' import runAxeCheck from '@instructure/ui-axe-check' function createProps(changeItemStateStub, setOneQuestionAtATimeStub) { return { calculatorType: 'basic', itemBody: 'STEM', itemId: '12', interactionData: { trueChoice: 'True', falseChoice: 'False', }, scoringData: { value: true, }, openImportModal: Function.prototype, changeItemState: changeItemStateStub, setOneQuestionAtATime: setOneQuestionAtATimeStub, isSurvey: false, } } describe('***** old tests *****', () => { const changeItemStateStub = vi.fn() const oldProps = createProps(changeItemStateStub, vi.fn()) afterEach(() => { changeItemStateStub.mockClear() }) describe('overrideEditableForRegrading', () => { it('disables the question stem', () => { const {container} = render(<TrueFalseEdit {...oldProps} overrideEditableForRegrading />) // QuestionContainer passes readOnly to the RCE when disabled is true // Verify the RCE area is not editable const questionStem = container.querySelector('[data-automation="sdk-question-stem"]') expect(questionStem).toBeInTheDocument() // The calculator options should also be disabled const calculatorCheckbox = screen.getByRole('checkbox', { name: /show on-screen calculator/i, }) expect(calculatorCheckbox.disabled).toBe(true) }) }) }) describe('True False Item Edit', () => { let changeItemStateStub, setOneQuestionAtATimeStub, props beforeEach(() => { changeItemStateStub = vi.fn() setOneQuestionAtATimeStub = vi.fn() props = createProps(changeItemStateStub, setOneQuestionAtATimeStub) }) it('renders a rich content editor by default', async () => { await verifyAtLeastOneRichContentEditorExists(TrueFalseEdit, props) }) it('does not render a rich content editor when it is turned off', async () => { await verifyNoRichContentEditorsExist(TrueFalseEdit, {...props, enableRichContentEditor: false}) }) it('includes validation errors in changeItemState', async () => { await verifyItemChangesAreValidated(TrueFalseEdit, {...props, itemBody: ''}) }) describe('QuestionConfigContainer', () => { it('renders an QuestionSettingsContainer', () => { render(<TrueFalseEdit {...props} />) const questionSettingsContainers = screen.getAllByTestId('question-settings-container') expect(questionSettingsContainers).toHaveLength(1) }) }) describe('#onSelectionUpdate', () => { it('calls changeItemState with the correct arguments', () => { render(<TrueFalseEdit {...props} />) const radioInput = screen.getByRole('radio', { name: new RegExp(`Answer: ${props.interactionData.falseChoice}`), }) userEvent.click(radioInput) expect(changeItemStateStub).toHaveBeenCalledWith( expect.objectContaining({scoringData: {value: false}}), ) }) }) describe('#selectedValue', () => { it('selects the correct input from scoredData', () => { render(<TrueFalseEdit {...props} />) const trueInput = screen.getByRole('radio', { name: new RegExp(`Answer: ${props.interactionData.trueChoice}`), }) expect(trueInput.checked).toBe(true) const falseInput = screen.getByRole('radio', { name: new RegExp(`Answer: ${props.interactionData.falseChoice}`), }) expect(falseInput.checked).toBe(false) }) it('selects the correct input from scoredData when false', () => { const falseProps = Object.assign({}, props, { scoringData: { value: false, }, }) render(<TrueFalseEdit {...falseProps} />) const trueInput = screen.getByRole('radio', { name: new RegExp(`Answer: ${props.interactionData.trueChoice}`), }) expect(trueInput.checked).toBe(false) const falseInput = screen.getByRole('radio', { name: new RegExp(`Answer: ${props.interactionData.falseChoice}`), }) expect(falseInput.checked).toBe(true) }) }) describe('overrideEditableForRegrading', () => { it('disables the calculator option', () => { render(<TrueFalseEdit {...props} overrideEditableForRegrading />) const calculatorCheckbox = screen.getByRole('checkbox', {name: /show on-screen calculator/i}) const calculatorBasicRadioInput = screen.getByRole('radio', {name: /basic calculator/i}) const calculatorScientificRadioInput = screen.getByRole('radio', { name: /scientific calculator/i, }) expect(calculatorCheckbox.disabled).toBe(true) expect(calculatorBasicRadioInput.disabled).toBe(true) expect(calculatorScientificRadioInput.disabled).toBe(true) }) }) describe('a11y tests', () => { it('should meet a11y standards', async () => { render( <main> <TrueFalseEdit {...props} /> </main>, ) expect( await runAxeCheck(document.body, { ignores: ['scrollable-region-focusable'], }), ).toBe(true) }) }) describe('calculator per question option', () => { it('does not render the options if showCalculatorOption is false', () => { render(<TrueFalseEdit {...props} showCalculatorOption={false} />) expect(screen.queryByRole('button', {name: /options/i})).toBeNull() }) it('renders the calculator per question option', () => { render(<TrueFalseEdit {...props} />) const calculatorCheckboxes = screen.queryAllByRole('checkbox', { name: /show on-screen calculator/i, }) expect(calculatorCheckboxes).toHaveLength(1) }) it('calls the correct callback function with the correct data when the calculator type is changed', () => { render(<TrueFalseEdit {...props} />) const scientificOption = screen.getByRole('radio', {name: /scientific calculator/i}) userEvent.click(scientificOption) expect(changeItemStateStub).toHaveBeenCalledWith( expect.objectContaining({calculatorType: 'scientific'}), ) }) it('calls the correct callback function when OQAAT is changed', () => { render(<TrueFalseEdit {...props} />) const toggle = screen.getByRole('checkbox', {name: /enable one question at a time/i}) userEvent.click(toggle) expect(setOneQuestionAtATimeStub).toHaveBeenCalledTimes(1) }) }) })