Skip to content

Commit

Permalink
Merge pull request #14 from leung018:mc-17-edit-page-logic
Browse files Browse the repository at this point in the history
Mc-17-edit-page-logic Part 1
  • Loading branch information
leung018 authored Nov 14, 2023
2 parents 5ada66d + 3205328 commit ee156b4
Show file tree
Hide file tree
Showing 6 changed files with 463 additions and 127 deletions.
283 changes: 259 additions & 24 deletions src/app/components/mc/editor.test.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,275 @@
import { fireEvent, render } from '@testing-library/react'
import { QuestionSetRepoFactory } from '../../../repo/question_set'
import { fireEvent, render, screen } from '@testing-library/react'
import {
QuestionSetRepo,
QuestionSetRepoFactory,
} from '../../../repo/question_set'
import { QuestionSetEditorUIService } from './editor'
import { MultipleChoice } from '../../../model/mc'

describe('QuestionSetEditor', () => {
it('should save question set', () => {
const editorRepo = QuestionSetRepoFactory.createTestInstance()
const { getByLabelText, getByText } = render(
class UIServiceInteractor {
readonly screen
private readonly editorRepo: QuestionSetRepo
private questionSetName: string
private questionNumberFocus = 1

constructor({ questionSetName = 'Dummy name' }) {
this.editorRepo = QuestionSetRepoFactory.createTestInstance()
render(
QuestionSetEditorUIService.createTestInstance({
editorRepo,
editorRepo: this.editorRepo,
}).getElement(),
)
const questionSetNameInput = getByLabelText('Question Set Name:')
const questionInput = getByLabelText('Question 1:')
this.screen = screen

this.questionSetName = questionSetName
this.syncQuestionSetName()
}

private syncQuestionSetName() {
fireEvent.change(screen.getByLabelText('Question Set Name:'), {
target: { value: this.questionSetName },
})
return this
}

const choice1Input = getByLabelText('Choice 1:')
const isChoice1CorrectInput = getByLabelText('Choice 1 is correct answer')
const isChoice1FixedPositionInput = getByLabelText(
'Choice 1 is fixed position',
setQuestionNumberFocus(questionNumber: number) {
this.questionNumberFocus = questionNumber
return this
}

getSavedQuestionSet() {
return this.editorRepo.getQuestionSetByName(this.questionSetName)
}

inputQuestionDescription({ description }: { description: string }) {
fireEvent.change(
screen.getByLabelText(`Question ${this.questionNumberFocus}:`),
{
target: { value: description },
},
)
return this
}

inputAnswer({
choiceNumber,
answer,
}: {
choiceNumber: number
answer: string
}) {
fireEvent.change(
screen.getByLabelText(
`answer of question ${this.questionNumberFocus} choice ${choiceNumber}`,
),
{
target: { value: answer },
},
)
return this
}

clickFixedPosition({ choiceNumber }: { choiceNumber: number }) {
fireEvent.click(
screen.getByLabelText(
`question ${this.questionNumberFocus} choice ${choiceNumber} is fixed position`,
),
)
return this
}

clickCorrectAnswer({ choiceNumber }: { choiceNumber: number }) {
fireEvent.click(
screen.getByLabelText(
`question ${this.questionNumberFocus} choice ${choiceNumber} is correct answer`,
),
)
return this
}

clickAddChoice() {
const addChoiceButtons = screen.getAllByText('Add Choice')
fireEvent.click(addChoiceButtons[this.questionNumberFocus - 1])
return this
}

const choice2Input = getByLabelText('Choice 2:')
clickAddQuestion() {
fireEvent.click(screen.getByText('Add Question'))
return this
}

fireEvent.change(questionSetNameInput, { target: { value: 'Test name' } })
fireEvent.change(questionInput, { target: { value: 'Am I handsome?' } })
fireEvent.change(choice1Input, { target: { value: 'True' } })
fireEvent.change(isChoice1CorrectInput, { target: { value: 'true' } })
fireEvent.change(isChoice1FixedPositionInput, {
target: { value: 'true' },
clickSave() {
fireEvent.click(screen.getByText('Save'))
return this
}
}

describe('QuestionSetEditorUIService', () => {
it('should save question set successfully when no extra choice or question added', () => {
const interactor = new UIServiceInteractor({ questionSetName: 'Test name' })
interactor
.setQuestionNumberFocus(1)
.inputQuestionDescription({ description: 'Am I handsome?' })
.inputAnswer({ choiceNumber: 1, answer: 'True' })
.clickFixedPosition({ choiceNumber: 1 })
.inputAnswer({ choiceNumber: 2, answer: 'False' })
.clickCorrectAnswer({ choiceNumber: 2 })
.clickSave()

const actualQuestionSet = interactor.getSavedQuestionSet()

expect(actualQuestionSet.name).toBe('Test name')
expect(actualQuestionSet.questions).toEqual([
{
description: 'Am I handsome?',
mc: new MultipleChoice({
choices: [
{
answer: 'True',
isFixedPosition: true,
},
{
answer: 'False',
isFixedPosition: false,
},
],
correctChoiceIndex: 1,
}),
},
])
})

it('should also save all input specified in extra option', () => {
const interactor = new UIServiceInteractor({})
interactor
.setQuestionNumberFocus(1)
.inputQuestionDescription({ description: '1 + 1 = ?' })

interactor
.inputAnswer({ choiceNumber: 1, answer: '1' })
.inputAnswer({ choiceNumber: 2, answer: '0' })
.clickAddChoice()
.inputAnswer({ choiceNumber: 3, answer: 'None of the above' })
.clickCorrectAnswer({ choiceNumber: 3 })
.clickFixedPosition({ choiceNumber: 3 })
.clickSave()

const actualQuestionSet = interactor.getSavedQuestionSet()
expect(actualQuestionSet.questions[0]).toEqual({
description: '1 + 1 = ?',
mc: new MultipleChoice({
choices: [
{
answer: '1',
isFixedPosition: false,
},
{
answer: '0',
isFixedPosition: false,
},
{
answer: 'None of the above',
isFixedPosition: true,
},
],
correctChoiceIndex: 2,
}),
})
})

it('should save question set after multiple clicks of add choice and add question', () => {
const interactor = new UIServiceInteractor({})

interactor
.setQuestionNumberFocus(1)
.inputQuestionDescription({ description: '1 + 1 = ?' })
.inputAnswer({ choiceNumber: 1, answer: '2' })
.inputAnswer({ choiceNumber: 2, answer: '0' })
.clickCorrectAnswer({ choiceNumber: 1 })

interactor.clickAddQuestion()

interactor
.setQuestionNumberFocus(2)
.inputQuestionDescription({ description: '1 + 2 = ?' })
.inputAnswer({ choiceNumber: 1, answer: '3' })
.inputAnswer({ choiceNumber: 2, answer: '0' })
.clickCorrectAnswer({ choiceNumber: 1 })

fireEvent.change(choice2Input, { target: { value: 'False' } })
interactor.clickAddQuestion()

fireEvent.click(getByText('Save'))
interactor
.setQuestionNumberFocus(3)
.inputQuestionDescription({ description: '1 + 3 = ?' })
.inputAnswer({ choiceNumber: 1, answer: '1' })
.inputAnswer({ choiceNumber: 2, answer: '3' })
.clickAddChoice()
.clickAddChoice()
.inputAnswer({ choiceNumber: 3, answer: '0' })
.inputAnswer({ choiceNumber: 4, answer: 'None of the above' })
.clickCorrectAnswer({ choiceNumber: 4 })
.clickFixedPosition({ choiceNumber: 4 })

const actualQuestionSet = editorRepo.getQuestionSetByName('Test name')
interactor.clickSave()

// TODO: Assert the question set is saved with expected values
const actualQuestionSet = interactor.getSavedQuestionSet()
expect(actualQuestionSet.questions).toEqual([
{
description: '1 + 1 = ?',
mc: new MultipleChoice({
choices: [
{
answer: '2',
isFixedPosition: false,
},
{
answer: '0',
isFixedPosition: false,
},
],
correctChoiceIndex: 0,
}),
},
{
description: '1 + 2 = ?',
mc: new MultipleChoice({
choices: [
{
answer: '3',
isFixedPosition: false,
},
{
answer: '0',
isFixedPosition: false,
},
],
correctChoiceIndex: 0,
}),
},
{
description: '1 + 3 = ?',
mc: new MultipleChoice({
choices: [
{
answer: '1',
isFixedPosition: false,
},
{
answer: '3',
isFixedPosition: false,
},
{
answer: '0',
isFixedPosition: false,
},
{
answer: 'None of the above',
isFixedPosition: true,
},
],
correctChoiceIndex: 3,
}),
},
])
})
})
Loading

0 comments on commit ee156b4

Please sign in to comment.