Compute category versions from combining versions of children (#45685)
This commit is contained in:
@@ -2,10 +2,11 @@
|
||||
title: Versioning
|
||||
intro: 'Testing of pages that only available in *some* versions'
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghes: '*'
|
||||
ghae: '*'
|
||||
ghec: '*'
|
||||
# Note that these here are wrong!
|
||||
# They deliberately don't match what's set in the versions
|
||||
# within the children.
|
||||
ghes: '>=3.99'
|
||||
ghec: '<1.0'
|
||||
children:
|
||||
- /only-fpt
|
||||
- /only-ghec
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { expect } from '@jest/globals'
|
||||
import { getDOM, head } from '#src/tests/helpers/e2etest.js'
|
||||
import { supported } from '#src/versions/lib/enterprise-server-releases.js'
|
||||
|
||||
@@ -47,6 +46,33 @@ describe('article versioning', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('category versioning', () => {
|
||||
test('category page work in all children versions', async () => {
|
||||
{
|
||||
// Note that in the `versions:` of get-started/versioning/index.md
|
||||
// it *lacks* fpt. It's a deliberate pretend omission/mistake.
|
||||
// But clearly the page works.
|
||||
const res = await head('/en/get-started/versioning')
|
||||
expect(res.statusCode).toBe(200)
|
||||
}
|
||||
{
|
||||
// The actual version number of get-started/versioning/index.md
|
||||
// does not specify this version of ghes, it still works.
|
||||
const res = await head('/en/enterprise-server@latest/get-started/versioning')
|
||||
expect(res.statusCode).toBe(302)
|
||||
expect(res.headers.location).toMatch(
|
||||
/\/en\/enterprise-server@[\d.]+\/get-started\/versioning/,
|
||||
)
|
||||
}
|
||||
{
|
||||
// The actual version number of get-started/versioning/index.md
|
||||
// does not specify this version of ghec, it still works.
|
||||
const res = await head('/en/enterprise-cloud@latest/get-started/versioning')
|
||||
expect(res.statusCode).toBe(200)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('home page versioning', () => {
|
||||
test('invalid language and valid version', async () => {
|
||||
// Don't use 'latest' here because that will trigger a redirect
|
||||
|
||||
@@ -6,6 +6,7 @@ import createTree from './create-tree.js'
|
||||
import nonEnterpriseDefaultVersion from '#src/versions/lib/non-enterprise-default-version.js'
|
||||
import readFileContents from './read-file-contents.js'
|
||||
import Page from './page.js'
|
||||
import Permalink from './permalink.js'
|
||||
import frontmatterSchema from './frontmatter.js'
|
||||
import { correctTranslatedContentStrings } from '#src/languages/lib/correct-translation-content.js'
|
||||
|
||||
@@ -42,6 +43,7 @@ export async function loadUnversionedTree(languagesOnly = null) {
|
||||
}
|
||||
const unversionedTree = {}
|
||||
unversionedTree.en = await createTree(path.join(languages.en.dir, 'content'))
|
||||
setCategoryApplicableVersions(unversionedTree.en)
|
||||
|
||||
const languagesValues = Object.entries(languages)
|
||||
.filter(([language]) => {
|
||||
@@ -67,6 +69,52 @@ export async function loadUnversionedTree(languagesOnly = null) {
|
||||
return unversionedTree
|
||||
}
|
||||
|
||||
function setCategoryApplicableVersions(tree) {
|
||||
// Now that the tree has been fully computed, we can for any node that
|
||||
// is a category page, re-set its `.applicableVersions` and `.permalinks`
|
||||
// based on the union set of all its immediate children's
|
||||
// `.applicableVersions`.
|
||||
for (const childPage of tree.childPages) {
|
||||
if (childPage.page.relativePath.endsWith('index.md')) {
|
||||
const combinedApplicableVersions = []
|
||||
let moreThanOneChild = false
|
||||
for (const childChildPage of childPage.childPages || []) {
|
||||
for (const version of childChildPage.page.applicableVersions) {
|
||||
if (!combinedApplicableVersions.includes(version)) {
|
||||
combinedApplicableVersions.push(version)
|
||||
}
|
||||
}
|
||||
setCategoryApplicableVersions(childPage)
|
||||
moreThanOneChild = true
|
||||
}
|
||||
if (
|
||||
// Some landing pages have no children at all.
|
||||
// For example the search/index.md page. With no children,
|
||||
// the combined applicableVersions would be [].
|
||||
moreThanOneChild &&
|
||||
!equalSets(
|
||||
new Set(childPage.page.applicableVersions),
|
||||
new Set(combinedApplicableVersions),
|
||||
) &&
|
||||
!childPage.page.relativePath.startsWith('early-access')
|
||||
) {
|
||||
const newPermalinks = Permalink.derive(
|
||||
childPage.page.languageCode,
|
||||
childPage.page.relativePath,
|
||||
childPage.page.title,
|
||||
combinedApplicableVersions,
|
||||
)
|
||||
childPage.page.permalinks = newPermalinks
|
||||
childPage.page.applicableVersions = combinedApplicableVersions
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function equalSets(setA, setB) {
|
||||
return setA.size === setB.size && [...setA].every((x) => setB.has(x))
|
||||
}
|
||||
|
||||
async function translateTree(dir, langObj, enTree) {
|
||||
const item = {}
|
||||
const enPage = enTree.page
|
||||
|
||||
@@ -23,7 +23,20 @@ export default async function findPage(
|
||||
|
||||
let page = req.context.pages[req.pagePath]
|
||||
if (page && isDev && englishPrefixRegex.test(req.pagePath)) {
|
||||
// The .applicableVersions and .permalinks properties are computed
|
||||
// when the page is read in from disk. But when the initial tree
|
||||
// was created at startup, the pages in the tree were mutated
|
||||
// based on their context. For example, a category page's versions
|
||||
// is based on looping through all its children's versions.
|
||||
const reuseOldVersions = page.relativePath.endsWith('index.md')
|
||||
const oldApplicableVersions = page.applicableVersions
|
||||
const oldPermalinks = page.permalinks
|
||||
|
||||
page = await rereadByPath(req.pagePath, contentRoot, req.context.currentVersion)
|
||||
if (reuseOldVersions) {
|
||||
page.applicableVersions = oldApplicableVersions
|
||||
page.permalinks = oldPermalinks
|
||||
}
|
||||
|
||||
// This can happen if the page we just re-read has changed which
|
||||
// versions it's available in (the `versions` frontmatter) meaning
|
||||
|
||||
@@ -578,7 +578,9 @@ async function processPermalink(core, permalink, page, pageMap, redirects, opts,
|
||||
try {
|
||||
html = await renderInnerHTML(page, permalink)
|
||||
} catch (error) {
|
||||
console.warn(`The error happened trying to render ${page.relativePath}`)
|
||||
console.warn(
|
||||
`The error happened trying to render ${page.relativePath} (permalink: ${permalink.href})`,
|
||||
)
|
||||
throw error
|
||||
}
|
||||
const $ = cheerio.load(html, { xmlMode: true })
|
||||
|
||||
Reference in New Issue
Block a user