You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							593 lines
						
					
					
						
							13 KiB
						
					
					
				
			
		
		
	
	
							593 lines
						
					
					
						
							13 KiB
						
					
					
				'use strict'
 | 
						|
 | 
						|
const t = require('tap')
 | 
						|
const test = t.test
 | 
						|
const Fastify = require('..')
 | 
						|
 | 
						|
test('Prefix options should add a prefix for all the routes inside a register / 1', t => {
 | 
						|
  t.plan(6)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.get('/first', (req, reply) => {
 | 
						|
    reply.send({ route: '/first' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.get('/first', (req, reply) => {
 | 
						|
      reply.send({ route: '/v1/first' })
 | 
						|
    })
 | 
						|
 | 
						|
    fastify.register(function (fastify, opts, done) {
 | 
						|
      fastify.get('/first', (req, reply) => {
 | 
						|
        reply.send({ route: '/v1/v2/first' })
 | 
						|
      })
 | 
						|
      done()
 | 
						|
    }, { prefix: '/v2' })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/v1' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/first'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { route: '/first' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/first'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { route: '/v1/first' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/v2/first'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { route: '/v1/v2/first' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Prefix options should add a prefix for all the routes inside a register / 2', t => {
 | 
						|
  t.plan(4)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.get('/first', (req, reply) => {
 | 
						|
      reply.send({ route: '/v1/first' })
 | 
						|
    })
 | 
						|
 | 
						|
    fastify.get('/second', (req, reply) => {
 | 
						|
      reply.send({ route: '/v1/second' })
 | 
						|
    })
 | 
						|
    done()
 | 
						|
  }, { prefix: '/v1' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/first'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { route: '/v1/first' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/second'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { route: '/v1/second' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Prefix options should add a prefix for all the chained routes inside a register / 3', t => {
 | 
						|
  t.plan(4)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify
 | 
						|
      .get('/first', (req, reply) => {
 | 
						|
        reply.send({ route: '/v1/first' })
 | 
						|
      })
 | 
						|
      .get('/second', (req, reply) => {
 | 
						|
        reply.send({ route: '/v1/second' })
 | 
						|
      })
 | 
						|
    done()
 | 
						|
  }, { prefix: '/v1' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/first'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { route: '/v1/first' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/second'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { route: '/v1/second' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Prefix should support parameters as well', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.get('/hello', (req, reply) => {
 | 
						|
      reply.send({ id: req.params.id })
 | 
						|
    })
 | 
						|
    done()
 | 
						|
  }, { prefix: '/v1/:id' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/param/hello'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { id: 'param' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Prefix should support /', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.get('/', (req, reply) => {
 | 
						|
      reply.send({ hello: 'world' })
 | 
						|
    })
 | 
						|
    done()
 | 
						|
  }, { prefix: '/v1' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Prefix without /', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.get('/', (req, reply) => {
 | 
						|
      reply.send({ hello: 'world' })
 | 
						|
    })
 | 
						|
    done()
 | 
						|
  }, { prefix: 'v1' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Prefix with trailing /', t => {
 | 
						|
  t.plan(6)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.get('/route1', (req, reply) => {
 | 
						|
      reply.send({ hello: 'world1' })
 | 
						|
    })
 | 
						|
    fastify.get('route2', (req, reply) => {
 | 
						|
      reply.send({ hello: 'world2' })
 | 
						|
    })
 | 
						|
 | 
						|
    fastify.register(function (fastify, opts, done) {
 | 
						|
      fastify.get('/route3', (req, reply) => {
 | 
						|
        reply.send({ hello: 'world3' })
 | 
						|
      })
 | 
						|
      done()
 | 
						|
    }, { prefix: '/inner/' })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/v1/' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/route1'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world1' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/route2'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world2' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/inner/route3'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world3' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Prefix works multiple levels deep', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.register(function (fastify, opts, done) {
 | 
						|
      fastify.register(function (fastify, opts, done) {
 | 
						|
        fastify.register(function (fastify, opts, done) {
 | 
						|
          fastify.get('/', (req, reply) => {
 | 
						|
            reply.send({ hello: 'world' })
 | 
						|
          })
 | 
						|
          done()
 | 
						|
        }, { prefix: '/v3' })
 | 
						|
        done()
 | 
						|
      }) // No prefix on this level
 | 
						|
      done()
 | 
						|
    }, { prefix: 'v2' })
 | 
						|
    done()
 | 
						|
  }, { prefix: '/v1' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/v2/v3'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Different register - encapsulation check', t => {
 | 
						|
  t.plan(4)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.get('/first', (req, reply) => {
 | 
						|
    reply.send({ route: '/first' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.register(function (instance, opts, done) {
 | 
						|
    instance.register(function (f, opts, done) {
 | 
						|
      f.get('/', (req, reply) => {
 | 
						|
        reply.send({ route: '/v1/v2' })
 | 
						|
      })
 | 
						|
      done()
 | 
						|
    }, { prefix: '/v2' })
 | 
						|
    done()
 | 
						|
  }, { prefix: '/v1' })
 | 
						|
 | 
						|
  fastify.register(function (instance, opts, done) {
 | 
						|
    instance.register(function (f, opts, done) {
 | 
						|
      f.get('/', (req, reply) => {
 | 
						|
        reply.send({ route: '/v3/v4' })
 | 
						|
      })
 | 
						|
      done()
 | 
						|
    }, { prefix: '/v4' })
 | 
						|
    done()
 | 
						|
  }, { prefix: '/v3' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/v2'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { route: '/v1/v2' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v3/v4'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { route: '/v3/v4' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('Can retrieve prefix within encapsulated instances', t => {
 | 
						|
  t.plan(4)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function (instance, opts, done) {
 | 
						|
    instance.get('/one', function (req, reply) {
 | 
						|
      reply.send(instance.prefix)
 | 
						|
    })
 | 
						|
 | 
						|
    instance.register(function (instance, opts, done) {
 | 
						|
      instance.get('/two', function (req, reply) {
 | 
						|
        reply.send(instance.prefix)
 | 
						|
      })
 | 
						|
      done()
 | 
						|
    }, { prefix: '/v2' })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/v1' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/one'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.equal(res.payload, '/v1')
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/v1/v2/two'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.equal(res.payload, '/v1/v2')
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('matches both /prefix and /prefix/ with a / route', t => {
 | 
						|
  t.plan(4)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.get('/', (req, reply) => {
 | 
						|
      reply.send({ hello: 'world' })
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/prefix' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix/'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('prefix "/prefix/" does not match "/prefix" with a / route', t => {
 | 
						|
  t.plan(4)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.get('/', (req, reply) => {
 | 
						|
      reply.send({ hello: 'world' })
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/prefix/' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.equal(res.statusCode, 404)
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix/'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('matches both /prefix and /prefix/ with a / route - ignoreTrailingSlash: true', t => {
 | 
						|
  t.plan(4)
 | 
						|
  const fastify = Fastify({
 | 
						|
    ignoreTrailingSlash: true
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.get('/', (req, reply) => {
 | 
						|
      reply.send({ hello: 'world' })
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/prefix' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix/'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('matches both /prefix and /prefix/  with a / route - prefixTrailingSlash: "both", ignoreTrailingSlash: false', t => {
 | 
						|
  t.plan(4)
 | 
						|
  const fastify = Fastify({
 | 
						|
    ignoreTrailingSlash: false
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.route({
 | 
						|
      method: 'GET',
 | 
						|
      url: '/',
 | 
						|
      prefixTrailingSlash: 'both',
 | 
						|
      handler: (req, reply) => {
 | 
						|
        reply.send({ hello: 'world' })
 | 
						|
      }
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/prefix' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix/'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('returns 404 status code with /prefix/ and / route - prefixTrailingSlash: "both" (default), ignoreTrailingSlash: true', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify({
 | 
						|
    ignoreTrailingSlash: true
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.route({
 | 
						|
      method: 'GET',
 | 
						|
      url: '/',
 | 
						|
      handler: (req, reply) => {
 | 
						|
        reply.send({ hello: 'world' })
 | 
						|
      }
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/prefix/' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix//'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), {
 | 
						|
      error: 'Not Found',
 | 
						|
      message: 'Route GET:/prefix// not found',
 | 
						|
      statusCode: 404
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('matches only /prefix  with a / route - prefixTrailingSlash: "no-slash", ignoreTrailingSlash: false', t => {
 | 
						|
  t.plan(4)
 | 
						|
  const fastify = Fastify({
 | 
						|
    ignoreTrailingSlash: false
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.route({
 | 
						|
      method: 'GET',
 | 
						|
      url: '/',
 | 
						|
      prefixTrailingSlash: 'no-slash',
 | 
						|
      handler: (req, reply) => {
 | 
						|
        reply.send({ hello: 'world' })
 | 
						|
      }
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/prefix' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix/'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.equal(JSON.parse(res.payload).statusCode, 404)
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('matches only /prefix/  with a / route - prefixTrailingSlash: "slash", ignoreTrailingSlash: false', t => {
 | 
						|
  t.plan(4)
 | 
						|
  const fastify = Fastify({
 | 
						|
    ignoreTrailingSlash: false
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.route({
 | 
						|
      method: 'GET',
 | 
						|
      url: '/',
 | 
						|
      prefixTrailingSlash: 'slash',
 | 
						|
      handler: (req, reply) => {
 | 
						|
        reply.send({ hello: 'world' })
 | 
						|
      }
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/prefix' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix/'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.same(JSON.parse(res.payload), { hello: 'world' })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/prefix'
 | 
						|
  }, (err, res) => {
 | 
						|
    t.error(err)
 | 
						|
    t.equal(JSON.parse(res.payload).statusCode, 404)
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('calls onRoute only once when prefixing', async t => {
 | 
						|
  t.plan(1)
 | 
						|
  const fastify = Fastify({
 | 
						|
    ignoreTrailingSlash: false
 | 
						|
  })
 | 
						|
 | 
						|
  let onRouteCalled = 0
 | 
						|
  fastify.register(function (fastify, opts, next) {
 | 
						|
    fastify.addHook('onRoute', () => {
 | 
						|
      onRouteCalled++
 | 
						|
    })
 | 
						|
 | 
						|
    fastify.route({
 | 
						|
      method: 'GET',
 | 
						|
      url: '/',
 | 
						|
      prefixTrailingSlash: 'both',
 | 
						|
      handler: (req, reply) => {
 | 
						|
        reply.send({ hello: 'world' })
 | 
						|
      }
 | 
						|
    })
 | 
						|
 | 
						|
    next()
 | 
						|
  }, { prefix: '/prefix' })
 | 
						|
 | 
						|
  await fastify.ready()
 | 
						|
 | 
						|
  t.same(onRouteCalled, 1)
 | 
						|
})
 |