UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

293 lines (248 loc) • 9.13 kB
import React from 'react' import update from 'immutability-helper' import {expect, find, mount, within} from '@instructure/ui-test-utils' import * as util from '../util' import FormulaSection from '../FormulaSection' import {render, screen} from '@testing-library/react' describe('FormulaSection', () => { const defaultProps = { formulaErrors: [], generatedSolutionsErrors: [], handleAnswerCountChange: Function.prototype, handleAnswerPrecisionChange: Function.prototype, handleFormulaChange: Function.prototype, handleGenerateSolutions: Function.prototype, handleMarginOfErrorChange: Function.prototype, handleMarginOfErrorTypeChange: Function.prototype, handleScientificNotationChange: Function.prototype, locale: 'en', overrideEditableForRegrading: false, scoringData: { value: { generatedSolutions: [ { inputs: [{name: 'x', value: 2}], output: 2, }, { inputs: [{name: 'x', value: 3}], output: 3, }, ], numeric: { type: 'marginOfError', margin: '0', marginType: 'absolute', }, variables: [{name: 'x', min: 0, max: 5, precision: 1}], }, }, status: util.STATUS_STOPPED, } it('renders a table and no spinner when solutions are available', async () => { render(<FormulaSection {...defaultProps} />) expect(screen.queryByRole('table')).to.not.be.null() expect(screen.queryByRole('img', {name: /running/i})).to.be.null() }) // TODO: QUIZ-17438 - This test fails in jsdom due to getAttributeNames not being // available on some internal element during Inst UI Spinner rendering. The component // behavior is verified by the surrounding tests. Needs jsdom upgrade or Spinner mock. it.skip('renders a spinner and no table while waiting for solutions', async () => { const testProps = { ...defaultProps, status: util.STATUS_RUNNING, } render(<FormulaSection {...testProps} />) expect(screen.queryByRole('table')).to.be.null() expect(screen.queryByRole('img', {name: /running/i})).to.not.be.null() }) it('renders neither a table nor spinner when canceled', async () => { const testProps = { ...defaultProps, status: util.STATUS_CANCELED, } render(<FormulaSection {...testProps} />) expect(screen.queryByRole('table')).to.be.null() expect(screen.queryByRole('img', {name: /running/i})).to.be.null() }) it('renders neither a table nor spinner when there are no solutions and stopped', async () => { const testProps = { ...defaultProps, scoringData: { value: { generatedSolutions: [], variables: [], numeric: { type: 'marginOfError', margin: '0', marginType: 'absolute', }, }, }, } render(<FormulaSection {...testProps} />) expect(screen.queryByRole('table')).to.be.null() expect(screen.queryByRole('img', {name: /running/i})).to.be.null() }) it('renders a message when not enough solutions could be found', async () => { const testProps = { ...defaultProps, status: util.STATUS_FAILED, } const subject = await mount(<FormulaSection {...testProps} />) const formulaSection = within(subject.getDOMNode()) expect(formulaSection.getTextContent()).to.match(/We were only able to find 2 solutions\./) }) it('renders a message when no solutions could be found', async () => { const scoringData = update(defaultProps.scoringData, { value: { generatedSolutions: {$set: []}, }, }) const testProps = { ...defaultProps, status: util.STATUS_FAILED, scoringData, } const subject = await mount(<FormulaSection {...testProps} />) const formulaSection = within(subject.getDOMNode()) expect(formulaSection.getTextContent()).to.match(/We were not able to find any solutions\./) }) it('renders error messages with invalid setup', async () => { const testProps = { ...defaultProps, status: util.STATUS_FORMULA_SETUP_INVALID, formulaErrors: ['hello world'], } const subject = await mount(<FormulaSection {...testProps} />) const formulaSection = within(subject.getDOMNode()) expect(formulaSection.getTextContent()).to.include('hello world') }) it('does not render error messages with valid setup', async () => { const testProps = { ...defaultProps, status: util.STATUS_STOPPED, formulaErrors: ['hello world'], } const subject = await mount(<FormulaSection {...testProps} />) const formulaSection = within(subject.getDOMNode()) expect(formulaSection.getTextContent()).to.not.include('hello world') }) describe('override editable for regrading', () => { it('renders a disabled formula input', async () => { const testProps = { ...defaultProps, overrideEditableForRegrading: true, } const subject = await mount(<FormulaSection {...testProps} />) const formulaSection = within(subject.getDOMNode()) const formulaTextarea = await formulaSection.find(':label(Formula)') expect(formulaTextarea.getDOMNode().disabled).to.be.true() }) it('renders disabled generate button', async () => { const testProps = { ...defaultProps, overrideEditableForRegrading: true, } const subject = await mount(<FormulaSection {...testProps} />) const formulaSection = within(subject.getDOMNode()) const generateButton = await formulaSection.find(':label(Generate)', {exact: false}) expect(generateButton.getDOMNode().disabled).to.be.true() }) }) describe('formatNumStr', () => { it('properly formats en numbers', async () => { const scoringData = update(defaultProps.scoringData, { value: { generatedSolutions: { $set: [{inputs: [{name: 'x', value: 4000.5}], output: 4000.5}], }, }, }) const testProps = { ...defaultProps, scoringData, locale: 'en', } const subject = await mount(<FormulaSection {...testProps} />) const formulaSection = within(subject.getDOMNode()) const formatted = await formulaSection.find(':textContent(4,000.5)') expect(formatted).to.be.ok() }) it('properly formats non-en numbers', async () => { const scoringData = update(defaultProps.scoringData, { value: { generatedSolutions: { $set: [{inputs: [{name: 'x', value: 4000.5}], output: 4000.5}], }, }, }) const testProps = { ...defaultProps, scoringData, locale: 'fr', } const subject = await mount(<FormulaSection {...testProps} />) const formulaSection = within(subject.getDOMNode()) const formatted = await formulaSection.find(':textContent(4 000,5)') expect(formatted).to.be.ok() }) it('properly formats en for multiple variables', async () => { const scoringData = update(defaultProps.scoringData, { value: { variables: { $push: [{name: 'x', min: 0, max: 5, precision: 5}], }, generatedSolutions: { $set: [{inputs: [{name: 'x', value: 4.56789}], output: 4.56789}], }, }, }) const testProps = { ...defaultProps, scoringData, } const subject = await mount(<FormulaSection {...testProps} />) const formulaSection = within(subject.getDOMNode()) const formatted = await formulaSection.find(':textContent(4.56789)') expect(formatted).to.be.ok() }) it('does localize numbers in scientific notation', async () => { const scoringData = { ...defaultProps.scoringData, value: { ...defaultProps.scoringData.value, variables: [ {name: 'x', min: '5.0*10^-3', max: '2.5*10^-2', precision: '1'}, {name: 'y', min: '0.01', max: '0.10', precision: '2'}, ], generatedSolutions: [ { inputs: [ {name: 'x', value: '6.2*10^-3'}, {name: 'y', value: '0.07'}, ], output: '0.076', }, ], }, } await mount(<FormulaSection {...defaultProps} locale="es" scoringData={scoringData} />) expect(await find(':textContent(6,2*10^-3)')).to.be.ok() expect(await find(':textContent(0,07)')).to.be.ok() expect(await find(':textContent(0,076)')).to.be.ok() }) }) it('should meet a11y standards', async () => { const subject = await mount(<FormulaSection {...defaultProps} />) const formulaSection = within(subject.getDOMNode()) expect( await formulaSection.accessible({ ignores: [ 'aria-allowed-role', // TODO: remove this when instui fixes Select 'aria-allowed-attr', ] /* QUIZ-8495 */, }), ).to.be.true() }) })