Skip to content

Commit d1b602b

Browse files
authored
Fix section complete logic (#633)
1 parent aefc33f commit d1b602b

File tree

2 files changed

+115
-36
lines changed

2 files changed

+115
-36
lines changed

app/controllers/saveAndContinueController.test.ts

+80-16
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import FormWizard from 'hmpo-form-wizard'
22
import { Response } from 'express'
3-
import Controller from './saveAndContinueController'
3+
import Controller, { Progress, SectionCompleteRule } from './saveAndContinueController'
44

55
describe('SaveAndContinueController', () => {
66
const controller = new Controller({ route: '/' })
77

8-
describe('getSectionProgress', () => {
8+
describe('getSectionProgressAnswers', () => {
99
const conditionFn = jest.fn()
1010

1111
const buildRequestWith = ({
@@ -41,7 +41,7 @@ describe('SaveAndContinueController', () => {
4141
],
4242
})
4343

44-
controller.getSectionProgress(req, true)
44+
controller.getSectionProgressAnswers(req, true)
4545

4646
expect(conditionFn).toHaveBeenCalledTimes(3)
4747
})
@@ -51,7 +51,7 @@ describe('SaveAndContinueController', () => {
5151
sectionProgressRules: [{ fieldCode: 'foo_section_complete', conditionFn }],
5252
})
5353

54-
controller.getSectionProgress(req, true)
54+
controller.getSectionProgressAnswers(req, true)
5555

5656
expect(conditionFn).toHaveBeenLastCalledWith(true, {})
5757
})
@@ -61,7 +61,7 @@ describe('SaveAndContinueController', () => {
6161
sectionProgressRules: [{ fieldCode: 'foo_section_complete', conditionFn }],
6262
})
6363

64-
controller.getSectionProgress(req, false)
64+
controller.getSectionProgressAnswers(req, false)
6565

6666
expect(conditionFn).toHaveBeenLastCalledWith(false, {})
6767
})
@@ -73,7 +73,7 @@ describe('SaveAndContinueController', () => {
7373
formValues,
7474
})
7575

76-
controller.getSectionProgress(req, true)
76+
controller.getSectionProgressAnswers(req, true)
7777

7878
expect(conditionFn).toHaveBeenLastCalledWith(true, formValues)
7979
})
@@ -87,10 +87,9 @@ describe('SaveAndContinueController', () => {
8787
],
8888
})
8989

90-
const result = controller.getSectionProgress(req, true)
90+
const result = controller.getSectionProgressAnswers(req, true)
9191

9292
expect(result).toEqual({
93-
assessment_complete: 'YES',
9493
foo_section_complete: 'YES',
9594
bar_section_complete: 'YES',
9695
baz_section_complete: 'YES',
@@ -106,17 +105,82 @@ describe('SaveAndContinueController', () => {
106105
],
107106
})
108107

109-
const result = controller.getSectionProgress(req, true)
108+
const result = controller.getSectionProgressAnswers(req, true)
110109

111110
expect(result).toEqual({
112-
assessment_complete: 'NO',
113111
foo_section_complete: 'YES',
114112
bar_section_complete: 'NO',
115113
baz_section_complete: 'YES',
116114
})
117115
})
118116
})
119117

118+
describe('getAssessmentProgress', () => {
119+
it('marks the section as complete if all subsections are complete', () => {
120+
const answers: FormWizard.Answers = {
121+
foo_section_complete: 'YES',
122+
bar_section_complete: 'YES',
123+
}
124+
125+
const sectionCompleteRules: SectionCompleteRule[] = [
126+
{ sectionName: 'test_section', fieldCodes: ['foo_section_complete', 'bar_section_complete'] },
127+
]
128+
129+
const result = controller.getAssessmentProgress(answers, sectionCompleteRules)
130+
131+
expect(result).toEqual({
132+
test_section: true,
133+
})
134+
})
135+
136+
it('marks the section as incomplete is a subsection is incomplete', () => {
137+
const answers: FormWizard.Answers = {
138+
foo_section_complete: 'YES',
139+
bar_section_complete: 'NO',
140+
}
141+
142+
const sectionCompleteRules: SectionCompleteRule[] = [
143+
{ sectionName: 'test_section', fieldCodes: ['foo_section_complete', 'bar_section_complete'] },
144+
]
145+
146+
const result = controller.getAssessmentProgress(answers, sectionCompleteRules)
147+
148+
expect(result).toEqual({
149+
test_section: false,
150+
})
151+
})
152+
})
153+
154+
describe('getAssessmentCompletionAnswers', () => {
155+
it('marks the assessment as complete if all sections are complete', () => {
156+
const progress: Progress = {
157+
foo_section_complete: true,
158+
bar_section_complete: true,
159+
baz_section_complete: true,
160+
}
161+
162+
const result = controller.getAssessmentCompletionAnswers(progress)
163+
164+
expect(result).toEqual({
165+
assessment_complete: 'YES',
166+
})
167+
})
168+
169+
it('marks the assessment as incomplete if a section is incomplete', () => {
170+
const progress: Progress = {
171+
foo_section_complete: true,
172+
bar_section_complete: false,
173+
baz_section_complete: true,
174+
}
175+
176+
const result = controller.getAssessmentCompletionAnswers(progress)
177+
178+
expect(result).toEqual({
179+
assessment_complete: 'NO',
180+
})
181+
})
182+
})
183+
120184
describe('updateAssessmentProgress', () => {
121185
const buildRequestWith = ({ persistedAnswers = {} }: { persistedAnswers?: Record<string, string | string[]> }) =>
122186
({
@@ -161,9 +225,9 @@ describe('SaveAndContinueController', () => {
161225
],
162226
})
163227

164-
controller.updateAssessmentProgress(req, res)
228+
const progress = controller.getAssessmentProgress(req.form.persistedAnswers, res.locals.form.sectionProgressRules)
165229

166-
expect(res.locals.sectionProgress?.accommodation).toEqual(true)
230+
expect(progress.accommodation).toEqual(true)
167231
})
168232

169233
it('sets the sections to incomplete when their required fields have not been completed', () => {
@@ -188,11 +252,11 @@ describe('SaveAndContinueController', () => {
188252
],
189253
})
190254

191-
controller.updateAssessmentProgress(req, res)
255+
const progress = controller.getAssessmentProgress(req.form.persistedAnswers, res.locals.form.sectionProgressRules)
192256

193-
expect(res.locals.sectionProgress?.finance).toEqual(false)
194-
expect(res.locals.sectionProgress?.['alcohol-use']).toEqual(false)
195-
expect(res.locals.sectionProgress?.['drug-use']).toEqual(false)
257+
expect(progress.finance).toEqual(false)
258+
expect(progress['alcohol-use']).toEqual(false)
259+
expect(progress['drug-use']).toEqual(false)
196260
})
197261
})
198262
})

app/controllers/saveAndContinueController.ts

+35-20
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import sectionConfig from '../form/v1_0/config/sections'
1212
import ForbiddenError from '../../server/errors/forbiddenError'
1313

1414
export type Progress = Record<string, boolean>
15+
export type SectionCompleteRule = { sectionName: string; fieldCodes: Array<string> }
1516

1617
class SaveAndContinueController extends BaseController {
1718
apiService: StrengthsBasedNeedsAssessmentsApiService
@@ -133,41 +134,41 @@ class SaveAndContinueController extends BaseController {
133134
}
134135
}
135136

136-
updateAssessmentProgress(req: FormWizard.Request, res: Response) {
137-
type SectionCompleteRule = { sectionName: string; fieldCodes: Array<string> }
138-
type AnswerValues = Record<string, string>
139-
137+
getAssessmentProgress(formAnswers: FormWizard.Answers, sectionCompleteRules: SectionCompleteRule[]): Progress {
140138
const subsectionIsComplete =
141-
(answers: AnswerValues = {}) =>
139+
(answers: FormWizard.Answers = {}) =>
142140
(fieldCode: string) =>
143141
answers[fieldCode] === 'YES'
144142
const checkProgress =
145-
(answers: AnswerValues) =>
143+
(answers: FormWizard.Answers) =>
146144
(sectionProgress: Progress, { sectionName, fieldCodes }: SectionCompleteRule): Progress => ({
147145
...sectionProgress,
148146
[sectionName]: fieldCodes.every(subsectionIsComplete(answers)),
149147
})
150148

151-
const sections = res.locals.form.sectionProgressRules
152-
const sectionProgress: Progress = sections.reduce(
153-
checkProgress(req.form.persistedAnswers as Record<string, string>),
154-
{},
155-
)
156-
res.locals.sectionProgress = sectionProgress
157-
res.locals.assessmentIsComplete = !Object.values(sectionProgress).includes(false)
149+
return sectionCompleteRules.reduce(checkProgress(formAnswers), {})
150+
}
151+
152+
checkAssessmentComplete(progress: Progress): boolean {
153+
return !Object.values(progress).includes(false)
158154
}
159155

160156
async getValues(req: FormWizard.Request, res: Response, next: NextFunction) {
161157
try {
162-
this.updateAssessmentProgress(req, res)
158+
const sectionProgress = this.getAssessmentProgress(
159+
req.form.persistedAnswers,
160+
res.locals.form.sectionProgressRules,
161+
)
162+
res.locals.sectionProgress = sectionProgress
163+
res.locals.assessmentIsComplete = this.checkAssessmentComplete(sectionProgress)
163164

164165
return super.getValues(req, res, next)
165166
} catch (error) {
166167
return next(error)
167168
}
168169
}
169170

170-
getSectionProgress(req: FormWizard.Request, isSectionComplete: boolean): FormWizard.Answers {
171+
getSectionProgressAnswers(req: FormWizard.Request, isSectionComplete: boolean): FormWizard.Answers {
171172
const sectionProgressFields: FormWizard.Answers = Object.fromEntries(
172173
req.form.options.sectionProgressRules?.map(({ fieldCode, conditionFn }) => [
173174
fieldCode,
@@ -177,7 +178,12 @@ class SaveAndContinueController extends BaseController {
177178

178179
return {
179180
...sectionProgressFields,
180-
assessment_complete: Object.values(sectionProgressFields).every(answer => answer === 'YES') ? 'YES' : 'NO',
181+
}
182+
}
183+
184+
getAssessmentCompletionAnswers(progress: Progress): FormWizard.Answers {
185+
return {
186+
assessment_complete: this.checkAssessmentComplete(progress) ? 'YES' : 'NO',
181187
}
182188
}
183189

@@ -189,16 +195,25 @@ class SaveAndContinueController extends BaseController {
189195
...req.form.values,
190196
}).getPageNavigation()
191197

192-
const allAnswers: FormWizard.Answers = {
198+
const sectionCompleteAnswers = this.getSectionProgressAnswers(req, isSectionComplete)
199+
200+
const combinedAnswers: FormWizard.Answers = {
193201
...req.form.persistedAnswers,
194202
...(req.form.values || {}),
195-
...this.getSectionProgress(req, isSectionComplete),
203+
...sectionCompleteAnswers,
204+
}
205+
206+
const answersToPersist = {
207+
...combinedAnswers,
208+
...this.getAssessmentCompletionAnswers(
209+
this.getAssessmentProgress(combinedAnswers, res.locals.form.sectionProgressRules),
210+
),
196211
}
197212

198-
const { answersToAdd, answersToRemove } = buildRequestBody(req.form.options, allAnswers, options)
213+
const { answersToAdd, answersToRemove } = buildRequestBody(req.form.options, answersToPersist, options)
199214

200215
req.form.values = {
201-
...allAnswers,
216+
...answersToPersist,
202217
...answersToRemove.reduce((removedAnswers, fieldCode) => ({ ...removedAnswers, [fieldCode]: null }), {}),
203218
}
204219
res.locals.values = req.form.values

0 commit comments

Comments
 (0)