UNPKG

9.59 kBJavaScriptView Raw
1'use strict'
2
3const t = require('tap')
4const test = t.test
5const Fastify = require('..')
6const sget = require('simple-get').concat
7const http = require('http')
8const split = require('split2')
9
10test('Should register a versioned route', t => {
11 t.plan(11)
12 const fastify = Fastify()
13
14 fastify.route({
15 method: 'GET',
16 url: '/',
17 version: '1.2.0',
18 handler: (req, reply) => {
19 reply.send({ hello: 'world' })
20 }
21 })
22
23 fastify.inject({
24 method: 'GET',
25 url: '/',
26 headers: {
27 'Accept-Version': '1.x'
28 }
29 }, (err, res) => {
30 t.error(err)
31 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
32 t.strictEqual(res.statusCode, 200)
33 })
34
35 fastify.inject({
36 method: 'GET',
37 url: '/',
38 headers: {
39 'Accept-Version': '1.2.x'
40 }
41 }, (err, res) => {
42 t.error(err)
43 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
44 t.strictEqual(res.statusCode, 200)
45 })
46
47 fastify.inject({
48 method: 'GET',
49 url: '/',
50 headers: {
51 'Accept-Version': '1.2.0'
52 }
53 }, (err, res) => {
54 t.error(err)
55 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
56 t.strictEqual(res.statusCode, 200)
57 })
58
59 fastify.inject({
60 method: 'GET',
61 url: '/',
62 headers: {
63 'Accept-Version': '1.2.1'
64 }
65 }, (err, res) => {
66 t.error(err)
67 t.strictEqual(res.statusCode, 404)
68 })
69})
70
71test('Should register the same route with different versions', t => {
72 t.plan(8)
73 const fastify = Fastify()
74
75 fastify.route({
76 method: 'GET',
77 url: '/',
78 version: '1.2.0',
79 handler: (req, reply) => {
80 reply.send('1.2.0')
81 }
82 })
83
84 fastify.route({
85 method: 'GET',
86 url: '/',
87 version: '1.3.0',
88 handler: (req, reply) => {
89 reply.send('1.3.0')
90 }
91 })
92
93 fastify.inject({
94 method: 'GET',
95 url: '/',
96 headers: {
97 'Accept-Version': '1.x'
98 }
99 }, (err, res) => {
100 t.error(err)
101 t.strictEqual(res.statusCode, 200)
102 t.strictEqual(res.payload, '1.3.0')
103 })
104
105 fastify.inject({
106 method: 'GET',
107 url: '/',
108 headers: {
109 'Accept-Version': '1.2.x'
110 }
111 }, (err, res) => {
112 t.error(err)
113 t.strictEqual(res.statusCode, 200)
114 t.strictEqual(res.payload, '1.2.0')
115 })
116
117 fastify.inject({
118 method: 'GET',
119 url: '/',
120 headers: {
121 'Accept-Version': '2.x'
122 }
123 }, (err, res) => {
124 t.error(err)
125 t.strictEqual(res.statusCode, 404)
126 })
127})
128
129test('The versioned route should take precedence', t => {
130 t.plan(3)
131 const fastify = Fastify()
132
133 fastify.route({
134 method: 'GET',
135 url: '/',
136 handler: (req, reply) => {
137 reply.send({ winter: 'is coming' })
138 }
139 })
140
141 fastify.route({
142 method: 'GET',
143 url: '/',
144 version: '1.2.0',
145 handler: (req, reply) => {
146 reply.send({ hello: 'world' })
147 }
148 })
149
150 fastify.inject({
151 method: 'GET',
152 url: '/',
153 headers: {
154 'Accept-Version': '1.x'
155 }
156 }, (err, res) => {
157 t.error(err)
158 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
159 t.strictEqual(res.statusCode, 200)
160 })
161})
162
163test('Versioned route but not version header should return a 404', t => {
164 t.plan(2)
165 const fastify = Fastify()
166
167 fastify.route({
168 method: 'GET',
169 url: '/',
170 version: '1.2.0',
171 handler: (req, reply) => {
172 reply.send({ hello: 'world' })
173 }
174 })
175
176 fastify.inject({
177 method: 'GET',
178 url: '/'
179 }, (err, res) => {
180 t.error(err)
181 t.strictEqual(res.statusCode, 404)
182 })
183})
184
185test('Should register a versioned route', t => {
186 t.plan(6)
187 const fastify = Fastify()
188
189 fastify.route({
190 method: 'GET',
191 url: '/',
192 version: '1.2.0',
193 handler: (req, reply) => {
194 reply.send({ hello: 'world' })
195 }
196 })
197
198 fastify.listen(0, err => {
199 t.error(err)
200 fastify.server.unref()
201
202 sget({
203 method: 'GET',
204 url: 'http://localhost:' + fastify.server.address().port,
205 headers: {
206 'Accept-Version': '1.x'
207 }
208 }, (err, response, body) => {
209 t.error(err)
210 t.strictEqual(response.statusCode, 200)
211 t.deepEqual(JSON.parse(body), { hello: 'world' })
212 })
213
214 sget({
215 method: 'GET',
216 url: 'http://localhost:' + fastify.server.address().port,
217 headers: {
218 'Accept-Version': '2.x'
219 }
220 }, (err, response, body) => {
221 t.error(err)
222 t.strictEqual(response.statusCode, 404)
223 })
224 })
225})
226
227test('Shorthand route declaration', t => {
228 t.plan(5)
229 const fastify = Fastify()
230
231 fastify.get('/', { version: '1.2.0' }, (req, reply) => {
232 reply.send({ hello: 'world' })
233 })
234
235 fastify.inject({
236 method: 'GET',
237 url: '/',
238 headers: {
239 'Accept-Version': '1.x'
240 }
241 }, (err, res) => {
242 t.error(err)
243 t.deepEqual(JSON.parse(res.payload), { hello: 'world' })
244 t.strictEqual(res.statusCode, 200)
245 })
246
247 fastify.inject({
248 method: 'GET',
249 url: '/',
250 headers: {
251 'Accept-Version': '1.2.1'
252 }
253 }, (err, res) => {
254 t.error(err)
255 t.strictEqual(res.statusCode, 404)
256 })
257})
258
259test('The not found handler should not use the Accept-Version header', t => {
260 t.plan(4)
261 const fastify = Fastify()
262
263 fastify.route({
264 method: 'GET',
265 url: '/',
266 version: '1.2.0',
267 handler: (req, reply) => {
268 reply.send({ hello: 'world' })
269 }
270 })
271
272 fastify.setNotFoundHandler(function (req, reply) {
273 t.notOk(req.headers['accept-version'])
274 reply.code(404).send('not found handler')
275 })
276
277 fastify.inject({
278 method: 'GET',
279 url: '/',
280 headers: {
281 'Accept-Version': '2.x'
282 }
283 }, (err, res) => {
284 t.error(err)
285 t.deepEqual(res.payload, 'not found handler')
286 t.strictEqual(res.statusCode, 404)
287 })
288})
289
290test('Bad accept version (inject)', t => {
291 t.plan(4)
292 const fastify = Fastify()
293
294 fastify.route({
295 method: 'GET',
296 url: '/',
297 version: '1.2.0',
298 handler: (req, reply) => {
299 reply.send({ hello: 'world' })
300 }
301 })
302
303 fastify.inject({
304 method: 'GET',
305 url: '/',
306 headers: {
307 'Accept-Version': 'a.b.c'
308 }
309 }, (err, res) => {
310 t.error(err)
311 t.strictEqual(res.statusCode, 404)
312 })
313
314 fastify.inject({
315 method: 'GET',
316 url: '/',
317 headers: {
318 'Accept-Version': 12
319 }
320 }, (err, res) => {
321 t.error(err)
322 t.strictEqual(res.statusCode, 404)
323 })
324})
325
326test('Bas accept version (server)', t => {
327 t.plan(5)
328 const fastify = Fastify()
329
330 fastify.route({
331 method: 'GET',
332 url: '/',
333 version: '1.2.0',
334 handler: (req, reply) => {
335 reply.send({ hello: 'world' })
336 }
337 })
338
339 fastify.listen(0, err => {
340 t.error(err)
341 fastify.server.unref()
342
343 sget({
344 method: 'GET',
345 url: 'http://localhost:' + fastify.server.address().port,
346 headers: {
347 'Accept-Version': 'a.b.c'
348 }
349 }, (err, response, body) => {
350 t.error(err)
351 t.strictEqual(response.statusCode, 404)
352 })
353
354 sget({
355 method: 'GET',
356 url: 'http://localhost:' + fastify.server.address().port,
357 headers: {
358 'Accept-Version': 12
359 }
360 }, (err, response, body) => {
361 t.error(err)
362 t.strictEqual(response.statusCode, 404)
363 })
364 })
365})
366
367test('test log stream', t => {
368 t.plan(3)
369 const stream = split(JSON.parse)
370 const fastify = Fastify({
371 logger: {
372 stream: stream,
373 level: 'info'
374 }
375 })
376
377 fastify.get('/', { version: '1.2.0' }, function (req, reply) {
378 reply.send(new Error('kaboom'))
379 })
380
381 fastify.listen(0, err => {
382 t.error(err)
383 fastify.server.unref()
384
385 http.get({
386 hostname: 'localhost',
387 port: fastify.server.address().port,
388 path: '/',
389 method: 'GET',
390 headers: {
391 'Accept-Version': '1.x'
392 }
393 })
394
395 stream.once('data', listenAtLogLine => {
396 stream.once('data', line => {
397 t.equal(line.req.version, '1.x')
398 stream.once('data', line => {
399 t.equal(line.req.version, '1.x')
400 })
401 })
402 })
403 })
404})
405
406test('Should register a versioned route with custome versioning strategy', t => {
407 t.plan(8)
408
409 const versioning = {
410 storage: function () {
411 let versions = {}
412 return {
413 get: (version) => { return versions[version] || null },
414 set: (version, store) => { versions[version] = store },
415 del: (version) => { delete versions[version] },
416 empty: () => { versions = {} }
417 }
418 },
419 deriveVersion: (req, ctx) => {
420 return req.headers.accept
421 }
422 }
423
424 const fastify = Fastify({ versioning })
425
426 fastify.route({
427 method: 'GET',
428 url: '/',
429 version: 'application/vnd.example.api+json;version=2',
430 handler: (req, reply) => {
431 reply.send({ hello: 'from route v2' })
432 }
433 })
434
435 fastify.route({
436 method: 'GET',
437 url: '/',
438 version: 'application/vnd.example.api+json;version=3',
439 handler: (req, reply) => {
440 reply.send({ hello: 'from route v3' })
441 }
442 })
443
444 fastify.inject({
445 method: 'GET',
446 url: '/',
447 headers: {
448 Accept: 'application/vnd.example.api+json;version=2'
449 }
450 }, (err, res) => {
451 t.error(err)
452 t.deepEqual(JSON.parse(res.payload), { hello: 'from route v2' })
453 t.strictEqual(res.statusCode, 200)
454 })
455
456 fastify.inject({
457 method: 'GET',
458 url: '/',
459 headers: {
460 Accept: 'application/vnd.example.api+json;version=3'
461 }
462 }, (err, res) => {
463 t.error(err)
464 t.deepEqual(JSON.parse(res.payload), { hello: 'from route v3' })
465 t.strictEqual(res.statusCode, 200)
466 })
467
468 fastify.inject({
469 method: 'GET',
470 url: '/',
471 headers: {
472 Accept: 'application/vnd.example.api+json;version=4'
473 }
474 }, (err, res) => {
475 t.error(err)
476 t.strictEqual(res.statusCode, 404)
477 })
478})