@fastify/caching
Version:
A plugin for Fastify to enable management of cache control headers
310 lines (236 loc) • 6.58 kB
JavaScript
'use strict'
const { test } = require('node:test')
const Fastify = require('fastify')
const plugin = require('..')
test('decorators get added', async (t) => {
t.plan(1)
const fastify = Fastify()
await fastify.register(plugin)
fastify.get('/', (_req, reply) => {
t.assert.ok(reply.etag)
reply.send()
})
await fastify.ready()
await fastify.inject({
method: 'GET',
path: '/'
})
})
test('decorators add headers', async (t) => {
t.plan(2)
const tag = '123456'
const fastify = Fastify()
await fastify.register(plugin)
fastify.get('/', (_req, reply) => {
reply.etag(tag).send()
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers.etag)
t.assert.strictEqual(response.headers.etag, tag)
})
test('sets etag header for falsy argument', async (t) => {
t.plan(1)
const fastify = Fastify()
await fastify.register(plugin)
fastify.get('/', (_req, reply) => {
reply.etag().send()
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers.etag)
})
test('sets no-cache header', async (t) => {
t.plan(2)
const fastify = Fastify()
await fastify.register(plugin, { privacy: plugin.privacy.NOCACHE })
fastify.get('/', (_req, reply) => {
reply.send({ hello: 'world' })
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers['cache-control'])
t.assert.strictEqual(response.headers['cache-control'], 'no-cache')
})
test('sets private with max-age header', async (t) => {
t.plan(2)
const opts = {
privacy: plugin.privacy.PRIVATE,
expiresIn: 300
}
const fastify = Fastify()
await fastify.register(plugin, opts)
fastify.get('/', (_req, reply) => {
reply.send({ hello: 'world' })
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers['cache-control'])
t.assert.strictEqual(
response.headers['cache-control'],
'private, max-age=300'
)
})
test('sets public with max-age and s-maxage header', async (t) => {
t.plan(2)
const opts = {
privacy: plugin.privacy.PUBLIC,
expiresIn: 300,
serverExpiresIn: 12345
}
const fastify = Fastify()
await fastify.register(plugin, opts)
fastify.get('/', (_req, reply) => {
reply.send({ hello: 'world' })
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers['cache-control'])
t.assert.strictEqual(
response.headers['cache-control'],
'public, max-age=300, s-maxage=12345'
)
})
test('do not set headers if another upstream plugin already sets it', async (t) => {
t.plan(2)
const opts = {
privacy: plugin.privacy.PUBLIC,
expiresIn: 300,
serverExpiresIn: 12345
}
const fastify = Fastify()
fastify.addHook('onRequest', async function checkCachingDoesNotOverrideCacheControlHeader (_req, reply) {
reply.header('cache-control', 'do not override')
})
await fastify.register(plugin, opts)
fastify.get('/', (_req, reply) => {
reply.send({ hello: 'world' })
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers['cache-control'])
t.assert.strictEqual(response.headers['cache-control'], 'do not override')
})
test('only sets max-age and ignores s-maxage with private header', async (t) => {
t.plan(2)
const opts = {
privacy: plugin.privacy.PRIVATE,
expiresIn: 300,
serverExpiresIn: 12345
}
const fastify = Fastify()
await fastify.register(plugin, opts)
fastify.get('/', (_req, reply) => {
reply.send({ hello: 'world' })
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers['cache-control'])
t.assert.strictEqual(
response.headers['cache-control'],
'private, max-age=300'
)
})
test('s-maxage is optional with public header', async (t) => {
t.plan(2)
const opts = {
privacy: plugin.privacy.PUBLIC,
expiresIn: 300
}
const fastify = Fastify()
await fastify.register(plugin, opts)
fastify.get('/', (_req, reply) => {
reply.send({ hello: 'world' })
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers['cache-control'])
t.assert.strictEqual(response.headers['cache-control'], 'public, max-age=300')
})
test('sets no-store with max-age header', async (t) => {
t.plan(2)
const fastify = Fastify()
await fastify.register(plugin, { privacy: 'no-store', expiresIn: 300 })
fastify.get('/', (_req, reply) => {
reply.send({ hello: 'world' })
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers['cache-control'])
t.assert.strictEqual(
response.headers['cache-control'],
'no-store, max-age=300'
)
})
test('sets the expires header', async (t) => {
t.plan(2)
const now = new Date()
const fastify = Fastify()
await fastify.register(plugin, { privacy: plugin.privacy.NOCACHE })
fastify.get('/', (_req, reply) => {
reply.expires(now).send({ hello: 'world' })
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers.expires)
t.assert.strictEqual(response.headers.expires, now.toUTCString())
})
test('sets the expires header to a falsy value', async (t) => {
t.plan(1)
const fastify = Fastify()
await fastify.register(plugin, { privacy: plugin.privacy.NOCACHE })
fastify.get('/', (_req, reply) => {
reply.expires().send({ hello: 'world' })
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ifError(response.headers.expires)
})
test('sets the expires header to a custom value', async (t) => {
t.plan(2)
const fastify = Fastify()
await fastify.register(plugin, { privacy: plugin.privacy.NOCACHE })
fastify.get('/', (_req, reply) => {
reply.expires('foobar').send({ hello: 'world' })
})
await fastify.ready()
const response = await fastify.inject({
method: 'GET',
path: '/'
})
t.assert.ok(response.headers.expires)
t.assert.strictEqual(response.headers.expires, 'foobar')
})