@hmcts/one-per-page
Advanced tools
Comparing version 2.1.0-2 to 2.1.0-3
@@ -0,1 +1,14 @@ | ||
<a name="2.1.0-3"></a> | ||
# 2.1.0-3 (2018-01-12) | ||
* Ensure objectFields declare themselves as filled if their children are filled ([54b1fe1](https://github.com/hmcts/one-per-page/commit/54b1fe1)) | ||
* Increase coverage in forms package ([8d907b3](https://github.com/hmcts/one-per-page/commit/8d907b3)) | ||
* Increase coverage over AddAnother and appendToList ([362c13d](https://github.com/hmcts/one-per-page/commit/362c13d)) | ||
* Move the appendToList field in to forms package and test it ([773d9f2](https://github.com/hmcts/one-per-page/commit/773d9f2)) | ||
* Test the AddAnother step ([a090720](https://github.com/hmcts/one-per-page/commit/a090720)) | ||
* Update to latest eslint config ([97f4198](https://github.com/hmcts/one-per-page/commit/97f4198)) | ||
* Fix: new RegExp(/) will match any url ([efb795b](https://github.com/hmcts/one-per-page/commit/efb795b)) | ||
<a name="2.1.0-2"></a> | ||
@@ -2,0 +15,0 @@ # 2.1.0-2 (2018-01-09) |
{ | ||
"name": "@hmcts/one-per-page", | ||
"description": "One question per page apps made easy", | ||
"version": "2.1.0-2", | ||
"version": "2.1.0-3", | ||
"main": "./src/main.js", | ||
@@ -6,0 +6,0 @@ "dependencies": { |
@@ -224,2 +224,45 @@ const { fieldDescriptor } = require('./fieldDescriptor'); | ||
module.exports = { nonEmptyText, text, bool, list, object, ref, date, convert }; | ||
const appendToList = (collectionKey, index, field) => fieldDescriptor({ | ||
parser(name, body, req) { | ||
const fieldValue = field.parse(name, body, req); | ||
return TransformFieldValue.from({ | ||
transformation: t => t, | ||
wrapped: fieldValue | ||
}, this); | ||
}, | ||
deserializer(name, values) { | ||
const arr = option | ||
.fromNullable(values[collectionKey]) | ||
.valueOrElse([]); | ||
const extracted = arr.length > index ? { [name]: arr[index] } : {}; | ||
const fieldValue = field.deserialize(name, extracted); | ||
return TransformFieldValue.from({ | ||
transformation: t => t, | ||
wrapped: fieldValue | ||
}, this); | ||
}, | ||
serializer(fieldValue, values) { | ||
const listOfItems = list(field) | ||
.deserialize(collectionKey, values) | ||
.serializedValues(values) || []; | ||
const newItem = field.serializer(fieldValue, values); | ||
if (defined(newItem[fieldValue.name])) { | ||
if (listOfItems.length > index) { | ||
listOfItems[index] = newItem[fieldValue.name]; | ||
} else { | ||
listOfItems.push(newItem[fieldValue.name]); | ||
} | ||
} | ||
return { [collectionKey]: listOfItems }; | ||
} | ||
}); | ||
module.exports = { | ||
nonEmptyText, text, bool, list, object, ref, | ||
date, convert, appendToList | ||
}; |
@@ -49,3 +49,4 @@ const { notDefined, defined } = require('../util/checks'); | ||
validations: fieldDesc.validations, | ||
serializer: fieldDesc.serializer | ||
serializer: fieldDesc.serializer, | ||
filledCheck: fieldDesc.filledCheck | ||
})); | ||
@@ -143,2 +144,6 @@ } | ||
} | ||
get isFilled() { | ||
return Object.values(this.fields).some(field => field.isFilled); | ||
} | ||
} | ||
@@ -200,3 +205,3 @@ | ||
get isFilled() { | ||
return this.filledCheck(this.wrapped.value); | ||
return this.wrapped.isFilled; | ||
} | ||
@@ -203,0 +208,0 @@ get mappedErrors() { |
@@ -17,2 +17,3 @@ const { form } = require('./form'); | ||
list, | ||
appendToList, | ||
object, | ||
@@ -34,2 +35,3 @@ ref, | ||
list, | ||
appendToList, | ||
object, | ||
@@ -36,0 +38,0 @@ ref, |
const Question = require('./Question'); | ||
const { fieldDescriptor } = require('../forms/fieldDescriptor'); | ||
const { defined } = require('../util/checks'); | ||
const { flattenObject } = require('../util/ops'); | ||
const { TransformFieldValue } = require('../forms/fieldValue'); | ||
const { filledForm } = require('../forms/filledForm'); | ||
const { form, list } = require('../forms'); | ||
const option = require('option'); | ||
const { form, list, appendToList } = require('../forms'); | ||
const { METHOD_NOT_ALLOWED } = require('http-status-codes'); | ||
const { expectImplemented } = require('../errors/expectImplemented'); | ||
const addAnother = (collectionKey, index, field) => fieldDescriptor({ | ||
parser(name, body, req) { | ||
const fieldValue = field.parse(name, body, req); | ||
return TransformFieldValue.from({ | ||
transformation: t => t, | ||
wrapped: fieldValue | ||
}, this); | ||
}, | ||
deserializer(name, values) { | ||
const arr = option | ||
.fromNullable(values[collectionKey]) | ||
.valueOrElse([]); | ||
const extracted = arr.length > index ? { [name]: arr[index] } : {}; | ||
const fieldValue = field.deserialize(name, extracted); | ||
return TransformFieldValue.from({ | ||
transformation: t => t, | ||
wrapped: fieldValue | ||
}, this); | ||
}, | ||
serializer(fieldValue, values) { | ||
const listOfItems = list(field) | ||
.deserialize(collectionKey, values) | ||
.serializedValues(values) || []; | ||
const newItem = field.serializer(fieldValue, values); | ||
if (defined(newItem[fieldValue.name])) { | ||
if (listOfItems.length > index) { | ||
listOfItems[index] = newItem[fieldValue.name]; | ||
} else { | ||
listOfItems.push(newItem[fieldValue.name]); | ||
} | ||
} | ||
return { [collectionKey]: listOfItems }; | ||
class AddAnother extends Question { | ||
constructor(...args) { | ||
super(...args); | ||
expectImplemented(this, 'field'); | ||
} | ||
}); | ||
class AddAnother extends Question { | ||
get form() { | ||
if (this.isListMode || this.isDeleteMode) { | ||
return form({ items: this.validateList(list(this.field)) }); | ||
} else if (this.isEditMode) { | ||
return form({ item: addAnother('items', this.index, this.field) }); | ||
if (this.isEditMode) { | ||
return form({ item: appendToList('items', this.index, this.field) }); | ||
} | ||
return form(); | ||
return form({ items: this.validateList(list(this.field)) }); | ||
} | ||
validateList(items) { | ||
return items; | ||
} | ||
deleteUrl(index) { | ||
@@ -77,14 +41,12 @@ return `${this.path}/item-${index}/delete`; | ||
get mode() { | ||
if (defined(this.req.params)) { | ||
if (defined(this.req.params['0'])) { | ||
if (defined(this.req.params['1'])) { | ||
return 'delete'; | ||
} | ||
return 'edit'; | ||
if (defined(this.req.params) && defined(this.req.params['0'])) { | ||
if (defined(this.req.params['1'])) { | ||
return 'delete'; | ||
} | ||
return 'edit'; | ||
} | ||
return 'list-items'; | ||
return 'list'; | ||
} | ||
get isListMode() { | ||
return this.mode === 'list-items'; | ||
return this.mode === 'list'; | ||
} | ||
@@ -120,3 +82,3 @@ get isEditMode() { | ||
} else { | ||
throw new Error(`${this.mode} not recognised`); | ||
throw new Error(`mode: ${this.mode} not recognised`); | ||
} | ||
@@ -127,3 +89,3 @@ } | ||
this.retrieve(); | ||
if (this.fields.filled) { | ||
if (this.fields.isFilled) { | ||
this.validate(); | ||
@@ -130,0 +92,0 @@ } |
@@ -86,3 +86,3 @@ const { Router: expressRouter } = require('express'); | ||
static bind(app) { | ||
app.all(new RegExp(this.pathToBind), (req, res, next) => { | ||
app.all(this.pathToBind, (req, res, next) => { | ||
const instance = req.journey.instance(this); | ||
@@ -89,0 +89,0 @@ req.currentStep = instance; |
@@ -5,3 +5,3 @@ const { expect } = require('../util/chai'); | ||
bool, | ||
list, | ||
list, appendToList, | ||
object, | ||
@@ -12,3 +12,3 @@ ref, | ||
} = require('../../src/forms/fields'); | ||
const { isObject, isEmptyObject } = require('../../src/util/checks'); | ||
const { defined, isObject, isEmptyObject } = require('../../src/util/checks'); | ||
@@ -59,3 +59,3 @@ const readable = value => { | ||
const serializes = ({ | ||
from = {}, to, key = 'foo', only = false, req = {}, | ||
from, to, key = 'foo', only = false, req = {}, | ||
assertions = ({ serializedValue }) => { | ||
@@ -72,5 +72,13 @@ const serialized = isObject(to) ? to : { [key]: to }; | ||
mochaTest(`serializes ${toStr} from ${fromStr}${reqStr}`, () => { | ||
const values = isObject(from) ? from : { [key]: from }; | ||
const fieldValue = field.deserialize(key, values, req); | ||
const serializedValue = fieldValue.serialize(); | ||
let fieldValue = {}; | ||
if (defined(from)) { | ||
const values = isObject(from) ? from : { [key]: from }; | ||
fieldValue = field.deserialize(key, values, req); | ||
} else if (defined(req.body)) { | ||
fieldValue = field.parse(key, req.body, req); | ||
} else { | ||
throw new Error('Provide req.body to parse or from to deserialize'); | ||
} | ||
const existingValues = defined(req.session) ? req.session : {}; | ||
const serializedValue = fieldValue.serialize(existingValues); | ||
return assertions({ fieldValue, field, serializedValue }); | ||
@@ -145,3 +153,3 @@ }); | ||
it.serializes({ to: {}, from: undefined }); | ||
it.serializes({ to: {}, from: {} }); | ||
it.serializes({ to: true, from: true }); | ||
@@ -199,2 +207,33 @@ it.serializes({ to: false, from: false }); | ||
describe('appendToList([list], [index], text)', fieldTest( | ||
appendToList('items', 1, text), it => { | ||
it.parses({ to: 'foo', from: 'foo' }); | ||
it.deserializes({ | ||
value: 'target from session', | ||
from: { items: ['other', 'target from session'] } | ||
}); | ||
it.serializes({ | ||
to: { items: ['from session', 'from body'] }, | ||
req: { | ||
body: { foo: 'from body' }, | ||
session: { items: ['from session'] } | ||
} | ||
}); | ||
it.serializes({ | ||
to: { items: ['from session'] }, | ||
req: { | ||
body: {}, | ||
session: { items: ['from session'] } | ||
} | ||
}); | ||
it.serializes({ | ||
to: { items: ['from body'] }, | ||
req: { | ||
body: { foo: 'from body' }, | ||
session: {} | ||
} | ||
}); | ||
}) | ||
); | ||
const objectWithChildren = object({ a: text, b: bool }); | ||
@@ -250,3 +289,3 @@ describe('object({ a: text, b: bool })', fieldTest(objectWithChildren, it => { | ||
it.deserializes({ value: 'From another step', req }); | ||
it.serializes({ to: {}, req }); | ||
it.serializes({ to: {}, from: {}, req }); | ||
})); | ||
@@ -253,0 +292,0 @@ |
@@ -24,2 +24,7 @@ const { expect, sinon } = require('../../util/chai'); | ||
}); | ||
it('returns {} if the field.value is undefined', () => { | ||
const f = new FieldValue({ name: 'name' }); | ||
expect(f.serialize()).to.eql({}); | ||
}); | ||
}); | ||
@@ -26,0 +31,0 @@ |
Sorry, the diff of this file is not supported yet
623414
221
8421
13