UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

231 lines (206 loc) 7.9 kB
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 &nbsp; into a space character', async () => { expect(getRceEssayContent('<p>one&nbsp;two&nbsp;three</p>')).toBe(`one${nbsp}two${nbsp}three`) }) it('correctly decodes html encoded symbols', async () => { expect(getRceEssayContent('<p>one&lt;two&gt;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) }) }) })