CoolFace
Apppublic

strong-tie/inbound-calls

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
hooks.on-ready.test.js404 linesDownload Raw Back to test
1'use strict'2 3const t = require('tap')4const Fastify = require('../fastify')5const immediate = require('node:util').promisify(setImmediate)6 7t.test('onReady should be called in order', t => {8  t.plan(7)9  const fastify = Fastify()10 11  let order = 012 13  fastify.addHook('onReady', function (done) {14    t.equal(order++, 0, 'called in root')15    t.equal(this.pluginName, fastify.pluginName, 'the this binding is the right instance')16    done()17  })18 19  fastify.register(async (childOne, o) => {20    childOne.addHook('onReady', function (done) {21      t.equal(order++, 1, 'called in childOne')22      t.equal(this.pluginName, childOne.pluginName, 'the this binding is the right instance')23      done()24    })25 26    childOne.register(async (childTwo, o) => {27      childTwo.addHook('onReady', async function () {28        await immediate()29        t.equal(order++, 2, 'called in childTwo')30        t.equal(this.pluginName, childTwo.pluginName, 'the this binding is the right instance')31      })32    })33  })34 35  fastify.ready(err => t.error(err))36})37 38t.test('onReady should be called once', async (t) => {39  const app = Fastify()40  let counter = 041 42  app.addHook('onReady', async function () {43    counter++44  })45 46  const promises = [1, 2, 3, 4, 5].map((id) => app.ready().then(() => id))47 48  const result = await Promise.race(promises)49 50  t.strictSame(result, 1, 'Should resolve in order')51  t.equal(counter, 1, 'Should call onReady only once')52})53 54t.test('async onReady should be called in order', async t => {55  t.plan(7)56  const fastify = Fastify()57 58  let order = 059 60  fastify.addHook('onReady', async function () {61    await immediate()62    t.equal(order++, 0, 'called in root')63    t.equal(this.pluginName, fastify.pluginName, 'the this binding is the right instance')64  })65 66  fastify.register(async (childOne, o) => {67    childOne.addHook('onReady', async function () {68      await immediate()69      t.equal(order++, 1, 'called in childOne')70      t.equal(this.pluginName, childOne.pluginName, 'the this binding is the right instance')71    })72 73    childOne.register(async (childTwo, o) => {74      childTwo.addHook('onReady', async function () {75        await immediate()76        t.equal(order++, 2, 'called in childTwo')77        t.equal(this.pluginName, childTwo.pluginName, 'the this binding is the right instance')78      })79    })80  })81 82  await fastify.ready()83  t.pass('ready')84})85 86t.test('mix ready and onReady', async t => {87  t.plan(2)88  const fastify = Fastify()89  let order = 090 91  fastify.addHook('onReady', async function () {92    await immediate()93    order++94  })95 96  await fastify.ready()97  t.equal(order, 1)98 99  await fastify.ready()100  t.equal(order, 1, 'ready hooks execute once')101})102 103t.test('listen and onReady order', async t => {104  t.plan(9)105 106  const fastify = Fastify()107  let order = 0108 109  fastify.register((instance, opts, done) => {110    instance.ready(checkOrder.bind(null, 0))111    instance.addHook('onReady', checkOrder.bind(null, 4))112 113    instance.register((subinstance, opts, done) => {114      subinstance.ready(checkOrder.bind(null, 1))115      subinstance.addHook('onReady', checkOrder.bind(null, 5))116 117      subinstance.register((realSubInstance, opts, done) => {118        realSubInstance.ready(checkOrder.bind(null, 2))119        realSubInstance.addHook('onReady', checkOrder.bind(null, 6))120        done()121      })122      done()123    })124    done()125  })126 127  fastify.addHook('onReady', checkOrder.bind(null, 3))128 129  await fastify.ready()130  t.pass('trigger the onReady')131  await fastify.listen({ port: 0 })132  t.pass('do not trigger the onReady')133 134  await fastify.close()135 136  function checkOrder (shouldbe) {137    t.equal(order, shouldbe)138    order++139  }140})141 142t.test('multiple ready calls', async t => {143  t.plan(11)144 145  const fastify = Fastify()146  let order = 0147 148  fastify.register(async (instance, opts) => {149    instance.ready(checkOrder.bind(null, 1))150    instance.addHook('onReady', checkOrder.bind(null, 6))151 152    await instance.register(async (subinstance, opts) => {153      subinstance.ready(checkOrder.bind(null, 2))154      subinstance.addHook('onReady', checkOrder.bind(null, 7))155    })156 157    t.equal(order, 0, 'ready and hooks not triggered yet')158    order++159  })160 161  fastify.addHook('onReady', checkOrder.bind(null, 3))162  fastify.addHook('onReady', checkOrder.bind(null, 4))163  fastify.addHook('onReady', checkOrder.bind(null, 5))164 165  await fastify.ready()166  t.pass('trigger the onReady')167 168  await fastify.ready()169  t.pass('do not trigger the onReady')170 171  await fastify.ready()172  t.pass('do not trigger the onReady')173 174  function checkOrder (shouldbe) {175    t.equal(order, shouldbe)176    order++177  }178})179 180t.test('onReady should manage error in sync', t => {181  t.plan(4)182  const fastify = Fastify()183 184  fastify.addHook('onReady', function (done) {185    t.pass('called in root')186    done()187  })188 189  fastify.register(async (childOne, o) => {190    childOne.addHook('onReady', function (done) {191      t.pass('called in childOne')192      done(new Error('FAIL ON READY'))193    })194 195    childOne.register(async (childTwo, o) => {196      childTwo.addHook('onReady', async function () {197        t.fail('should not be called')198      })199    })200  })201 202  fastify.ready(err => {203    t.ok(err)204    t.equal(err.message, 'FAIL ON READY')205  })206})207 208t.test('onReady should manage error in async', t => {209  t.plan(4)210  const fastify = Fastify()211 212  fastify.addHook('onReady', function (done) {213    t.pass('called in root')214    done()215  })216 217  fastify.register(async (childOne, o) => {218    childOne.addHook('onReady', async function () {219      t.pass('called in childOne')220      throw new Error('FAIL ON READY')221    })222 223    childOne.register(async (childTwo, o) => {224      childTwo.addHook('onReady', async function () {225        t.fail('should not be called')226      })227    })228  })229 230  fastify.ready(err => {231    t.ok(err)232    t.equal(err.message, 'FAIL ON READY')233  })234})235 236t.test('onReady should manage sync error', t => {237  t.plan(4)238  const fastify = Fastify()239 240  fastify.addHook('onReady', function (done) {241    t.pass('called in root')242    done()243  })244 245  fastify.register(async (childOne, o) => {246    childOne.addHook('onReady', function (done) {247      t.pass('called in childOne')248      throw new Error('FAIL UNWANTED SYNC EXCEPTION')249    })250 251    childOne.register(async (childTwo, o) => {252      childTwo.addHook('onReady', async function () {253        t.fail('should not be called')254      })255    })256  })257 258  fastify.ready(err => {259    t.ok(err)260    t.equal(err.message, 'FAIL UNWANTED SYNC EXCEPTION')261  })262})263 264t.test('onReady can not add decorators or application hooks', t => {265  t.plan(3)266  const fastify = Fastify()267 268  fastify.addHook('onReady', function (done) {269    t.pass('called in root')270    fastify.decorate('test', () => {})271 272    fastify.addHook('onReady', async function () {273      t.fail('it will be not called')274    })275    done()276  })277 278  fastify.addHook('onReady', function (done) {279    t.ok(this.hasDecorator('test'))280    done()281  })282 283  fastify.ready(err => { t.error(err) })284})285 286t.test('onReady cannot add lifecycle hooks', t => {287  t.plan(5)288  const fastify = Fastify()289 290  fastify.addHook('onReady', function (done) {291    t.pass('called in root')292    try {293      fastify.addHook('onRequest', (request, reply, done) => {})294    } catch (error) {295      t.ok(error)296      t.equal(error.message, 'Root plugin has already booted')297      // TODO: look where the error pops up298      t.equal(error.code, 'AVV_ERR_ROOT_PLG_BOOTED')299      done(error)300    }301  })302 303  fastify.addHook('onRequest', (request, reply, done) => {})304  fastify.get('/', async () => 'hello')305 306  fastify.ready((err) => { t.ok(err) })307})308 309t.test('onReady throw loading error', t => {310  t.plan(2)311  const fastify = Fastify()312 313  try {314    fastify.addHook('onReady', async function (done) {})315  } catch (e) {316    t.ok(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')317    t.ok(e.message === 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')318  }319})320 321t.test('onReady does not call done', t => {322  t.plan(6)323  const fastify = Fastify({ pluginTimeout: 500 })324 325  fastify.addHook('onReady', function someHookName (done) {326    t.pass('called in root')327    // done() // don't call done to test timeout328  })329 330  fastify.ready(err => {331    t.ok(err)332    t.equal(err.message, 'A callback for \'onReady\' hook "someHookName" timed out. You may have forgotten to call \'done\' function or to resolve a Promise')333    t.equal(err.code, 'FST_ERR_HOOK_TIMEOUT')334    t.ok(err.cause)335    t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')336  })337})338 339t.test('onReady execution order', t => {340  t.plan(3)341  const fastify = Fastify({ })342 343  let i = 0344  fastify.ready(() => { i++; t.equal(i, 1) })345  fastify.ready(() => { i++; t.equal(i, 2) })346  fastify.ready(() => { i++; t.equal(i, 3) })347})348 349t.test('ready return the server with callback', t => {350  t.plan(2)351  const fastify = Fastify()352 353  fastify.ready((err, instance) => {354    t.error(err)355    t.same(instance, fastify)356  })357})358 359t.test('ready return the server with Promise', t => {360  t.plan(1)361  const fastify = Fastify()362 363  fastify.ready()364    .then(instance => { t.same(instance, fastify) })365    .catch(err => { t.fail(err) })366})367 368t.test('ready return registered', t => {369  t.plan(4)370  const fastify = Fastify()371 372  fastify.register((one, opts, done) => {373    one.ready().then(itself => { t.same(itself, one) })374    done()375  })376 377  fastify.register((two, opts, done) => {378    two.ready().then(itself => { t.same(itself, two) })379 380    two.register((twoDotOne, opts, done) => {381      twoDotOne.ready().then(itself => { t.same(itself, twoDotOne) })382      done()383    })384    done()385  })386 387  fastify.ready()388    .then(instance => { t.same(instance, fastify) })389    .catch(err => { t.fail(err) })390})391 392t.test('do not crash with error in follow up onReady hook', async t => {393  const fastify = Fastify()394 395  fastify.addHook('onReady', async function () {396  })397 398  fastify.addHook('onReady', function () {399    throw new Error('kaboom')400  })401 402  await t.rejects(fastify.ready())403})404