-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from leung018:mc-17-edit-page-logic
Mc-17-edit-page-logic Part 1
- Loading branch information
Showing
6 changed files
with
463 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
}), | ||
}, | ||
]) | ||
}) | ||
}) |
Oops, something went wrong.