UNPKG

8.63 kBJavaScriptView Raw
1'use strict'
2
3const sget = require('simple-get').concat
4const Ajv = require('ajv')
5const Joi = require('joi')
6const yup = require('yup')
7
8module.exports.payloadMethod = function (method, t) {
9 const test = t.test
10 const fastify = require('..')()
11 const upMethod = method.toUpperCase()
12 const loMethod = method.toLowerCase()
13
14 const opts = {
15 schema: {
16 body: {
17 type: 'object',
18 properties: {
19 hello: {
20 type: 'integer'
21 }
22 }
23 }
24 }
25 }
26
27 const ajv = new Ajv({ coerceTypes: true, removeAdditional: true })
28 const optsWithCustomValidator = {
29 schema: {
30 body: {
31 type: 'object',
32 properties: {
33 hello: {
34 type: 'integer'
35 }
36 },
37 additionalProperties: false
38 }
39 },
40 schemaCompiler: function (schema) {
41 return ajv.compile(schema)
42 }
43 }
44
45 const optsWithJoiValidator = {
46 schema: {
47 body: Joi.object().keys({
48 hello: Joi.string().required()
49 }).required()
50 },
51 schemaCompiler: function (schema) {
52 return schema.validate.bind(schema)
53 }
54 }
55
56 const yupOptions = {
57 strict: true, // don't coerce
58 abortEarly: false, // return all errors
59 stripUnknown: true, // remove additional properties
60 recursive: true
61 }
62
63 const optsWithYupValidator = {
64 schema: {
65 body: yup.object().shape({
66 hello: yup.string().required()
67 }).required()
68 },
69 schemaCompiler: schema => data => {
70 try {
71 const result = schema.validateSync(data, yupOptions)
72 return { value: result }
73 } catch (e) {
74 return { error: e }
75 }
76 }
77 }
78
79 test(`${upMethod} can be created`, t => {
80 t.plan(1)
81 try {
82 fastify[loMethod]('/', opts, function (req, reply) {
83 reply.send(req.body)
84 })
85 fastify[loMethod]('/custom', optsWithCustomValidator, function (req, reply) {
86 reply.send(req.body)
87 })
88 fastify[loMethod]('/joi', optsWithJoiValidator, function (req, reply) {
89 reply.send(req.body)
90 })
91 fastify[loMethod]('/yup', optsWithYupValidator, function (req, reply) {
92 reply.send(req.body)
93 })
94
95 fastify.register(function (fastify2, opts, next) {
96 fastify2.setSchemaCompiler(function schema (schema) {
97 return body => ({ error: new Error('From custom schema compiler!') })
98 })
99 const withInstanceCustomCompiler = {
100 schema: {
101 body: {
102 type: 'object',
103 properties: { },
104 additionalProperties: false
105 }
106 }
107 }
108 fastify2[loMethod]('/plugin', withInstanceCustomCompiler, (req, reply) => reply.send({ hello: 'never here!' }))
109
110 const optsWithCustomValidator2 = {
111 schema: {
112 body: {
113 type: 'object',
114 properties: { },
115 additionalProperties: false
116 }
117 },
118 schemaCompiler: function (schema) {
119 return function (body) {
120 return { error: new Error('Always fail!') }
121 }
122 }
123 }
124 fastify2[loMethod]('/plugin/custom', optsWithCustomValidator2, (req, reply) => reply.send({ hello: 'never here!' }))
125
126 next()
127 })
128 t.pass()
129 } catch (e) {
130 t.fail()
131 }
132 })
133
134 fastify.listen(0, function (err) {
135 if (err) {
136 t.error(err)
137 }
138
139 fastify.server.unref()
140
141 test(`${upMethod} - correctly replies`, t => {
142 if (upMethod === 'HEAD') {
143 t.plan(2)
144 sget({
145 method: upMethod,
146 url: 'http://localhost:' + fastify.server.address().port
147 }, (err, response) => {
148 t.error(err)
149 t.strictEqual(response.statusCode, 200)
150 })
151 } else {
152 t.plan(3)
153 sget({
154 method: upMethod,
155 url: 'http://localhost:' + fastify.server.address().port,
156 body: {
157 hello: 42
158 },
159 json: true
160 }, (err, response, body) => {
161 t.error(err)
162 t.strictEqual(response.statusCode, 200)
163 t.deepEqual(body, { hello: 42 })
164 })
165 }
166 })
167
168 test(`${upMethod} - 400 on bad parameters`, t => {
169 t.plan(3)
170 sget({
171 method: upMethod,
172 url: 'http://localhost:' + fastify.server.address().port,
173 body: {
174 hello: 'world'
175 },
176 json: true
177 }, (err, response, body) => {
178 t.error(err)
179 t.strictEqual(response.statusCode, 400)
180 t.deepEqual(body, {
181 error: 'Bad Request',
182 message: 'body.hello should be integer',
183 statusCode: 400
184 })
185 })
186 })
187
188 test(`${upMethod} - input-validation coerce`, t => {
189 t.plan(3)
190 sget({
191 method: upMethod,
192 url: 'http://localhost:' + fastify.server.address().port,
193 body: {
194 hello: '42'
195 },
196 json: true
197 }, (err, response, body) => {
198 t.error(err)
199 t.strictEqual(response.statusCode, 200)
200 t.deepEqual(body, { hello: 42 })
201 })
202 })
203
204 test(`${upMethod} - input-validation custom schema compiler`, t => {
205 t.plan(3)
206 sget({
207 method: upMethod,
208 url: 'http://localhost:' + fastify.server.address().port + '/custom',
209 body: {
210 hello: '42',
211 world: 55
212 },
213 json: true
214 }, (err, response, body) => {
215 t.error(err)
216 t.strictEqual(response.statusCode, 200)
217 t.deepEqual(body, { hello: 42 })
218 })
219 })
220
221 test(`${upMethod} - input-validation joi schema compiler ok`, t => {
222 t.plan(3)
223 sget({
224 method: upMethod,
225 url: 'http://localhost:' + fastify.server.address().port + '/joi',
226 body: {
227 hello: '42'
228 },
229 json: true
230 }, (err, response, body) => {
231 t.error(err)
232 t.strictEqual(response.statusCode, 200)
233 t.deepEqual(body, { hello: 42 })
234 })
235 })
236
237 test(`${upMethod} - input-validation joi schema compiler ko`, t => {
238 t.plan(3)
239 sget({
240 method: upMethod,
241 url: 'http://localhost:' + fastify.server.address().port + '/joi',
242 body: {
243 hello: 44
244 },
245 json: true
246 }, (err, response, body) => {
247 t.error(err)
248 t.strictEqual(response.statusCode, 400)
249 t.deepEqual(body, {
250 error: 'Bad Request',
251 message: 'child "hello" fails because ["hello" must be a string]',
252 statusCode: 400
253 })
254 })
255 })
256
257 test(`${upMethod} - input-validation yup schema compiler ok`, t => {
258 t.plan(3)
259 sget({
260 method: upMethod,
261 url: 'http://localhost:' + fastify.server.address().port + '/yup',
262 body: {
263 hello: '42'
264 },
265 json: true
266 }, (err, response, body) => {
267 t.error(err)
268 t.strictEqual(response.statusCode, 200)
269 t.deepEqual(body, { hello: 42 })
270 })
271 })
272
273 test(`${upMethod} - input-validation yup schema compiler ko`, t => {
274 t.plan(3)
275 sget({
276 method: upMethod,
277 url: 'http://localhost:' + fastify.server.address().port + '/yup',
278 body: {
279 hello: 44
280 },
281 json: true
282 }, (err, response, body) => {
283 t.error(err)
284 t.strictEqual(response.statusCode, 400)
285 t.deepEqual(body, {
286 error: 'Bad Request',
287 message: 'hello must be a `string` type, but the final value was: `44`.',
288 statusCode: 400
289 })
290 })
291 })
292
293 test(`${upMethod} - input-validation instance custom schema compiler encapsulated`, t => {
294 t.plan(3)
295 sget({
296 method: upMethod,
297 url: 'http://localhost:' + fastify.server.address().port + '/plugin',
298 body: { },
299 json: true
300 }, (err, response, body) => {
301 t.error(err)
302 t.strictEqual(response.statusCode, 400)
303 t.deepEqual(body, {
304 error: 'Bad Request',
305 message: 'From custom schema compiler!',
306 statusCode: '400'
307 })
308 })
309 })
310
311 test(`${upMethod} - input-validation custom schema compiler encapsulated`, t => {
312 t.plan(3)
313 sget({
314 method: upMethod,
315 url: 'http://localhost:' + fastify.server.address().port + '/plugin/custom',
316 body: { },
317 json: true
318 }, (err, response, body) => {
319 t.error(err)
320 t.strictEqual(response.statusCode, 400)
321 t.deepEqual(body, {
322 error: 'Bad Request',
323 message: 'Always fail!',
324 statusCode: '400'
325 })
326 })
327 })
328 })
329}