187 lines
5.7 KiB
JavaScript
187 lines
5.7 KiB
JavaScript
import nock from 'nock'
|
|
import { expect, jest } from '@jest/globals'
|
|
|
|
import { checkCachingHeaders } from '../helpers/caching-headers.js'
|
|
import { setDefaultFastlySurrogateKey } from '../../middleware/set-fastly-surrogate-key.js'
|
|
import archivedEnterpriseVersionsAssets from '../../middleware/archived-enterprise-versions-assets.js'
|
|
|
|
function mockRequest(path, { headers }) {
|
|
const _headers = Object.fromEntries(
|
|
Object.entries(headers || {}).map(([key, value]) => [key.toLowerCase(), value])
|
|
)
|
|
return {
|
|
path,
|
|
url: path,
|
|
get: (header) => {
|
|
return _headers[header.toLowerCase()]
|
|
},
|
|
set: (header, value) => {
|
|
_headers[header.toLowerCase()] = value
|
|
},
|
|
|
|
headers,
|
|
}
|
|
}
|
|
const mockResponse = () => {
|
|
const res = {}
|
|
res.status = 404
|
|
res.statusCode = 404
|
|
res.json = (payload) => {
|
|
res._json = payload
|
|
}
|
|
res.send = (body) => {
|
|
res.status = 200
|
|
res.statusCode = 200
|
|
res._send = body
|
|
}
|
|
res.headers = {}
|
|
res.set = (key, value) => {
|
|
if (typeof key === 'string') {
|
|
res.headers[key.toLowerCase()] = value
|
|
} else {
|
|
for (const [k, value] of Object.entries(key)) {
|
|
res.headers[k.toLowerCase()] = value
|
|
}
|
|
}
|
|
}
|
|
res.removeHeader = (key) => {
|
|
delete res.headers[key]
|
|
}
|
|
res.hasHeader = (key) => {
|
|
return key in res.headers
|
|
}
|
|
return res
|
|
}
|
|
|
|
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 req = mockRequest('/enterprise/2.21/_next/static/foo.css', {
|
|
headers: {
|
|
Referrer: '/enterprise/2.21',
|
|
},
|
|
})
|
|
const res = mockResponse()
|
|
const next = () => {
|
|
throw new Error('did not expect this to ever happen')
|
|
}
|
|
setDefaultFastlySurrogateKey(req, res, () => {})
|
|
await archivedEnterpriseVersionsAssets(req, res, next)
|
|
expect(res.statusCode).toBe(200)
|
|
checkCachingHeaders(res, false, 60)
|
|
})
|
|
|
|
it('should proxy if the Referrer header indicates so on home page', async () => {
|
|
const req = mockRequest('/_next/static/only-on-proxy.css', {
|
|
headers: {
|
|
Referrer: '/enterprise/2.21',
|
|
},
|
|
})
|
|
const res = mockResponse()
|
|
const next = () => {
|
|
throw new Error('did not expect this to ever happen')
|
|
}
|
|
setDefaultFastlySurrogateKey(req, res, () => {})
|
|
await archivedEnterpriseVersionsAssets(req, res, next)
|
|
expect(res.statusCode).toBe(200)
|
|
checkCachingHeaders(res, false, 60)
|
|
})
|
|
|
|
it('should proxy if the Referrer header indicates so on sub-page', async () => {
|
|
const req = mockRequest('/_next/static/only-on-2.3.css', {
|
|
headers: {
|
|
Referrer: '/en/enterprise-server@2.3/some/page',
|
|
},
|
|
})
|
|
const res = mockResponse()
|
|
const next = () => {
|
|
throw new Error('did not expect this to ever happen')
|
|
}
|
|
setDefaultFastlySurrogateKey(req, res, () => {})
|
|
await archivedEnterpriseVersionsAssets(req, res, next)
|
|
expect(res.statusCode).toBe(200)
|
|
checkCachingHeaders(res, false, 60)
|
|
})
|
|
|
|
it('might still 404 even with the right referrer', async () => {
|
|
const req = mockRequest('/_next/static/fourofour.css', {
|
|
headers: {
|
|
Referrer: '/en/enterprise-server@2.3/some/page',
|
|
},
|
|
})
|
|
const res = mockResponse()
|
|
let nexted = false
|
|
const next = () => {
|
|
nexted = true
|
|
}
|
|
setDefaultFastlySurrogateKey(req, res, next)
|
|
await archivedEnterpriseVersionsAssets(req, res, next)
|
|
expect(res.statusCode).toBe(404)
|
|
// It did't exit in that middleware but called next() to move on
|
|
// with any other middlewares.
|
|
expect(nexted).toBe(true)
|
|
})
|
|
|
|
it('404 on the proxy but actually present here', async () => {
|
|
const req = mockRequest('/assets/images/site/logo.png', {
|
|
headers: {
|
|
Referrer: '/en/enterprise-server@2.3/some/page',
|
|
},
|
|
})
|
|
const res = mockResponse()
|
|
let nexted = false
|
|
const next = () => {
|
|
nexted = true
|
|
}
|
|
setDefaultFastlySurrogateKey(req, res, () => {})
|
|
await archivedEnterpriseVersionsAssets(req, res, next)
|
|
// It tried to go via the proxy, but it wasn't there, but then it
|
|
// tried "our disk" and it's eventually there.
|
|
expect(nexted).toBe(true)
|
|
})
|
|
})
|