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.
		
		
		
		
		
			
		
			
				
					
					
						
							1005 lines
						
					
					
						
							22 KiB
						
					
					
				
			
		
		
	
	
							1005 lines
						
					
					
						
							22 KiB
						
					
					
				'use strict'
 | 
						|
 | 
						|
/* eslint no-prototype-builtins: 0 */
 | 
						|
 | 
						|
const t = require('tap')
 | 
						|
const test = t.test
 | 
						|
const Fastify = require('..')
 | 
						|
const sget = require('simple-get').concat
 | 
						|
const fp = require('fastify-plugin')
 | 
						|
const fakeTimer = require('@sinonjs/fake-timers')
 | 
						|
 | 
						|
test('require a plugin', t => {
 | 
						|
  t.plan(1)
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(require('./plugin.helper'))
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.ok(fastify.test)
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - ignore prefix', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  plugin[Symbol.for('skip-override')] = true
 | 
						|
  fastify.register(plugin, { prefix: 'foo' })
 | 
						|
 | 
						|
  fastify.inject({
 | 
						|
    method: 'GET',
 | 
						|
    url: '/'
 | 
						|
  }, function (err, res) {
 | 
						|
    t.error(err)
 | 
						|
    t.equal(res.payload, 'hello')
 | 
						|
  })
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    instance.get('/', function (request, reply) {
 | 
						|
      reply.send('hello')
 | 
						|
    })
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - naming plugins', async t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(require('./plugin.name.display'))
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    // one line
 | 
						|
    t.equal(fastify.pluginName, 'function (fastify, opts, done) { -- // one line')
 | 
						|
    done()
 | 
						|
  })
 | 
						|
  fastify.register(function fooBar (fastify, opts, done) {
 | 
						|
    t.equal(fastify.pluginName, 'fooBar')
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  await fastify.ready()
 | 
						|
})
 | 
						|
 | 
						|
test('fastify.register with fastify-plugin should not encapsulate his code', t => {
 | 
						|
  t.plan(10)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register((instance, opts, done) => {
 | 
						|
    instance.register(fp((i, o, n) => {
 | 
						|
      i.decorate('test', () => {})
 | 
						|
      t.ok(i.test)
 | 
						|
      n()
 | 
						|
    }))
 | 
						|
 | 
						|
    t.notOk(instance.test)
 | 
						|
 | 
						|
    // the decoration is added at the end
 | 
						|
    instance.after(() => {
 | 
						|
      t.ok(instance.test)
 | 
						|
    })
 | 
						|
 | 
						|
    instance.get('/', (req, reply) => {
 | 
						|
      t.ok(instance.test)
 | 
						|
      reply.send({ hello: 'world' })
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.notOk(fastify.test)
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.server.unref()
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.equal(response.statusCode, 200)
 | 
						|
      t.equal(response.headers['content-length'], '' + body.length)
 | 
						|
      t.same(JSON.parse(body), { hello: 'world' })
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('fastify.register with fastify-plugin should provide access to external fastify instance if opts argument is a function', t => {
 | 
						|
  t.plan(22)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register((instance, opts, done) => {
 | 
						|
    instance.register(fp((i, o, n) => {
 | 
						|
      i.decorate('global', () => {})
 | 
						|
      t.ok(i.global)
 | 
						|
      n()
 | 
						|
    }))
 | 
						|
 | 
						|
    instance.register((i, o, n) => n(), p => {
 | 
						|
      t.notOk(p === instance || p === fastify)
 | 
						|
      t.ok(instance.isPrototypeOf(p))
 | 
						|
      t.ok(fastify.isPrototypeOf(p))
 | 
						|
      t.ok(p.global)
 | 
						|
    })
 | 
						|
 | 
						|
    instance.register((i, o, n) => {
 | 
						|
      i.decorate('local', () => {})
 | 
						|
      n()
 | 
						|
    })
 | 
						|
 | 
						|
    instance.register((i, o, n) => n(), p => t.notOk(p.local))
 | 
						|
 | 
						|
    instance.register((i, o, n) => {
 | 
						|
      t.ok(i.local)
 | 
						|
      n()
 | 
						|
    }, p => p.decorate('local', () => {}))
 | 
						|
 | 
						|
    instance.register((i, o, n) => n(), p => t.notOk(p.local))
 | 
						|
 | 
						|
    instance.register(fp((i, o, n) => {
 | 
						|
      t.ok(i.global_2)
 | 
						|
      n()
 | 
						|
    }), p => p.decorate('global_2', () => 'hello'))
 | 
						|
 | 
						|
    instance.register((i, o, n) => {
 | 
						|
      i.decorate('global_2', () => 'world')
 | 
						|
      n()
 | 
						|
    }, p => p.get('/', (req, reply) => {
 | 
						|
      t.ok(p.global_2)
 | 
						|
      reply.send({ hello: p.global_2() })
 | 
						|
    }))
 | 
						|
 | 
						|
    t.notOk(instance.global)
 | 
						|
    t.notOk(instance.global_2)
 | 
						|
    t.notOk(instance.local)
 | 
						|
 | 
						|
    // the decoration is added at the end
 | 
						|
    instance.after(() => {
 | 
						|
      t.ok(instance.global)
 | 
						|
      t.equal(instance.global_2(), 'hello')
 | 
						|
      t.notOk(instance.local)
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.notOk(fastify.global)
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.server.unref()
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.equal(response.statusCode, 200)
 | 
						|
      t.equal(response.headers['content-length'], '' + body.length)
 | 
						|
      t.same(JSON.parse(body), { hello: 'world' })
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('fastify.register with fastify-plugin registers root level plugins', t => {
 | 
						|
  t.plan(15)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  function rootPlugin (instance, opts, done) {
 | 
						|
    instance.decorate('test', 'first')
 | 
						|
    t.ok(instance.test)
 | 
						|
    done()
 | 
						|
  }
 | 
						|
 | 
						|
  function innerPlugin (instance, opts, done) {
 | 
						|
    instance.decorate('test2', 'second')
 | 
						|
    done()
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(fp(rootPlugin))
 | 
						|
 | 
						|
  fastify.register((instance, opts, done) => {
 | 
						|
    t.ok(instance.test)
 | 
						|
    instance.register(fp(innerPlugin))
 | 
						|
 | 
						|
    instance.get('/test2', (req, reply) => {
 | 
						|
      t.ok(instance.test2)
 | 
						|
      reply.send({ test2: instance.test2 })
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.ok(fastify.test)
 | 
						|
    t.notOk(fastify.test2)
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.get('/', (req, reply) => {
 | 
						|
    t.ok(fastify.test)
 | 
						|
    reply.send({ test: fastify.test })
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.server.unref()
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.equal(response.statusCode, 200)
 | 
						|
      t.equal(response.headers['content-length'], '' + body.length)
 | 
						|
      t.same(JSON.parse(body), { test: 'first' })
 | 
						|
    })
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port + '/test2'
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.equal(response.statusCode, 200)
 | 
						|
      t.equal(response.headers['content-length'], '' + body.length)
 | 
						|
      t.same(JSON.parse(body), { test2: 'second' })
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('check dependencies - should not throw', t => {
 | 
						|
  t.plan(12)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register((instance, opts, done) => {
 | 
						|
    instance.register(fp((i, o, n) => {
 | 
						|
      i.decorate('test', () => {})
 | 
						|
      t.ok(i.test)
 | 
						|
      n()
 | 
						|
    }))
 | 
						|
 | 
						|
    instance.register(fp((i, o, n) => {
 | 
						|
      try {
 | 
						|
        i.decorate('otherTest', () => {}, ['test'])
 | 
						|
        t.ok(i.test)
 | 
						|
        t.ok(i.otherTest)
 | 
						|
        n()
 | 
						|
      } catch (e) {
 | 
						|
        t.fail()
 | 
						|
      }
 | 
						|
    }))
 | 
						|
 | 
						|
    instance.get('/', (req, reply) => {
 | 
						|
      t.ok(instance.test)
 | 
						|
      t.ok(instance.otherTest)
 | 
						|
      reply.send({ hello: 'world' })
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.notOk(fastify.test)
 | 
						|
    t.notOk(fastify.otherTest)
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.server.unref()
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.equal(response.statusCode, 200)
 | 
						|
      t.equal(response.headers['content-length'], '' + body.length)
 | 
						|
      t.same(JSON.parse(body), { hello: 'world' })
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('check dependencies - should throw', t => {
 | 
						|
  t.plan(12)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register((instance, opts, done) => {
 | 
						|
    instance.register(fp((i, o, n) => {
 | 
						|
      try {
 | 
						|
        i.decorate('otherTest', () => {}, ['test'])
 | 
						|
        t.fail()
 | 
						|
      } catch (e) {
 | 
						|
        t.equal(e.code, 'FST_ERR_DEC_MISSING_DEPENDENCY')
 | 
						|
        t.equal(e.message, 'The decorator is missing dependency \'test\'.')
 | 
						|
      }
 | 
						|
      n()
 | 
						|
    }))
 | 
						|
 | 
						|
    instance.register(fp((i, o, n) => {
 | 
						|
      i.decorate('test', () => {})
 | 
						|
      t.ok(i.test)
 | 
						|
      t.notOk(i.otherTest)
 | 
						|
      n()
 | 
						|
    }))
 | 
						|
 | 
						|
    instance.get('/', (req, reply) => {
 | 
						|
      t.ok(instance.test)
 | 
						|
      t.notOk(instance.otherTest)
 | 
						|
      reply.send({ hello: 'world' })
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.notOk(fastify.test)
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.server.unref()
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.equal(response.statusCode, 200)
 | 
						|
      t.equal(response.headers['content-length'], '' + body.length)
 | 
						|
      t.same(JSON.parse(body), { hello: 'world' })
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('set the plugin name based on the plugin displayName symbol', t => {
 | 
						|
  t.plan(5)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(fp((fastify, opts, done) => {
 | 
						|
    t.equal(fastify.pluginName, 'plugin-A')
 | 
						|
    fastify.register(fp((fastify, opts, done) => {
 | 
						|
      t.equal(fastify.pluginName, 'plugin-A -> plugin-AB')
 | 
						|
      done()
 | 
						|
    }, { name: 'plugin-AB' }))
 | 
						|
    fastify.register(fp((fastify, opts, done) => {
 | 
						|
      t.equal(fastify.pluginName, 'plugin-A -> plugin-AB -> plugin-AC')
 | 
						|
      done()
 | 
						|
    }, { name: 'plugin-AC' }))
 | 
						|
    done()
 | 
						|
  }, { name: 'plugin-A' }))
 | 
						|
 | 
						|
  fastify.register(fp((fastify, opts, done) => {
 | 
						|
    t.equal(fastify.pluginName, 'plugin-A -> plugin-AB -> plugin-AC -> plugin-B')
 | 
						|
    done()
 | 
						|
  }, { name: 'plugin-B' }))
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.close()
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('plugin name will change when using no encapsulation', t => {
 | 
						|
  t.plan(5)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(fp((fastify, opts, done) => {
 | 
						|
    // store it in a different variable will hold the correct name
 | 
						|
    const pluginName = fastify.pluginName
 | 
						|
    fastify.register(fp((fastify, opts, done) => {
 | 
						|
      t.equal(fastify.pluginName, 'plugin-A -> plugin-AB')
 | 
						|
      done()
 | 
						|
    }, { name: 'plugin-AB' }))
 | 
						|
    fastify.register(fp((fastify, opts, done) => {
 | 
						|
      t.equal(fastify.pluginName, 'plugin-A -> plugin-AB -> plugin-AC')
 | 
						|
      done()
 | 
						|
    }, { name: 'plugin-AC' }))
 | 
						|
    setImmediate(() => {
 | 
						|
      // normally we would expect the name plugin-A
 | 
						|
      // but we operate on the same instance in each plugin
 | 
						|
      t.equal(fastify.pluginName, 'plugin-A -> plugin-AB -> plugin-AC')
 | 
						|
      t.equal(pluginName, 'plugin-A')
 | 
						|
    })
 | 
						|
    done()
 | 
						|
  }, { name: 'plugin-A' }))
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.close()
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('plugin name is undefined when accessing in no plugin context', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  t.equal(fastify.pluginName, undefined)
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.close()
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('set the plugin name based on the plugin function name', t => {
 | 
						|
  t.plan(5)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(function myPluginA (fastify, opts, done) {
 | 
						|
    t.equal(fastify.pluginName, 'myPluginA')
 | 
						|
    fastify.register(function myPluginAB (fastify, opts, done) {
 | 
						|
      t.equal(fastify.pluginName, 'myPluginAB')
 | 
						|
      done()
 | 
						|
    })
 | 
						|
    setImmediate(() => {
 | 
						|
      // exact name due to encapsulation
 | 
						|
      t.equal(fastify.pluginName, 'myPluginA')
 | 
						|
    })
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.register(function myPluginB (fastify, opts, done) {
 | 
						|
    t.equal(fastify.pluginName, 'myPluginB')
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.close()
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('approximate a plugin name when no meta data is available', t => {
 | 
						|
  t.plan(7)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register((fastify, opts, done) => {
 | 
						|
    // A
 | 
						|
    t.equal(fastify.pluginName.startsWith('(fastify, opts, done)'), true)
 | 
						|
    t.equal(fastify.pluginName.includes('// A'), true)
 | 
						|
    fastify.register((fastify, opts, done) => {
 | 
						|
      // B
 | 
						|
      t.equal(fastify.pluginName.startsWith('(fastify, opts, done)'), true)
 | 
						|
      t.equal(fastify.pluginName.includes('// B'), true)
 | 
						|
      done()
 | 
						|
    })
 | 
						|
    setImmediate(() => {
 | 
						|
      t.equal(fastify.pluginName.startsWith('(fastify, opts, done)'), true)
 | 
						|
      t.equal(fastify.pluginName.includes('// A'), true)
 | 
						|
    })
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.close()
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('approximate a plugin name also when fastify-plugin has no meta data', t => {
 | 
						|
  t.plan(4)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register(fp((fastify, opts, done) => {
 | 
						|
    t.match(fastify.pluginName, /plugin\.test/)
 | 
						|
    fastify.register(fp(function B (fastify, opts, done) {
 | 
						|
      // function has name
 | 
						|
      t.match(fastify.pluginName, /plugin\.test-auto-\d+ -> B/)
 | 
						|
      done()
 | 
						|
    }))
 | 
						|
    setImmediate(() => {
 | 
						|
      t.match(fastify.pluginName, /plugin\.test-auto-\d+ -> B/)
 | 
						|
    })
 | 
						|
    done()
 | 
						|
  }))
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.close()
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('plugin encapsulation', t => {
 | 
						|
  t.plan(10)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register((instance, opts, done) => {
 | 
						|
    instance.register(fp((i, o, n) => {
 | 
						|
      i.decorate('test', 'first')
 | 
						|
      n()
 | 
						|
    }))
 | 
						|
 | 
						|
    instance.get('/first', (req, reply) => {
 | 
						|
      reply.send({ plugin: instance.test })
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.register((instance, opts, done) => {
 | 
						|
    instance.register(fp((i, o, n) => {
 | 
						|
      i.decorate('test', 'second')
 | 
						|
      n()
 | 
						|
    }))
 | 
						|
 | 
						|
    instance.get('/second', (req, reply) => {
 | 
						|
      reply.send({ plugin: instance.test })
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.notOk(fastify.test)
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
    fastify.server.unref()
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port + '/first'
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.equal(response.statusCode, 200)
 | 
						|
      t.equal(response.headers['content-length'], '' + body.length)
 | 
						|
      t.same(JSON.parse(body), { plugin: 'first' })
 | 
						|
    })
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port + '/second'
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.equal(response.statusCode, 200)
 | 
						|
      t.equal(response.headers['content-length'], '' + body.length)
 | 
						|
      t.same(JSON.parse(body), { plugin: 'second' })
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('if a plugin raises an error and there is not a callback to handle it, the server must not start', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.register((instance, opts, done) => {
 | 
						|
    done(new Error('err'))
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.ok(err instanceof Error)
 | 
						|
    t.equal(err.message, 'err')
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('add hooks after route declaration', t => {
 | 
						|
  t.plan(3)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    instance.decorateRequest('check', null)
 | 
						|
    instance.addHook('onRequest', (req, reply, done) => {
 | 
						|
      req.check = {}
 | 
						|
      done()
 | 
						|
    })
 | 
						|
    setImmediate(done)
 | 
						|
  }
 | 
						|
  fastify.register(fp(plugin))
 | 
						|
 | 
						|
  fastify.register((instance, options, done) => {
 | 
						|
    instance.addHook('preHandler', function b (req, res, done) {
 | 
						|
      req.check.hook2 = true
 | 
						|
      done()
 | 
						|
    })
 | 
						|
 | 
						|
    instance.get('/', (req, reply) => {
 | 
						|
      reply.send(req.check)
 | 
						|
    })
 | 
						|
 | 
						|
    instance.addHook('preHandler', function c (req, res, done) {
 | 
						|
      req.check.hook3 = true
 | 
						|
      done()
 | 
						|
    })
 | 
						|
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.addHook('preHandler', function a (req, res, done) {
 | 
						|
    req.check.hook1 = true
 | 
						|
    done()
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.same(JSON.parse(body), { hook1: true, hook2: true, hook3: true })
 | 
						|
      fastify.close()
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('nested plugins', t => {
 | 
						|
  t.plan(5)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  t.teardown(fastify.close.bind(fastify))
 | 
						|
 | 
						|
  fastify.register(function (fastify, opts, done) {
 | 
						|
    fastify.register((fastify, opts, done) => {
 | 
						|
      fastify.get('/', function (req, reply) {
 | 
						|
        reply.send('I am child 1')
 | 
						|
      })
 | 
						|
      done()
 | 
						|
    }, { prefix: '/child1' })
 | 
						|
 | 
						|
    fastify.register((fastify, opts, done) => {
 | 
						|
      fastify.get('/', function (req, reply) {
 | 
						|
        reply.send('I am child 2')
 | 
						|
      })
 | 
						|
      done()
 | 
						|
    }, { prefix: '/child2' })
 | 
						|
 | 
						|
    done()
 | 
						|
  }, { prefix: '/parent' })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port + '/parent/child1'
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.same(body.toString(), 'I am child 1')
 | 
						|
    })
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port + '/parent/child2'
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.same(body.toString(), 'I am child 2')
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('nested plugins awaited', t => {
 | 
						|
  t.plan(5)
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  t.teardown(fastify.close.bind(fastify))
 | 
						|
 | 
						|
  fastify.register(async function wrap (fastify, opts) {
 | 
						|
    await fastify.register(async function child1 (fastify, opts) {
 | 
						|
      fastify.get('/', function (req, reply) {
 | 
						|
        reply.send('I am child 1')
 | 
						|
      })
 | 
						|
    }, { prefix: '/child1' })
 | 
						|
 | 
						|
    await fastify.register(async function child2 (fastify, opts) {
 | 
						|
      fastify.get('/', function (req, reply) {
 | 
						|
        reply.send('I am child 2')
 | 
						|
      })
 | 
						|
    }, { prefix: '/child2' })
 | 
						|
  }, { prefix: '/parent' })
 | 
						|
 | 
						|
  fastify.listen(0, err => {
 | 
						|
    t.error(err)
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port + '/parent/child1'
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.same(body.toString(), 'I am child 1')
 | 
						|
    })
 | 
						|
 | 
						|
    sget({
 | 
						|
      method: 'GET',
 | 
						|
      url: 'http://localhost:' + fastify.server.address().port + '/parent/child2'
 | 
						|
    }, (err, response, body) => {
 | 
						|
      t.error(err)
 | 
						|
      t.same(body.toString(), 'I am child 2')
 | 
						|
    })
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - decorators', t => {
 | 
						|
  t.plan(1)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.decorate('plugin1', true)
 | 
						|
  fastify.decorateReply('plugin1', true)
 | 
						|
  fastify.decorateRequest('plugin1', true)
 | 
						|
 | 
						|
  plugin[Symbol.for('skip-override')] = true
 | 
						|
  plugin[Symbol.for('plugin-meta')] = {
 | 
						|
    decorators: {
 | 
						|
      fastify: ['plugin1'],
 | 
						|
      reply: ['plugin1'],
 | 
						|
      request: ['plugin1']
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(plugin)
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.ok(fastify.plugin)
 | 
						|
  })
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    instance.decorate('plugin', true)
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - decorators - should throw', t => {
 | 
						|
  t.plan(1)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.decorate('plugin1', true)
 | 
						|
  fastify.decorateReply('plugin1', true)
 | 
						|
 | 
						|
  plugin[Symbol.for('skip-override')] = true
 | 
						|
  plugin[Symbol.for('plugin-meta')] = {
 | 
						|
    decorators: {
 | 
						|
      fastify: ['plugin1'],
 | 
						|
      reply: ['plugin1'],
 | 
						|
      request: ['plugin1']
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(plugin)
 | 
						|
  fastify.ready((err) => {
 | 
						|
    t.equal(err.message, "The decorator 'plugin1' is not present in Request")
 | 
						|
  })
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    instance.decorate('plugin', true)
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - decorators - should throw with plugin name', t => {
 | 
						|
  t.plan(1)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  fastify.decorate('plugin1', true)
 | 
						|
  fastify.decorateReply('plugin1', true)
 | 
						|
 | 
						|
  plugin[Symbol.for('skip-override')] = true
 | 
						|
  plugin[Symbol.for('plugin-meta')] = {
 | 
						|
    name: 'the-plugin',
 | 
						|
    decorators: {
 | 
						|
      fastify: ['plugin1'],
 | 
						|
      reply: ['plugin1'],
 | 
						|
      request: ['plugin1']
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(plugin)
 | 
						|
  fastify.ready((err) => {
 | 
						|
    t.equal(err.message, "The decorator 'plugin1' required by 'the-plugin' is not present in Request")
 | 
						|
  })
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    instance.decorate('plugin', true)
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - dependencies', t => {
 | 
						|
  t.plan(1)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  dependency[Symbol.for('skip-override')] = true
 | 
						|
  dependency[Symbol.for('plugin-meta')] = {
 | 
						|
    name: 'plugin'
 | 
						|
  }
 | 
						|
 | 
						|
  plugin[Symbol.for('skip-override')] = true
 | 
						|
  plugin[Symbol.for('plugin-meta')] = {
 | 
						|
    dependencies: ['plugin']
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(dependency)
 | 
						|
  fastify.register(plugin)
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.pass('everything right')
 | 
						|
  })
 | 
						|
 | 
						|
  function dependency (instance, opts, done) {
 | 
						|
    done()
 | 
						|
  }
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - dependencies (nested)', t => {
 | 
						|
  t.plan(1)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  dependency[Symbol.for('skip-override')] = true
 | 
						|
  dependency[Symbol.for('plugin-meta')] = {
 | 
						|
    name: 'plugin'
 | 
						|
  }
 | 
						|
 | 
						|
  nested[Symbol.for('skip-override')] = true
 | 
						|
  nested[Symbol.for('plugin-meta')] = {
 | 
						|
    dependencies: ['plugin']
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(dependency)
 | 
						|
  fastify.register(plugin)
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.pass('everything right')
 | 
						|
  })
 | 
						|
 | 
						|
  function dependency (instance, opts, done) {
 | 
						|
    done()
 | 
						|
  }
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    instance.register(nested)
 | 
						|
    done()
 | 
						|
  }
 | 
						|
 | 
						|
  function nested (instance, opts, done) {
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
test('pluginTimeout', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify({
 | 
						|
    pluginTimeout: 10
 | 
						|
  })
 | 
						|
  fastify.register(function (app, opts, done) {
 | 
						|
    // to no call done on purpose
 | 
						|
  })
 | 
						|
  fastify.ready((err) => {
 | 
						|
    t.ok(err)
 | 
						|
    t.equal(err.code, 'ERR_AVVIO_PLUGIN_TIMEOUT')
 | 
						|
  })
 | 
						|
})
 | 
						|
 | 
						|
test('pluginTimeout default', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const clock = fakeTimer.install()
 | 
						|
 | 
						|
  const fastify = Fastify()
 | 
						|
  fastify.register(function (app, opts, done) {
 | 
						|
    // default time elapsed without calling done
 | 
						|
    clock.tick(10000)
 | 
						|
  })
 | 
						|
 | 
						|
  fastify.ready((err) => {
 | 
						|
    t.ok(err)
 | 
						|
    t.equal(err.code, 'ERR_AVVIO_PLUGIN_TIMEOUT')
 | 
						|
  })
 | 
						|
 | 
						|
  t.teardown(clock.uninstall)
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - version', t => {
 | 
						|
  t.plan(1)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  plugin[Symbol.for('skip-override')] = true
 | 
						|
  plugin[Symbol.for('plugin-meta')] = {
 | 
						|
    name: 'plugin',
 | 
						|
    fastify: '2.0.0'
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(plugin)
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.pass('everything right')
 | 
						|
  })
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - version range', t => {
 | 
						|
  t.plan(1)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  plugin[Symbol.for('skip-override')] = true
 | 
						|
  plugin[Symbol.for('plugin-meta')] = {
 | 
						|
    name: 'plugin',
 | 
						|
    fastify: '>=2.0.0'
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(plugin)
 | 
						|
 | 
						|
  fastify.ready(() => {
 | 
						|
    t.pass('everything right')
 | 
						|
  })
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - version not matching requirement', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  plugin[Symbol.for('skip-override')] = true
 | 
						|
  plugin[Symbol.for('plugin-meta')] = {
 | 
						|
    name: 'plugin',
 | 
						|
    fastify: '99.0.0'
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(plugin)
 | 
						|
 | 
						|
  fastify.ready((err) => {
 | 
						|
    t.ok(err)
 | 
						|
    t.equal(err.code, 'FST_ERR_PLUGIN_VERSION_MISMATCH')
 | 
						|
  })
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - version not matching requirement 2', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  plugin[Symbol.for('skip-override')] = true
 | 
						|
  plugin[Symbol.for('plugin-meta')] = {
 | 
						|
    name: 'plugin',
 | 
						|
    fastify: '<=3.0.0'
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(plugin)
 | 
						|
 | 
						|
  fastify.ready((err) => {
 | 
						|
    t.ok(err)
 | 
						|
    t.equal(err.code, 'FST_ERR_PLUGIN_VERSION_MISMATCH')
 | 
						|
  })
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
test('plugin metadata - version not matching requirement 3', t => {
 | 
						|
  t.plan(2)
 | 
						|
  const fastify = Fastify()
 | 
						|
 | 
						|
  plugin[Symbol.for('skip-override')] = true
 | 
						|
  plugin[Symbol.for('plugin-meta')] = {
 | 
						|
    name: 'plugin',
 | 
						|
    fastify: '>=99.0.0'
 | 
						|
  }
 | 
						|
 | 
						|
  fastify.register(plugin)
 | 
						|
 | 
						|
  fastify.ready((err) => {
 | 
						|
    t.ok(err)
 | 
						|
    t.equal(err.code, 'FST_ERR_PLUGIN_VERSION_MISMATCH')
 | 
						|
  })
 | 
						|
 | 
						|
  function plugin (instance, opts, done) {
 | 
						|
    done()
 | 
						|
  }
 | 
						|
})
 |