UNPKG

@instructure/quiz-taking

Version:
224 lines (199 loc) • 7.13 kB
import React from 'react' import {AttemptHistory} from '../presenter' import {describe, expect, it, vi} from 'vitest' import userEvent from '@testing-library/user-event' import {render, screen} from '../../../../tests/utils/rtlRenderOverride' describe('AttemptHistory Presenter', () => { const attempt = { authoritative: false, displayName: null, percentage: 0.8, pointsPossible: 10, score: 8, quizSessionId: '1', } const attemptHistory = [attempt] const props = { attemptHistory, getQuizSessions: () => {}, quizId: '42', scoreToKeep: 'highest', selectedSessionId: '1', isSurvey: false, } it('renders AttemptHistoryPresenter', () => { render(<AttemptHistory {...props} />) expect(screen.getByRole('cell', {name: /8 of 10/i})).toBeInTheDocument() }) it('renders scores as letter grades when restrictQuantitativeData', () => { render( <AttemptHistory {...props} restrictQuantitativeData gradingScheme={[ {name: 'A-', value: 0.9}, {name: 'F', value: 0.0}, ]} />, ) expect(screen.getByRole('columnheader', {name: /grade/i})).toBeInTheDocument() }) describe('includes information about score to keep', () => { describe('scoreToKeep is average', () => { it('displays the correct scoreToKeep name', () => { render(<AttemptHistory {...props} scoreToKeep="average" />) expect(screen.getByText(/average score/i)).toBeInTheDocument() }) }) describe('scoreToKeep is first', () => { it('displays the correct scoreToKeep name', () => { render(<AttemptHistory {...props} scoreToKeep="first" />) expect(screen.getByText(/first score is kept/i)).toBeInTheDocument() }) }) }) it('displays display name if present', () => { const displayName = 'Average' const attemptWithDisplayName = { ...attempt, displayName, } render(<AttemptHistory {...props} attemptHistory={[attemptWithDisplayName]} />) expect(screen.getByText(/average/i)).toBeInTheDocument() }) it('renders empty when no results are present', () => { render(<AttemptHistory {...props} attemptHistory={[]} />) expect(screen.getByText(/no attempt information/i)).toBeInTheDocument() }) it('renders when missing points possible', () => { const attempt = { authoritative: true, score: 1000000, quizSessionId: '1', } render(<AttemptHistory {...props} attemptHistory={[attempt]} />) expect(screen.getByText(/1,000,000/i)).toBeInTheDocument() expect(screen.queryByText(/undefined/i)).not.toBeInTheDocument() expect(screen.queryByText(/NaN/i)).not.toBeInTheDocument() }) it('calls getQuizSessions when attempt history is given', () => { const getQuizSessionsStub = vi.fn() render(<AttemptHistory {...props} getQuizSessions={getQuizSessionsStub} />) expect(getQuizSessionsStub).toHaveBeenCalledExactlyOnceWith('42', {ids: ['1']}) }) it('does not call getQuizSessions when no attempt history is given', () => { const getQuizSessionsStub = vi.fn() render( <AttemptHistory {...props} attemptHistory={null} getQuizSessions={getQuizSessionsStub} />, ) expect(getQuizSessionsStub).not.toHaveBeenCalled() }) it('does not render anything when no attempt history is given', () => { render(<AttemptHistory {...props} attemptHistory={null} />) expect(screen.queryByRole('table', {name: /attempt history/i})).not.toBeInTheDocument() }) it('does not call getQuizSessions when attempt history does not include quiz session ids', () => { const attempt = { authoritative: true, percentage: 0.8, pointsPossible: 10, score: 8, } const getQuizSessionsStub = vi.fn() render( <AttemptHistory {...props} attemptHistory={[attempt]} getQuizSessions={getQuizSessionsStub} />, ) expect(getQuizSessionsStub).not.toHaveBeenCalled() }) it('calls getQuizSessions on update if there were none previously', () => { const getQuizSessionsStub = vi.fn() const {rerender} = render( <AttemptHistory {...props} attemptHistory={null} getQuizSessions={getQuizSessionsStub} />, ) rerender( <AttemptHistory {...props} getQuizSessions={getQuizSessionsStub} attemptHistory={attemptHistory} />, ) expect(getQuizSessionsStub).toHaveBeenCalledExactlyOnceWith('42', {ids: ['1']}) }) it('calls getQuizSessions on update if the new ones have different quiz session ids', () => { const getQuizSessionsStub = vi.fn() const {rerender} = render(<AttemptHistory {...props} getQuizSessions={getQuizSessionsStub} />) rerender( <AttemptHistory {...props} getQuizSessions={getQuizSessionsStub} attemptHistory={[{...attempt, quizSessionId: '2'}]} />, ) expect(getQuizSessionsStub).toHaveBeenCalledTimes(2) expect(getQuizSessionsStub).toHaveBeenCalledWith('42', {ids: ['1']}) expect(getQuizSessionsStub).toHaveBeenCalledWith('42', {ids: ['2']}) }) it('does not call getQuizSessions on update if attempts do not change', () => { const getQuizSessionsStub = vi.fn() const {rerender} = render(<AttemptHistory {...props} getQuizSessions={getQuizSessionsStub} />) rerender( <AttemptHistory {...props} getQuizSessions={getQuizSessionsStub} attemptHistory={[{...attempt}]} />, ) expect(getQuizSessionsStub).toHaveBeenCalledTimes(1) }) it('renders average score, if given', () => { render(<AttemptHistory {...props} averageScore={0.8} />) expect(screen.getByRole('row', {name: /average score.*80%/i})).toBeInTheDocument() }) it('renders average score as a letter grade when restrictedQuantitativeData', () => { render( <AttemptHistory {...props} averageScore={0.91} restrictQuantitativeData gradingScheme={[ {name: 'A-', value: 0.9}, {name: 'F', value: 0.0}, ]} />, ) expect(screen.getByRole('row', {name: /average score.*a-/i})).toBeInTheDocument() }) it('falls back to letter grade when percentage is not available', () => { const attempt = { authoritative: true, percentage: null, pointsPossible: 10, score: 8, } render( <AttemptHistory {...props} attemptHistory={[attempt]} restrictQuantitativeData gradingScheme={[ {name: 'A-', value: 0.8}, {name: 'F', value: 0.0}, ]} />, ) expect(screen.getByRole('row', {name: /attempt 1.*a-/i})).toBeInTheDocument() }) describe('when callback is provided', () => { it('sends quizSessionId to callback', () => { const onAttemptClick = vi.fn() render(<AttemptHistory {...props} onAttemptClick={onAttemptClick} />) const button = screen.getByRole('button', {name: /attempt 1/i}) userEvent.click(button) expect(onAttemptClick).toHaveBeenCalledWith(attempt.quizSessionId) }) }) })