Skip to content

Commit

Permalink
refactor: Extract assessment answer presentation
Browse files Browse the repository at this point in the history
This change extracts the handling of rendering assessment answers
within another component, for example, a list of panels with a tag
into another presenter.

This will allow it to be shared by other parts of the app and give the
ability to present the assessment answers in separate ways more easily.

This change does still contain a style of loading settings internally
that we would like to get rid of (see #696) as the refactor would
be a much bigger and more time consuming change at this stage.
  • Loading branch information
teneightfive committed Jul 28, 2020
1 parent 9e9850a commit db049af
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 42 deletions.
8 changes: 5 additions & 3 deletions app/move/controllers/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,14 @@ module.exports = function view(req, res) {
const urls = {
update: updateUrls,
}
const assessment = presenters
.assessmentAnswersByCategory(assessmentAnswers)
.filter(category => category.key !== 'court')
.map(presenters.assessmentCategoryToPanelComponent)

const locals = {
move,
assessment,
personEscortRecord,
personEscortRecordIsEnabled,
personEscortRecordIsComplete,
Expand All @@ -62,9 +67,6 @@ module.exports = function view(req, res) {
moveSummary: presenters.moveToMetaListComponent(move, updateActions),
personalDetailsSummary: presenters.personToSummaryListComponent(person),
tagList: presenters.assessmentToTagList(assessmentAnswers),
assessment: presenters
.assessmentAnswersByCategory(assessmentAnswers)
.map(presenters.assessmentCategoryToPanelComponent),
canCancelMove:
(userPermissions.includes('move:cancel') &&
move.status === 'requested' &&
Expand Down
46 changes: 44 additions & 2 deletions app/move/controllers/view.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ const pathStubs = {
const controller = proxyquire('./view', pathStubs)

const mockAssessmentAnswers = []
const mockAssessmentByCategory = [
{
key: 'risk',
answers: [],
},
{
key: 'health',
answers: [],
},
{
key: 'court',
answers: [],
},
]

const mockMove = {
id: 'moveId',
Expand Down Expand Up @@ -99,7 +113,7 @@ describe('Move controllers', function () {
.returns('__frameworkFlagsToTagList__')
sinon.stub(presenters, 'personToSummaryListComponent').returnsArg(0)
sinon.stub(presenters, 'assessmentToTagList').returnsArg(0)
sinon.stub(presenters, 'assessmentAnswersByCategory').returnsArg(0)
sinon.stub(presenters, 'assessmentAnswersByCategory').returns([])
sinon.stub(presenters, 'assessmentCategoryToPanelComponent').returnsArg(0)
sinon.stub(presenters, 'assessmentToSummaryListComponent').returnsArg(0)
sinon
Expand All @@ -123,6 +137,7 @@ describe('Move controllers', function () {

context('by default', function () {
beforeEach(function () {
presenters.assessmentAnswersByCategory.returns(mockAssessmentByCategory)
controller(req, res)
params = res.render.args[0][1]
})
Expand Down Expand Up @@ -231,9 +246,36 @@ describe('Move controllers', function () {
).to.be.calledOnceWithExactly(mockAssessmentAnswers)
})

it('should call assessmentCategoryToPanelComponent presenter with correct categories', function () {
expect(presenters.assessmentCategoryToPanelComponent).to.be.calledTwice
expect(presenters.assessmentCategoryToPanelComponent).to.be.calledWith(
{
answers: [],
key: 'health',
},
1
)
expect(presenters.assessmentCategoryToPanelComponent).to.be.calledWith(
{
answers: [],
key: 'risk',
},
0
)
})

it('should contain assessment param', function () {
expect(params).to.have.property('assessment')
expect(params.assessment).to.deep.equal(mockAssessmentAnswers)
expect(params.assessment).to.deep.equal([
{
answers: [],
key: 'risk',
},
{
answers: [],
key: 'health',
},
])
})

it('should call assessmentToSummaryListComponent presenter with correct args', function () {
Expand Down
7 changes: 1 addition & 6 deletions app/move/views/_includes/assessment.njk
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@
</h2>

{% for panel in assessmentCategory.panels %}
{% call appPanel(panel) %}
{{ appMetaList({
classes: "app-meta-list--divider",
items: panel.items
}) }}
{% endcall %}
{{ appPanel(panel) }}
{% else %}
{{ appMessage({
classes: "app-message--muted govuk-!-margin-top-2",
Expand Down
4 changes: 2 additions & 2 deletions common/presenters/assessment-answers-by-category.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const { sortBy, mapValues } = require('lodash')

const { TAG_CATEGORY_WHITELIST } = require('../../config')
const { ASSESSMENT_ANSWERS_SETTINGS } = require('../../config')
const { filterExpired } = require('../helpers/reference-data')

module.exports = function assessmentAnswersByCategory(assessmentAnswers = []) {
const mapped = mapValues(TAG_CATEGORY_WHITELIST, (params, category) => {
const mapped = mapValues(ASSESSMENT_ANSWERS_SETTINGS, (params, category) => {
const answers = assessmentAnswers
.filter(answer => answer.category === category)
.filter(filterExpired)
Expand Down
52 changes: 52 additions & 0 deletions common/presenters/assessment-answers-to-meta-list-component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const i18n = require('../../config/i18n')
const filters = require('../../config/nunjucks/filters')

function _mapAnswer({
comments,
created_at: createdAt,
nomis_alert_description: description,
}) {
let html = ''

if (description) {
html = `
<h4 class="govuk-!-margin-top-0 govuk-!-margin-bottom-2">
${description}
</h4>
`
}

html += comments || ''

if (description) {
html += `
<div class="app-secondary-text-colour govuk-!-margin-top-2 govuk-!-font-size-14">
${i18n.t('created_on')} ${filters.formatDateWithDay(createdAt)}
</div>
`
}

return {
value: {
html: `
<div>
${
html ||
`<span class="app-secondary-text-colour">${i18n.t(
'empty_details'
)}</span>`
}
</div>
`,
},
}
}

function assessmentAnswersToMetaListComponent(answers = []) {
return {
classes: 'app-meta-list--divider govuk-!-font-size-16',
items: answers.map(_mapAnswer),
}
}

module.exports = assessmentAnswersToMetaListComponent
37 changes: 8 additions & 29 deletions common/presenters/assessment-category-to-panel-component.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,14 @@
const { kebabCase, groupBy, mapValues, values } = require('lodash')

const i18n = require('../../config/i18n')
const filters = require('../../config/nunjucks/filters')
const componentService = require('../services/component')

function _mapAnswer(answer) {
let html = ''
const assessmentAnswersToMetaListComponent = require('./assessment-answers-to-meta-list-component')

if (answer.nomis_alert_description) {
html = `<h4 class="govuk-!-margin-top-0 govuk-!-margin-bottom-2">${answer.nomis_alert_description}</h4>`
}

html += answer.comments || ''

if (answer.created_at) {
html += `<div class="govuk-!-margin-top-2 govuk-!-font-size-16">${i18n.t(
'created_on'
)} ${filters.formatDateWithDay(answer.created_at)}</div>`
}

return {
value: {
html,
},
}
}

module.exports = function assessmentCategoryToPanelListComponent({
answers,
key,
tagClass,
}) {
function assessmentCategoryToPanelListComponent({ answers, key, tagClass }) {
const groupedByTitle = groupBy(answers, 'title')
const panels = mapValues(groupedByTitle, (answers, title) => {
const metaList = assessmentAnswersToMetaListComponent(answers)

return {
attributes: {
id: kebabCase(title),
Expand All @@ -40,7 +17,7 @@ module.exports = function assessmentCategoryToPanelListComponent({
text: title,
classes: tagClass,
},
items: answers.map(_mapAnswer),
html: componentService.getComponent('appMetaList', metaList),
}
})

Expand All @@ -49,3 +26,5 @@ module.exports = function assessmentCategoryToPanelListComponent({
panels: values(panels),
}
}

module.exports = assessmentCategoryToPanelListComponent
13 changes: 13 additions & 0 deletions config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,19 @@ module.exports = {
sortOrder: 2,
},
},
ASSESSMENT_ANSWERS_SETTINGS: {
risk: {
tagClass: 'app-tag--destructive',
sortOrder: 1,
},
health: {
tagClass: '',
sortOrder: 2,
},
court: {
sortOrder: 3,
},
},
LOCATIONS_BATCH_SIZE: process.env.LOCATIONS_BATCH_SIZE || 40,
E2E: {
BASE_URL: process.env.E2E_BASE_URL || BASE_URL,
Expand Down
1 change: 1 addition & 0 deletions locales/en/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"sort_ascending": "Sort {{label}} ascending",
"sort_descending": "Sort {{label}} descending",
"empty_response": "Nothing provided",
"empty_details": "Details not provided",
"primary_navigation": {
"home": "Home",
"outgoing": "Outgoing",
Expand Down

0 comments on commit db049af

Please sign in to comment.