@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
185 lines (155 loc) • 6.39 kB
JavaScript
import {vi} from 'vitest'
import runAxeCheck from '@instructure/ui-axe-check'
import ReactDOM from 'react-dom'
import shouldRenderComponent from '../../../../../tests/util/render-checks'
import {wrapInDragAndDropTestContext} from '../../../../../tests/util/dndTestUtils'
import OrderingTake from '../index'
import OrderGroup from '../../common/OrderGroup'
import ReorderChoiceButton from '../../common/ReorderChoiceButton'
import {ScreenReaderContent} from '@instructure/ui-a11y-content'
import {ReactTestbed} from '../../../../../tests/util/react-testbed'
const firstChoiceID = '1'
const secondChoiceID = '2'
const thirdChoiceID = '3'
const defaultOrder = [firstChoiceID, secondChoiceID, thirdChoiceID]
const choices = {
[firstChoiceID]: {id: firstChoiceID, itemBody: 'Gollum'},
[secondChoiceID]: {id: secondChoiceID, itemBody: 'Frodo'},
[thirdChoiceID]: {id: thirdChoiceID, itemBody: 'Gimli'},
}
const props = {
itemBody: 'Order these characters from tallest to shortest:',
interactionData: {choices},
properties: {
displayAnswersParagraph: false,
includeLabels: true,
topLabel: 'Taller',
bottomLabel: 'Shorter',
},
userResponse: {
value: defaultOrder,
},
handleResponseUpdate: () => {},
}
describe('Ordering Take', () => {
const testbed = new ReactTestbed(wrapInDragAndDropTestContext(OrderingTake), props)
const handleResponseUpdateStub = vi.fn()
const getComponent = tb => {
return tb.findChildrenByType(OrderingTake)[0]
}
const getChoiceButtons = tb => {
return tb.findChildrenByType(ReorderChoiceButton)
}
shouldRenderComponent(testbed, {}, OrderingTake)
afterEach(() => {
handleResponseUpdateStub.mockClear()
})
describe('rendering', () => {
it('renders each interaction choice', () => {
testbed.render()
const text = testbed.getText()
const choices = props.interactionData.choices
Object.keys(choices).forEach(choiceKey => expect(text).toContain(choices[choiceKey].itemBody))
})
it('renders title and labels', () => {
testbed.render()
const text = testbed.getText()
expect(text).toContain(props.properties.topLabel)
expect(text).toContain(props.properties.topLabel)
expect(text).toContain(props.itemBody)
})
})
describe('#onMoveChoice', () => {
it('should call handleResponseUpdate with updated choice sequence', () => {
testbed.render({
handleResponseUpdate: handleResponseUpdateStub,
})
getComponent(testbed).handleMoveChoice(0, 1) // shift first and second choices
const result = handleResponseUpdateStub.mock.calls[0][0] // get call and compare values
expect(result[0]).toBe(secondChoiceID)
expect(result[1]).toBe(firstChoiceID)
expect(result[2]).toBe(thirdChoiceID)
})
it('can handle moving an item more than one space away', () => {
testbed.render({
handleResponseUpdate: handleResponseUpdateStub,
})
getComponent(testbed).handleMoveChoice(0, 2) // move first item to the end
const result = handleResponseUpdateStub.mock.calls[0][0]
expect(result[0]).toBe(secondChoiceID)
expect(result[1]).toBe(thirdChoiceID)
expect(result[2]).toBe(firstChoiceID)
})
it('should call handleResponseUpdate with updated choice sequence when moving choice up', () => {
testbed.render({
handleResponseUpdate: handleResponseUpdateStub,
})
getComponent(testbed).handleMoveChoiceUp(thirdChoiceID)
const result = handleResponseUpdateStub.mock.calls[0][0]
expect(result[0]).toBe(firstChoiceID)
expect(result[1]).toBe(thirdChoiceID)
expect(result[2]).toBe(secondChoiceID)
})
it('should call handleResponseUpdate with updated choice sequence when moving choice down', () => {
testbed.render({
handleResponseUpdate: handleResponseUpdateStub,
})
getComponent(testbed).handleMoveChoiceDown(secondChoiceID)
const result = handleResponseUpdateStub.mock.calls[0][0]
expect(result[0]).toBe(firstChoiceID)
expect(result[1]).toBe(thirdChoiceID)
expect(result[2]).toBe(secondChoiceID)
})
it('should focus the moved choice after a move', () => {
testbed.render({
handleResponseUpdate: handleResponseUpdateStub,
})
const firstButton = getChoiceButtons(testbed)[0]
firstButton.handleMoveDown()
expect(document.activeElement.textContent).toContain(choices[firstChoiceID].itemBody)
expect(document.activeElement.textContent).not.toContain(choices[secondChoiceID].itemBody)
const lastButton = getChoiceButtons(testbed)[2]
lastButton.handleMoveUp()
expect(document.activeElement.textContent).toContain(choices[thirdChoiceID].itemBody)
expect(document.activeElement.textContent).not.toContain(choices[firstChoiceID].itemBody)
})
it('swaps two choices on move down', () => {
testbed.render({
handleResponseUpdate: handleResponseUpdateStub,
})
const firstButton = getChoiceButtons(testbed)[0]
firstButton.handleMoveDown()
const result = handleResponseUpdateStub.mock.calls[0][0]
expect(result).toEqual([secondChoiceID, firstChoiceID, thirdChoiceID])
})
it('swaps two choices on move up', () => {
testbed.render({
handleResponseUpdate: handleResponseUpdateStub,
})
const secondButton = getChoiceButtons(testbed)[1]
secondButton.handleMoveUp()
const result = handleResponseUpdateStub.mock.calls[0][0]
expect(result).toEqual([secondChoiceID, firstChoiceID, thirdChoiceID])
})
})
describe('choice order', () => {
it('passes userResponse value to OrderGroup', () => {
testbed.render()
const orderGroup = testbed.findChildrenByType(OrderGroup)[0]
expect(orderGroup.props.choiceOrder).toEqual(defaultOrder)
})
})
describe('a11y tests', () => {
it('should render position in screenreadercontent', () => {
testbed.render()
const srContent = testbed.findChildrenByType(ScreenReaderContent)[1]
expect(srContent).toBeDefined()
const srNode = ReactDOM.findDOMNode(srContent)
expect(srNode.textContent).toContain('position 1')
})
it('should meet a11y standards', async () => {
testbed.render()
expect(await runAxeCheck(testbed.rootNode)).toBe(true)
})
})
})