Skip to content

Commit

Permalink
Merge pull request #12 from leung018/mc-12-edit-mc-set-page
Browse files Browse the repository at this point in the history
  • Loading branch information
leung018 authored Oct 26, 2023
2 parents e34aa03 + c989fa0 commit 8c6fb2d
Show file tree
Hide file tree
Showing 13 changed files with 243 additions and 11 deletions.
40 changes: 40 additions & 0 deletions src/app/components/mc/editor.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { fireEvent, render } from '@testing-library/react'
import { QuestionSetRepoFactory } from '../../../repo/question_set'
import { QuestionSetEditorUIService } from './editor'

describe('QuestionSetEditor', () => {
it('should save question set', () => {
const editorRepo = QuestionSetRepoFactory.createTestInstance()
const { getByLabelText, getByText } = render(
QuestionSetEditorUIService.createTestInstance({
editorRepo,
}).getElement(),
)
const questionSetNameInput = getByLabelText('Question Set Name:')
const questionInput = getByLabelText('Question 1:')

const choice1Input = getByLabelText('Choice 1:')
const isChoice1CorrectInput = getByLabelText('Choice 1 is correct answer')
const isChoice1FixedPositionInput = getByLabelText(
'Choice 1 is fixed position',
)

const choice2Input = getByLabelText('Choice 2:')

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' },
})

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

fireEvent.click(getByText('Save'))

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

// TODO: Assert the question set is saved with expected values
})
})
134 changes: 134 additions & 0 deletions src/app/components/mc/editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import {
QuestionSetRepo,
QuestionSetRepoFactory,
} from '../../../repo/question_set'

export class QuestionSetEditorUIService {
static create() {
return new QuestionSetEditorUIService({
editorRepo: QuestionSetRepoFactory.createTestInstance(), // TODO: replace with real repo
})
}

static createTestInstance({
editorRepo = QuestionSetRepoFactory.createTestInstance(),
}) {
return new QuestionSetEditorUIService({ editorRepo })
}

private editorRepo: QuestionSetRepo

private constructor({ editorRepo }: { editorRepo: QuestionSetRepo }) {
this.editorRepo = editorRepo
}

getElement() {
return <QuestionSetEditor />
}
}

function QuestionSetEditor() {
return (
<div className="container mx-auto p-4">
<div className="form-group">
<label htmlFor="question-set-name">
<h1 className="text-lg font-bold mb-2">Question Set Name:</h1>
</label>
<input
type="text"
id="question-set-name"
className="border border-gray-300 px-2 py-1 w-full"
/>
</div>

<div className="mb-8">
<label>
<h2 className="text-lg font-bold mb-2">Question 1:</h2>
<input
type="text"
className="border border-gray-300 px-2 py-1 w-full"
/>
</label>
<div className="form-group">
<div className="grid grid-cols-5 gap-4">
<div className="col-span-3"></div>
<div className="col-span-1 text-center">Correct Answer</div>
<div className="col-span-1 text-center">Fixed Position</div>

<div className="col-span-3">
<label>
Choice 1:
<input
type="text"
className="border border-gray-300 px-2 py-1 ml-2"
/>
</label>
</div>
<div className="col-span-1 flex items-center justify-center">
<input
type="checkbox"
className="mr-1"
aria-label="Choice 1 is correct answer"
/>
</div>
<div className="col-span-1 flex items-center justify-center">
<input
type="checkbox"
className="mr-1"
aria-label="Choice 1 is fixed position"
/>
</div>
{/* TODO: Refactor the below duplication */}
<div className="col-span-3">
<label>
Choice 2:
<input
type="text"
className="border border-gray-300 px-2 py-1 ml-2"
/>
</label>
</div>
<div className="col-span-1 flex items-center justify-center">
<input
type="checkbox"
className="mr-1"
aria-label="Choice 2 is correct answer"
/>
</div>
<div className="col-span-1 flex items-center justify-center">
<input
type="checkbox"
className="mr-1"
aria-label="Choice 2 is fixed position"
/>
</div>

<div className="col-span-1">
<button
type="button"
className="bg-blue-500 text-white px-4 py-2 rounded"
>
Add Choice
</button>
</div>
</div>
</div>
</div>
<button
type="button"
className="bg-blue-500 text-white px-4 py-2 rounded"
>
Add Question
</button>

<div className="flex items-center justify-center w-full">
<button
type="button"
className="bg-green-500 text-white px-4 py-2 rounded"
>
Save
</button>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { MultipleChoice } from '../../../mc/mc'
import { MultipleChoice } from '../../../model/mc'
import {
MultipleChoiceQuestion,
MultipleChoiceQuestionFactory,
} from '../../../mc/question'
} from '../../../model/question'
import { render, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom'
import MultipleChoicePage from './display'
import MultipleChoiceQuiz from './quiz'

describe('MultipleChoicePage', () => {
describe('MultipleChoiceQuiz', () => {
it('should render title and choices of a question', () => {
const { getByText, getByLabelText } = renderMultipleChoicePage({
questions: [
Expand Down Expand Up @@ -98,5 +98,5 @@ function renderMultipleChoicePage({
}: {
questions: MultipleChoiceQuestion[]
}) {
return render(<MultipleChoicePage questions={questions} />)
return render(<MultipleChoiceQuiz questions={questions} />)
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
'use client'

import { useState } from 'react'
import { MultipleChoiceQuestion } from '../../../mc/question'
import { MultipleChoiceQuestion } from '../../../model/question'

interface MultipleChoicePageProps {
questions: MultipleChoiceQuestion[]
}

// TODO: Noted that won't test the rendering of submit button by now. Test that part later in the feature of submitting the answer is more meaningful.
export default function MultipleChoicePage({
export default function MultipleChoiceQuiz({
questions,
}: MultipleChoicePageProps) {
const [questionToCheckedChoiceMap, setCheckedChoice] = useState<
Expand Down
5 changes: 5 additions & 0 deletions src/app/mc/edit/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { QuestionSetEditorUIService } from '../../components/mc/editor'

export default function QuestionSetEditorPage() {
return QuestionSetEditorUIService.create().getElement()
}
8 changes: 4 additions & 4 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import MultipleChoicePage from './components/mc/display'
import { MultipleChoiceQuestion } from '../mc/question'
import { MultipleChoice } from '../mc/mc'
import MultipleChoiceQuiz from './components/mc/quiz'
import { MultipleChoiceQuestion } from '../model/question'
import { MultipleChoice } from '../model/mc'

export default function Home() {
const questions: MultipleChoiceQuestion[] = [
Expand Down Expand Up @@ -32,5 +32,5 @@ export default function Home() {
}),
},
]
return <MultipleChoicePage questions={questions} />
return <MultipleChoiceQuiz questions={questions} />
}
File renamed without changes.
24 changes: 24 additions & 0 deletions src/mc/mc.ts → src/model/mc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,27 @@ export class MultipleChoiceError extends CustomBaseError {
super(code, message)
}
}

// TODO: Migrate MultipleChoice to NewVersionMultipleChoice
export class NewVersionMultipleChoice {
choices: ReadonlyArray<{
description: string
isFixedPosition: boolean
}>

correctChoiceIndex: number

constructor({
choices,
correctChoiceIndex,
}: {
choices: ReadonlyArray<{
description: string
isFixedPosition: boolean
}>
correctChoiceIndex: number
}) {
this.choices = choices
this.correctChoiceIndex = correctChoiceIndex
}
}
File renamed without changes.
9 changes: 9 additions & 0 deletions src/model/question_set.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { NewVersionMultipleChoice } from './mc'

export interface QuestionSet {
name: string
questions: ReadonlyArray<{
title: string
mc: NewVersionMultipleChoice
}>
}
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions src/repo/question_set.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { QuestionSet } from '../model/question_set'

export interface QuestionSetRepo {
getQuestionSetByName(questionSetName: string): QuestionSet
}

export class QuestionSetRepoFactory {
static createTestInstance(): QuestionSetRepo {
return new InMemoryQuestionSetRepo()
}
}

class InMemoryQuestionSetRepo implements QuestionSetRepo {
getQuestionSetByName(questionSetName: string): QuestionSet {
return {
name: 'Sample Question Set',
questions: [],
}
}
}

0 comments on commit 8c6fb2d

Please sign in to comment.