@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
231 lines (206 loc) • 7.9 kB
JavaScript
import {vi} from 'vitest'
import React from 'react'
import {accessible, mount, within} from '@instructure/ui-test-utils'
import {render, screen} from '../../../../../../tests/util/rtlRenderOverride'
import {WordCount, countWords, getRceEssayContent, showWordCount} from '../index'
const nbsp = String.fromCharCode(160)
const essay12 = `One, tw'o thr-ee fo_ur <five>six<seven> eight&nine ten${nbsp}11 12.`
describe('<WordCount />', async () => {
describe('#countWords', async () => {
it('gets the right amount of words from a string', async () => {
expect(countWords(essay12)).toBe(12)
})
it('counts the longest Finnish word as one word', async () => {
expect(countWords('epäjärjestelmällistyttämättömyydellänsäkäänköhän')).toBe(1)
})
it('counts the longest Korean word as one word', async () => {
expect(countWords('청자양인각연당초상감모란문은구대접')).toBe(1)
})
})
describe('#getRceEssayContent', async () => {
it('removes html tags', async () => {
expect(getRceEssayContent('<p>one two three</p>')).toBe('one two three')
})
it('decodes into a space character', async () => {
expect(getRceEssayContent('<p>one two three</p>')).toBe(`one${nbsp}two${nbsp}three`)
})
it('correctly decodes html encoded symbols', async () => {
expect(getRceEssayContent('<p>one<two>three</p>')).toBe('one<two>three')
})
})
describe('#showWordCount', async () => {
it('returns false if word count is off', async () => {
expect(showWordCount(false, true, true)).toBe(false)
expect(showWordCount(false, true, false)).toBe(false)
expect(showWordCount(false, false, true)).toBe(false)
expect(showWordCount(false, false, false)).toBe(false)
})
describe('with wordCount on', () => {
it('returns false if RCE is used during editing', () => {
expect(showWordCount(true, true, true)).toBe(false)
})
it('returns true if RCE is used without editing', () => {
expect(showWordCount(true, true, false)).toBe(true)
})
it('returns true if RCE is not used', () => {
expect(showWordCount(true, false, true)).toBe(true)
expect(showWordCount(true, false, false)).toBe(true)
})
})
})
describe('rendering', async () => {
it('should not show errors when within bounds', async () => {
const subject = await mount(
<WordCount
essay={essay12}
wordCount={true}
wordLimitEnabled={true}
wordLimitMin={1}
wordLimitMax={25}
/>,
)
const wordcount = await within(subject.getDOMNode())
expect(wordcount).toBeDefined()
const counttxt = await wordcount.find(':textContent(12 words)')
expect(counttxt).toBeDefined()
const maxerrortxt = await wordcount.find(':textContent(Maximum words exceeded!)', {
expectEmpty: true,
})
expect(maxerrortxt).toBeNull()
const minerrortxt = await wordcount.find(':textContent(Must use at least)', {
expectEmpty: true,
})
expect(minerrortxt).toBeNull()
})
it('should show errors when out of bounds', async () => {
const subject = await mount(
<WordCount
essay={essay12}
wordCount={true}
wordLimitEnabled={true}
wordLimitMin={1}
wordLimitMax={5}
/>,
)
const wordcount = await within(subject.getDOMNode())
expect(wordcount).toBeDefined()
const counttxt = await wordcount.find(':textContent(12 words)')
expect(counttxt).toBeDefined()
const errortxt = await wordcount.find(':textContent(Maximum words exceeded!)')
expect(errortxt).toBeDefined()
})
it('should not show the wordCount when off', async () => {
const subject = await mount(<WordCount essay={essay12} wordCount={false} />)
const wordcount = await within(subject.getDOMNode())
expect(wordcount).toBeDefined()
expect(await wordcount.find(':textContent(12 words)', {expectEmpty: true})).toBeNull()
})
})
describe('limits', async () => {
it('produce errors when above maximum', async () => {
const notifyScreenreaderStub = vi.fn()
const subject = await mount(
<WordCount
essay="one two three"
notifyScreenreader={notifyScreenreaderStub}
wordCount={true}
wordLimitEnabled={true}
wordLimitMax={3}
wordLimitMin={1}
/>,
)
await subject.setProps({essay: 'one two three four'})
const wordcount = await within(subject.getDOMNode())
expect(await wordcount.find(':textContent(Maximum words exceeded!)')).toBeDefined()
expect(notifyScreenreaderStub).toHaveBeenCalled()
expect(notifyScreenreaderStub.mock.calls[0][0]).toBe('Maximum words exceeded!')
await subject.setProps({essay: 'one two three four five'})
expect(notifyScreenreaderStub).toHaveBeenCalled()
expect(notifyScreenreaderStub.mock.calls[1][0]).toBe('Maximum words exceeded!')
})
it('produce errors when below minimum', async () => {
const notifyScreenreaderStub = vi.fn()
const subject = await mount(
<WordCount
essay="one two three"
notifyScreenreader={notifyScreenreaderStub}
wordCount={true}
wordLimitEnabled={true}
wordLimitMax={5}
wordLimitMin={3}
/>,
)
await subject.setProps({essay: 'one two'})
const wordcount = await within(subject.getDOMNode())
expect(await wordcount.find(':textContent(Must use at least 3 words)')).toBeDefined()
expect(notifyScreenreaderStub).toHaveBeenCalled()
expect(notifyScreenreaderStub.mock.calls[0][0]).toBe('Must use at least 3 words')
})
it('should extend word limit text with explanation', async () => {
const subject = await mount(
<WordCount
essay="one two"
wordCount={true}
wordLimitEnabled={true}
wordLimitMax={5}
wordLimitMin={3}
/>,
)
const wordcount = await within(subject.getDOMNode())
const content = wordcount.getTextContent()
expect(content).toContain('(word limit)')
})
it('should not show errors when wordLimitEnabled is false even if limit values exist', () => {
render(
<WordCount
essay={essay12}
wordCount={true}
wordLimitEnabled={false}
wordLimitMin={1}
wordLimitMax={5}
/>,
)
expect(screen.getByText('12 words')).toBeDefined()
expect(screen.queryByText('Maximum words exceeded!')).toBeNull()
})
it('should not show warning icon when wordLimitEnabled is false', () => {
const {container} = render(
<WordCount
essay={essay12}
wordCount={true}
wordLimitEnabled={false}
wordLimitMin={1}
wordLimitMax={5}
/>,
)
const warningIcon = container.querySelector('svg[name="IconWarningSolid"]')
expect(warningIcon).toBeNull()
})
it('should not show word limit text when wordLimitEnabled is false', () => {
const {container} = render(
<WordCount
essay="one two"
wordCount={true}
wordLimitEnabled={false}
wordLimitMax={5}
wordLimitMin={3}
/>,
)
expect(container.textContent).not.toContain('(word limit)')
})
})
describe('a11y tests', async () => {
it('should meet a11y standards', async () => {
await mount(
<WordCount
essay={essay12}
wordCount={true}
wordLimitEnabled={true}
wordLimitMax={25}
wordLimitMin={1}
/>,
)
expect(await accessible(document.body, {ignores: ['region']})).toBe(true)
})
})
})