@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
116 lines (100 loc) • 4.16 kB
JavaScript
import React from 'react'
import zipAll from 'lodash/fp/zipAll'
import {expect, findAll, mount, within} from '@instructure/ui-test-utils'
import MultipleChoiceResult from '../index'
import {cartesianProduct, identityMatrix} from '../../../../util/combinatorics'
const props = {
itemBody: 'Who was the first President of the United States?',
itemId: '44',
interactionData: {
choices: [
{id: 'uuid1', itemBody: 'George Washington', position: 1},
{id: 'uuid2', itemBody: 'Alexander Hamilton', position: 2},
{id: 'uuid3', itemBody: 'John Adams', position: 3},
{id: 'uuid4', itemBody: 'Thomas Jefferson', position: 4},
],
},
scoredData: {
correct: true,
value: {
uuid2: {resultScore: 1, userResponded: true},
},
},
}
// generate all possible scoredData tuples
// with one or less userResponded as true and only 1 correct choice
function generateScoredDataTuples(choiceIds) {
return cartesianProduct(identityMatrix([1, 0], choiceIds.length), [
choiceIds.map(() => false),
...identityMatrix([true, false], choiceIds.length),
]).map(tuple => zipAll([choiceIds, ...tuple]))
}
describe('Multiple Choice Result', () => {
generateScoredDataTuples(['uuid1', 'uuid2', 'uuid3']).forEach(tuples => {
const scoredData = {}
tuples.forEach(([id, resultScore, userResponded]) => {
scoredData[id] = {resultScore, userResponded}
})
it(`renders radio inputs for scoredData tuple ${JSON.stringify(tuples)}`, async () => {
await mount(<MultipleChoiceResult {...props} scoredData={{value: scoredData}} />)
const inputs = await findAll('input[type="radio"]')
tuples.forEach(([_, __, userResponded], index) => {
expect(inputs[index].getDOMNode().checked).to.equal(!!userResponded)
})
})
})
describe('with unknown response', async () => {
const scoredData = {
value: null,
}
it('displays a (response not displayed) message', async () => {
const subject = await mount(<MultipleChoiceResult {...props} scoredData={scoredData} />)
expect(subject.getDOMNode().textContent).to.include('response not displayed')
})
})
describe('with no answer', () => {
const scoredData = {
value: {
uuid1: {resultScore: 0, correct: false, userResponded: false},
uuid2: {resultScore: 1, correct: true, userResponded: false},
uuid3: {resultScore: 0, correct: false, userResponded: false},
uuid4: {resultScore: 0, correct: false, userResponded: false},
},
}
it('displays a (no answer) message', async () => {
const subject = await mount(<MultipleChoiceResult {...props} scoredData={scoredData} />)
expect(subject.getDOMNode().textContent).to.include('no answer')
})
it('displays the correct answer', async () => {
const subject = await mount(<MultipleChoiceResult {...props} scoredData={scoredData} />)
expect(subject.getDOMNode().textContent).to.match(/\bcorrect answer:\s*alexander hamilton/i)
})
describe('when correct answer unknown', () => {
const scoredData = {
value: {
uuid1: {userResponded: false},
uuid2: {userResponded: false},
uuid3: {userResponded: false},
uuid4: {userResponded: false},
},
}
it('displays a (no answer) message', async () => {
const subject = await mount(<MultipleChoiceResult {...props} scoredData={scoredData} />)
expect(subject.getDOMNode().textContent).to.include('no answer')
})
it('does not show a correct answer', async () => {
const subject = await mount(<MultipleChoiceResult {...props} scoredData={scoredData} />)
expect(subject.getDOMNode().textContent).not.to.match(/\bcorrect answer\b/i)
})
})
})
it('should meet a11y standards', async () => {
const subject = await mount(<MultipleChoiceResult {...props} />)
const multipleChoiceResult = within(subject.getDOMNode())
expect(
await multipleChoiceResult.accessible({
ignores: ['radiogroup'], // https://github.com/dequelabs/axe-core/issues/176
}),
).to.be.true()
})
})