1
0
mirror of synced 2025-12-23 11:54:18 -05:00
Files
docs/tests/rendering/static-assets.js
Peter Bengtsson caf0791694 support archived enterprise assets (#25224)
* support archived enterprise assets

* better tests
2022-02-11 15:58:05 -05:00

169 lines
6.0 KiB
JavaScript

import fs from 'fs'
import path from 'path'
import nock from 'nock'
import { expect, jest } from '@jest/globals'
import { SURROGATE_ENUMS } from '../../middleware/set-fastly-surrogate-key.js'
import { get } from '../helpers/supertest.js'
function getNextStaticAsset(directory) {
const root = path.join('.next', 'static', directory)
const files = fs.readdirSync(root)
if (!files.length) throw new Error(`Can't find any files in ${root}`)
return path.join(root, files[0])
}
function checkCachingHeaders(res, defaultSurrogateKey = false, minMaxAge = 60 * 60) {
expect(res.headers['set-cookie']).toBeUndefined()
expect(res.headers['cache-control']).toContain('public')
const maxAgeSeconds = parseInt(res.header['cache-control'].match(/max-age=(\d+)/)[1], 10)
// Let's not be too specific in the tests, just as long as it's testing
// that it's a reasonably large number of seconds.
expect(maxAgeSeconds).toBeGreaterThanOrEqual(minMaxAge)
// Because it doesn't have have a unique URL
expect(res.headers['surrogate-key']).toBe(
defaultSurrogateKey ? SURROGATE_ENUMS.DEFAULT : SURROGATE_ENUMS.MANUAL
)
}
describe('static assets', () => {
it('should serve /assets/cb-* with optimal headers', async () => {
const res = await get('/assets/cb-1234/images/site/logo.png')
expect(res.statusCode).toBe(200)
checkCachingHeaders(res)
})
it('should serve /assets/ with optimal headers', async () => {
const res = await get('/assets/images/site/logo.png')
expect(res.statusCode).toBe(200)
checkCachingHeaders(res, true)
})
it('should serve /_next/static/ with optimal headers', async () => {
// This picks the first one found. We just need it to be anything
// that actually resolves.
const filePath = getNextStaticAsset('css')
const asURL = '/' + filePath.replace('.next', '_next').split(path.sep).join('/')
const res = await get(asURL)
expect(res.statusCode).toBe(200)
checkCachingHeaders(res)
})
it('should 404 on /assets/cb-* with plain text', async () => {
const res = await get('/assets/cb-1234/never/heard/of.png')
expect(res.statusCode).toBe(404)
expect(res.header['content-type']).toContain('text/plain')
// Only a tiny amount of Cache-Control on these
checkCachingHeaders(res, true, 60)
})
it('should 404 on /assets/ with plain text', async () => {
const res = await get('/assets/never/heard/of.png')
expect(res.statusCode).toBe(404)
expect(res.header['content-type']).toContain('text/plain')
checkCachingHeaders(res, true, 60)
})
it('should 404 on /_next/static/ with plain text', async () => {
const res = await get('/_next/static/never/heard/of.css')
expect(res.statusCode).toBe(404)
expect(res.header['content-type']).toContain('text/plain')
checkCachingHeaders(res, true, 60)
})
})
describe('archived enterprise static assets', () => {
// Sometimes static assets are proxied. The URL for the static asset
// might not indicate it's based on archived enterprise version.
jest.setTimeout(60 * 1000)
beforeAll(async () => {
// The first page load takes a long time so let's get it out of the way in
// advance to call out that problem specifically rather than misleadingly
// attributing it to the first test
// await get('/')
const sampleCSS = '/* nice CSS */'
nock('https://github.github.com')
.get('/help-docs-archived-enterprise-versions/2.21/_next/static/foo.css')
.reply(200, sampleCSS, {
'content-type': 'text/css',
'content-length': sampleCSS.length,
})
nock('https://github.github.com')
.get('/help-docs-archived-enterprise-versions/2.21/_next/static/only-on-proxy.css')
.reply(200, sampleCSS, {
'content-type': 'text/css',
'content-length': sampleCSS.length,
})
nock('https://github.github.com')
.get('/help-docs-archived-enterprise-versions/2.3/_next/static/only-on-2.3.css')
.reply(200, sampleCSS, {
'content-type': 'text/css',
'content-length': sampleCSS.length,
})
nock('https://github.github.com')
.get('/help-docs-archived-enterprise-versions/2.3/_next/static/fourofour.css')
.reply(404, 'Not found', {
'content-type': 'text/plain',
})
nock('https://github.github.com')
.get('/help-docs-archived-enterprise-versions/2.3/assets/images/site/logo.png')
.reply(404, 'Not found', {
'content-type': 'text/plain',
})
})
afterAll(() => nock.cleanAll())
it('should proxy if the static asset is prefixed', async () => {
const res = await get('/enterprise/2.21/_next/static/foo.css', {
headers: {
Referrer: '/enterprise/2.21',
},
})
expect(res.statusCode).toBe(200)
checkCachingHeaders(res, true, 60)
})
it('should proxy if the Referrer header indicates so', async () => {
const res = await get('/_next/static/only-on-proxy.css', {
headers: {
Referrer: '/enterprise/2.21',
},
})
expect(res.statusCode).toBe(200)
checkCachingHeaders(res, true, 60)
})
it('should proxy if the Referrer header indicates so', async () => {
const res = await get('/_next/static/only-on-2.3.css', {
headers: {
Referrer: '/en/enterprise-server@2.3/some/page',
},
})
expect(res.statusCode).toBe(200)
checkCachingHeaders(res, true, 60)
})
it('might still 404 even with the right referrer', async () => {
const res = await get('/_next/static/fourofour.css', {
headers: {
Referrer: '/en/enterprise-server@2.3/some/page',
},
})
expect(res.statusCode).toBe(404)
checkCachingHeaders(res, true, 60)
})
it('404 on the proxy but actually present here', async () => {
const res = await get('/assets/images/site/logo.png', {
headers: {
Referrer: '/en/enterprise-server@2.3/some/page',
},
})
// It tried to go via the proxy, but it wasn't there, but then it
// tried "our disk" and it's eventually there.
expect(res.statusCode).toBe(200)
checkCachingHeaders(res, true, 60)
})
})