fix request validation to accept arrays or primitives (#54331)

This commit is contained in:
Pierre Gayvallet 2020-01-10 15:48:23 +01:00 committed by GitHub
parent 919126160f
commit d8f94b1792
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 114 additions and 1 deletions

View file

@ -142,6 +142,61 @@ describe('Handler', () => {
statusCode: 400,
});
});
it('accept to receive an array payload', async () => {
const { server: innerServer, createRouter } = await server.setup(setupDeps);
const router = createRouter('/');
let body: any = null;
router.post(
{
path: '/',
validate: {
body: schema.arrayOf(schema.object({ foo: schema.string() })),
},
},
(context, req, res) => {
body = req.body;
return res.ok({ body: 'ok' });
}
);
await server.start();
await supertest(innerServer.listener)
.post('/')
.send([{ foo: 'bar' }, { foo: 'dolly' }])
.expect(200);
expect(body).toEqual([{ foo: 'bar' }, { foo: 'dolly' }]);
});
it('accept to receive a json primitive payload', async () => {
const { server: innerServer, createRouter } = await server.setup(setupDeps);
const router = createRouter('/');
let body: any = null;
router.post(
{
path: '/',
validate: {
body: schema.number(),
},
},
(context, req, res) => {
body = req.body;
return res.ok({ body: 'ok' });
}
);
await server.start();
await supertest(innerServer.listener)
.post('/')
.type('json')
.send('12')
.expect(200);
expect(body).toEqual(12);
});
});
describe('handleLegacyErrors', () => {

View file

@ -132,4 +132,62 @@ describe('Router validator', () => {
'The validation rule provided in the handler is not valid'
);
});
it('should validate and infer type when data is an array', () => {
expect(
RouteValidator.from({
body: schema.arrayOf(schema.string()),
}).getBody(['foo', 'bar'])
).toStrictEqual(['foo', 'bar']);
expect(
RouteValidator.from({
body: schema.arrayOf(schema.number()),
}).getBody([1, 2, 3])
).toStrictEqual([1, 2, 3]);
expect(
RouteValidator.from({
body: schema.arrayOf(schema.object({ foo: schema.string() })),
}).getBody([{ foo: 'bar' }, { foo: 'dolly' }])
).toStrictEqual([{ foo: 'bar' }, { foo: 'dolly' }]);
expect(() =>
RouteValidator.from({
body: schema.arrayOf(schema.number()),
}).getBody(['foo', 'bar', 'dolly'])
).toThrowError('[0]: expected value of type [number] but got [string]');
expect(() =>
RouteValidator.from({
body: schema.arrayOf(schema.number()),
}).getBody({ foo: 'bar' })
).toThrowError('expected value of type [array] but got [Object]');
});
it('should validate and infer type when data is a primitive', () => {
expect(
RouteValidator.from({
body: schema.string(),
}).getBody('foobar')
).toStrictEqual('foobar');
expect(
RouteValidator.from({
body: schema.number(),
}).getBody(42)
).toStrictEqual(42);
expect(
RouteValidator.from({
body: schema.boolean(),
}).getBody(true)
).toStrictEqual(true);
expect(() =>
RouteValidator.from({
body: schema.string(),
}).getBody({ foo: 'bar' })
).toThrowError('expected value of type [string] but got [Object]');
expect(() =>
RouteValidator.from({
body: schema.number(),
}).getBody('foobar')
).toThrowError('expected value of type [number] but got [string]');
});
});

View file

@ -274,7 +274,7 @@ export class RouteValidator<P = {}, Q = {}, B = {}> {
// if options.body.output === 'stream'
return schema.stream();
} else {
return schema.maybe(schema.nullable(schema.object({}, { allowUnknowns: true })));
return schema.maybe(schema.nullable(schema.any({})));
}
}
}