* cache full rendering * still not working with gzip * progress progress progress * smaller * hacky progress * small fixes * wip * lock file * wip * wip * package-lock updates * wip * search DOM in lowercase * simplify * with instrument * improve test coverage * mutateCheeriobodyByRequest * fix * remove renderContentCacheByContex * disable render caching in sync-search * diables things in github/github link checker * gzip lru * tidying up * updated * correct tests * fix: move userLanguage to LanguagesContext * Revert "fix: move userLanguage to LanguagesContext" This reverts commit d7c05d958c71eaad496eb46764eb845d80b866ca. * contexts ftw * fixed rendering tests * oops for got new file * nits addressed Co-authored-by: Mike Surowiec <mikesurowiec@users.noreply.github.com>
161 lines
6.0 KiB
JavaScript
161 lines
6.0 KiB
JavaScript
import cheerio from 'cheerio'
|
|
import { expect, jest, test } from '@jest/globals'
|
|
|
|
import { get } from '../helpers/e2etest.js'
|
|
import { PREFERRED_LOCALE_COOKIE_NAME } from '../../middleware/detect-language.js'
|
|
import {
|
|
getNextData,
|
|
getPrimerData,
|
|
getUserLanguage,
|
|
getIsDotComAuthenticated,
|
|
} from '../helpers/script-data.js'
|
|
|
|
const serializeTheme = (theme) => {
|
|
return encodeURIComponent(JSON.stringify(theme))
|
|
}
|
|
|
|
describe('in-memory render caching', () => {
|
|
jest.setTimeout(30 * 1000)
|
|
|
|
test('second render should be a cache hit with different csrf-token', async () => {
|
|
const res = await get('/en')
|
|
// Because these are effectively end-to-end tests, you can't expect
|
|
// the first request to be a cache miss because another end-to-end
|
|
// test might have "warmed up" this endpoint.
|
|
expect(res.headers['x-middleware-cache']).toBeTruthy()
|
|
const $1 = cheerio.load(res.text)
|
|
const res2 = await get('/en')
|
|
expect(res2.headers['x-middleware-cache']).toBe('hit')
|
|
const $2 = cheerio.load(res2.text)
|
|
const csrfTokenHTML1 = $1('meta[name="csrf-token"]').attr('content')
|
|
const csrfTokenHTML2 = $2('meta[name="csrf-token"]').attr('content')
|
|
expect(csrfTokenHTML1).not.toBe(csrfTokenHTML2)
|
|
// The HTML is one thing, we also need to check that the
|
|
// __NEXT_DATA__ serialized (JSON) state is different.
|
|
const csrfTokenNEXT1 = getNextData($1).props.csrfToken
|
|
const csrfTokenNEXT2 = getNextData($2).props.csrfToken
|
|
expect(csrfTokenHTML1).toBe(csrfTokenNEXT1)
|
|
expect(csrfTokenHTML2).toBe(csrfTokenNEXT2)
|
|
expect(csrfTokenNEXT1).not.toBe(csrfTokenNEXT2)
|
|
})
|
|
|
|
test('second render should be a cache hit with different dotcom-auth', async () => {
|
|
// Anonymous first
|
|
const res = await get('/en')
|
|
// Because these are effectively end-to-end tests, you can't expect
|
|
// the first request to be a cache miss because another end-to-end
|
|
// test might have "warmed up" this endpoint.
|
|
expect(res.headers['x-middleware-cache']).toBeTruthy()
|
|
const $1 = cheerio.load(res.text)
|
|
const res2 = await get('/en', {
|
|
headers: {
|
|
cookie: 'dotcom_user=peterbe',
|
|
},
|
|
})
|
|
expect(res2.headers['x-middleware-cache']).toBe('hit')
|
|
const $2 = cheerio.load(res2.text)
|
|
// The HTML is one thing, we also need to check that the
|
|
// __NEXT_DATA__ serialized (JSON) state is different.
|
|
const dotcomAuthNEXT1 = getIsDotComAuthenticated($1)
|
|
const dotcomAuthNEXT2 = getIsDotComAuthenticated($2)
|
|
expect(dotcomAuthNEXT1).not.toBe(dotcomAuthNEXT2)
|
|
})
|
|
|
|
test('second render should be a cache hit with different theme properties', async () => {
|
|
const cookieValue1 = {
|
|
color_mode: 'light',
|
|
light_theme: { name: 'light', color_mode: 'light' },
|
|
dark_theme: { name: 'dark_high_contrast', color_mode: 'dark' },
|
|
}
|
|
// Light mode first
|
|
const res1 = await get('/en', {
|
|
headers: {
|
|
cookie: `color_mode=${serializeTheme(cookieValue1)}`,
|
|
},
|
|
})
|
|
// Because these are effectively end-to-end tests, you can't expect
|
|
// the first request to be a cache miss because another end-to-end
|
|
// test might have "warmed up" this endpoint.
|
|
expect(res1.headers['x-middleware-cache']).toBeTruthy()
|
|
const $1 = cheerio.load(res1.text)
|
|
expect($1('body').data('color-mode')).toBe(cookieValue1.color_mode)
|
|
const themeProps1 = getNextData($1).props.themeProps
|
|
expect(themeProps1.colorMode).toBe('day')
|
|
|
|
const cookieValue2 = {
|
|
color_mode: 'dark',
|
|
light_theme: { name: 'light', color_mode: 'light' },
|
|
dark_theme: { name: 'dark_high_contrast', color_mode: 'dark' },
|
|
}
|
|
const res2 = await get('/en', {
|
|
headers: {
|
|
cookie: `color_mode=${serializeTheme(cookieValue2)}`,
|
|
},
|
|
})
|
|
expect(res2.headers['x-middleware-cache']).toBeTruthy()
|
|
const $2 = cheerio.load(res2.text)
|
|
expect($2('body').data('color-mode')).toBe(cookieValue2.color_mode)
|
|
const themeProps2 = getNextData($2).props.themeProps
|
|
expect(themeProps2.colorMode).toBe('night')
|
|
})
|
|
|
|
test('second render should be cache hit with different resolvedServerColorMode in __PRIMER_DATA__', async () => {
|
|
await get('/en') // first render to assert the next render comes from cache
|
|
|
|
const res = await get('/en', {
|
|
headers: {
|
|
cookie: `color_mode=${serializeTheme({
|
|
color_mode: 'dark',
|
|
light_theme: { name: 'light', color_mode: 'light' },
|
|
dark_theme: { name: 'dark_high_contrast', color_mode: 'dark' },
|
|
})}`,
|
|
},
|
|
})
|
|
expect(res.headers['x-middleware-cache']).toBeTruthy()
|
|
const $ = cheerio.load(res.text)
|
|
const data = getPrimerData($)
|
|
expect(data.resolvedServerColorMode).toBe('night')
|
|
|
|
// Now do it all over again but with a light color mode
|
|
const res2 = await get('/en', {
|
|
headers: {
|
|
cookie: `color_mode=${serializeTheme({
|
|
color_mode: 'light',
|
|
light_theme: { name: 'light', color_mode: 'light' },
|
|
dark_theme: { name: 'dark_high_contrast', color_mode: 'dark' },
|
|
})}`,
|
|
},
|
|
})
|
|
expect(res2.headers['x-middleware-cache']).toBeTruthy()
|
|
const $2 = cheerio.load(res2.text)
|
|
const data2 = getPrimerData($2)
|
|
expect(data2.resolvedServerColorMode).toBe('day')
|
|
})
|
|
|
|
test('user-language, by header, in meta tag', async () => {
|
|
await get('/en') // first render to assert the next render comes from cache
|
|
|
|
const res = await get('/en', {
|
|
headers: { 'accept-language': 'ja;q=1.0, *;q=0.9' },
|
|
})
|
|
expect(res.headers['x-middleware-cache']).toBeTruthy()
|
|
const $ = cheerio.load(res.text)
|
|
const userLanguage = getUserLanguage($)
|
|
expect(userLanguage).toBe('ja')
|
|
})
|
|
|
|
test('user-language, by cookie, in meta tag', async () => {
|
|
await get('/en') // first render to assert the next render comes from cache
|
|
|
|
const res = await get('/en', {
|
|
headers: {
|
|
Cookie: `${PREFERRED_LOCALE_COOKIE_NAME}=ja`,
|
|
},
|
|
})
|
|
expect(res.headers['x-middleware-cache']).toBeTruthy()
|
|
const $ = cheerio.load(res.text)
|
|
const userLanguage = getUserLanguage($)
|
|
expect(userLanguage).toBe('ja')
|
|
})
|
|
})
|