diff --git a/lib/validators.js b/lib/validators.js index 8a44f6b..71b1746 100644 --- a/lib/validators.js +++ b/lib/validators.js @@ -2,6 +2,7 @@ const Enjoi = require('enjoi'); const Joi = require('joi'); +const Yaml = require('js-yaml'); const extensions = [ { type: 'int64', base: Joi.string().regex(/^\d+$/) }, @@ -191,8 +192,21 @@ const create = function (options = {}) { if (requestBody.content[mediaType].schema) { const parameter = { in: 'body', schema: requestBody.content[mediaType].schema, name: 'body' }; const validator = makeValidator(parameter, consumes, openapi, allowUnknownProperties); - validate.payload = validator.validate; + validate.payload = (body, ctx) => { + const contentType = ctx.context.headers['content-type']; + if (consumes.includes(contentType) && contentType === 'text/x-yaml') { + try { + body = Yaml.load(body); + } + catch (err) { + // ignore parsing error + } + } + + return validator.validate(body, ctx); + }; break; + } } } diff --git a/test/fixtures/openapi3/defs/pets.yaml b/test/fixtures/openapi3/defs/pets.yaml index 1e88c02..f74b5b2 100644 --- a/test/fixtures/openapi3/defs/pets.yaml +++ b/test/fixtures/openapi3/defs/pets.yaml @@ -83,6 +83,9 @@ paths: application/json: schema: $ref: '#/components/schemas/newPet' + text/x-yaml: + schema: + $ref: '#/components/schemas/newPet' required: true responses: 200: diff --git a/test/test-hapi-openapi3.js b/test/test-hapi-openapi3.js index afa90f2..a82bc14 100644 --- a/test/test-hapi-openapi3.js +++ b/test/test-hapi-openapi3.js @@ -74,6 +74,43 @@ Test('test plugin', function (t) { } }); + t.test('validate yaml', async function (t) { + t.plan(2); + + const server = new Hapi.Server(); + + try { + await server.register({ + plugin: OpenAPI, + options: { + api: Path.join(__dirname, './fixtures/openapi3/defs/pets.yaml'), + handlers: Path.join(__dirname, './fixtures/handlers') + } + }); + let response = await server.inject({ + method: 'POST', + headers: {"content-type": "text/x-yaml"}, + url: '/v1/petstore/pets', + payload: "id: '0'\nname: 'Cat'" + }); + + t.strictEqual(response.statusCode, 200, `${response.request.path} OK.`); + + response = await server.inject({ + method: 'POST', + headers: {"content-type": "text/x-yaml"}, + url: '/v1/petstore/pets', + payload: `id: '0'\nname_does_not_exists: 'Cat'` + }); + + t.strictEqual(response.statusCode, 400, `${response.request.path} payload bad.`); + } + catch (error) { + t.fail(error.message); + } + + }); + t.test('routes with output validation', async function (t) { t.plan(5); @@ -338,4 +375,4 @@ Test('test plugin', function (t) { t.fail(error.message); } }); -}); \ No newline at end of file +});