Skip to content
Permalink
Browse files

fix: joi stripUnknown.arrays=false (very important!)

Read the reasoning in the commit changelog.
  • Loading branch information...
kirillgroshkov committed Mar 10, 2019
1 parent 05601a9 commit b8747661c06728df50a3b4244556acf9e96cf1eb
@@ -1,5 +1,46 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`array items with invalid props 1`] = `
Object {
"joiValidationErrorItems": Array [
Object {
"context": Object {
"key": "a1",
"label": "a1",
"value": 5,
},
"message": "\\"a1\\" must be a string",
"path": Array [
"a",
0,
"a1",
],
"type": "string.base",
},
],
}
`;

exports[`array with invalid items 1`] = `
Object {
"joiValidationErrorItems": Array [
Object {
"context": Object {
"key": 1,
"label": 1,
"value": "",
},
"message": "\\"1\\" must be an object",
"path": Array [
"a",
1,
],
"type": "object.base",
},
],
}
`;

exports[`error should contain errorItems 1`] = `
Object {
"joiValidationErrorItems": Array [
@@ -1,12 +1,27 @@
import { stringSchema } from './joi.shared.schemas'
import { arraySchema, objectSchema, stringSchema } from './joi.shared.schemas'
import { JoiValidationError } from './joi.validation.error'
import { getValidationResult, validate, validationErrorToString } from './joi.validation.util'

const schema = {
interface Obj1 {
a1: string
a2?: string
}

const obj1Schema = objectSchema({
a1: stringSchema.min(2).max(5),
a2: stringSchema.min(2).optional(),
})

interface Obj2 {
s1?: string
a: Obj1[]
}

const obj2Schema = objectSchema({
s1: stringSchema.optional(),
a: arraySchema.items(obj1Schema),
})

const invalidValues: any[] = [
undefined,
null,
@@ -30,19 +45,19 @@ const validValues: any[] = [

test('should fail on invalid values', () => {
invalidValues.forEach(v => {
expect(() => validate(v, schema)).toThrowErrorMatchingSnapshot()
expect(() => validate(v, obj1Schema)).toThrowErrorMatchingSnapshot()
})
})

test('should pass on valid values', () => {
validValues.forEach(v => {
validate(v, schema)
validate(v, obj1Schema)
})
})

test('should trim strings by default', async () => {
const v = { a1: ' sdf ' }
const v2 = validate(v, schema)
const v2 = validate(v, obj1Schema)

expect(v2.a1).toBe('sdf')
expect(v === v2).toBeFalsy() // object should be cloned
@@ -53,7 +68,7 @@ test('should strip unknown keys', async () => {
a1: 'ff',
unk: 'ddd',
}
const v2 = validate(v, schema)
const v2 = validate(v, obj1Schema)

expect(v2).toEqual({ a1: 'ff' })
expect(v2.unk).toBeUndefined()
@@ -64,7 +79,7 @@ test('getValidationResult should still convert', async () => {
a1: ' ff ', // to be converted
a2: 'a', // invalid!
}
const vr = getValidationResult(v, schema, 'objName')
const vr = getValidationResult(v, obj1Schema, 'objName')
expect(vr.value.a1).toBe('ff')
expect(vr.error).toBeInstanceOf(JoiValidationError)
expect(vr.error).toMatchSnapshot()
@@ -84,7 +99,55 @@ test('error should contain errorItems', async () => {
a1: ' ff ', // to be converted
a2: 'a', // invalid!
}
const { error } = getValidationResult(v, schema, 'objName')
const { error } = getValidationResult(v, obj1Schema, 'objName')
expect(error!.data).toMatchSnapshot()
})

test('array items with unknown props', async () => {
const v: Obj2 = {
a: [
{
a1: 'hello',
unk: 'unk', // unknown property!
} as Obj1,
],
}

const { value, error } = getValidationResult(v, obj2Schema)
// console.log(value)
expect(error).toBeUndefined()

// Expect 'unk' to be stripped away, no validation error
expect(value).toEqual({
a: [{ a1: 'hello' }],
})
})

test('array with invalid items', async () => {
const v: Obj2 = {
a: [
{
a1: 'hello',
} as Obj1,
'' as any, // invalid value
],
}

const { error } = getValidationResult(v, obj2Schema)
// console.log(value)
expect(error!.data).toMatchSnapshot()
})

test('array items with invalid props', async () => {
const v: Obj2 = {
a: [
{
a1: 5, // invalid type
} as any,
],
}

const { error } = getValidationResult(v, obj2Schema)
expect(error!.data).toMatchSnapshot()
})

@@ -21,7 +21,13 @@ const defaultOptions: ValidationOptions = {
allowUnknown: true,
stripUnknown: {
objects: true,
arrays: true, // let's be very careful with that! https://github.com/hapijs/joi/issues/658
// true: it will SILENTLY strip invalid values from arrays. Very dangerous! Can lead to data loss!
// false: it will THROW validation error if any of array items is invalid
// Q: is it invalid if it has unknown properties?
// A: no, unknown properties are just stripped (in both 'false' and 'true' states), array is still valid
// Q: will it strip or keep unknown properties in array items?..
// A: strip
arrays: false, // let's be very careful with that! https://github.com/hapijs/joi/issues/658
},
presence: 'required',
}

0 comments on commit b874766

Please sign in to comment.
You can’t perform that action at this time.