Skip to content

Commit a5d990e

Browse files
committed
support multiple featured tracks with versioning in raw YML, but only one featured track per version after processing
1 parent 1acff02 commit a5d990e

3 files changed

Lines changed: 63 additions & 19 deletions

File tree

lib/process-learning-tracks.js

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ module.exports = async function processLearningTracks (rawLearningTracks, contex
99
let featuredTrack
1010

1111
for await (const rawTrackName of rawLearningTracks) {
12-
// Track names in frontmatter may include Liquid conditionals
12+
let isFeaturedTrack = false
13+
14+
// Track names in frontmatter may include Liquid conditionals.
1315
const renderedTrackName = await renderContent(rawTrackName, context, renderOpts)
1416
if (!renderedTrackName) continue
1517

18+
// Find the data for the current product and track name.
1619
const track = context.site.data['learning-tracks'][context.currentProduct][renderedTrackName]
1720
if (!track) continue
1821

@@ -25,15 +28,22 @@ module.exports = async function processLearningTracks (rawLearningTracks, contex
2528
guides: await getLinkData(track.guides, context)
2629
}
2730

31+
// Determine if this is the featured track.
2832
if (track.featured_track) {
29-
// Set the featured track, which is not included in the array of other learning tracks.
30-
featuredTrack = learningTrack
31-
} else {
32-
// Only add the track to the array of tracks if there are guides in this version.
33-
if (learningTrack.guides.length) {
34-
learningTracks.push(learningTrack)
33+
// Featured track properties may include Liquid conditionals with versioning, so we need to parse to
34+
// determine if the featured track is relevant for this version.
35+
const parsed = await renderContent(track.featured_track, context, renderOpts)
36+
if (parsed === 'true') {
37+
featuredTrack = learningTrack
38+
isFeaturedTrack = true
3539
}
3640
}
41+
42+
// Only add the track to the array of tracks if there are guides in this version
43+
// and it's not the featured track.
44+
if (learningTrack.guides.length && !isFeaturedTrack) {
45+
learningTracks.push(learningTrack)
46+
}
3747
}
3848

3949
return { featuredTrack, learningTracks }

tests/content/lint-files.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ const ghesReleaseNotesSchema = require('../helpers/schemas/release-notes-schema'
1414
const learningTracksSchema = require('../helpers/schemas/learning-tracks-schema')
1515
const renderContent = require('../../lib/render-content')
1616
const { execSync } = require('child_process')
17+
const allVersions = Object.keys(require('../../lib/all-versions'))
18+
const enterpriseServerVersions = allVersions.filter(v => v.startsWith('enterprise-server@'))
1719

1820
const rootDir = path.join(__dirname, '../..')
1921
const contentDir = path.join(rootDir, 'content')
@@ -723,8 +725,25 @@ describe('lint learning tracks', () => {
723725
expect(errors.length, errorMessage).toBe(0)
724726
})
725727

726-
it('has at least one featured track', () => {
727-
expect(Object.values(dictionary).filter(entry => entry.featured_track).length).toBe(1)
728+
it.only('has one and only one featured track per version', async () => {
729+
const featuredTracks = {}
730+
const context = { enterpriseServerVersions }
731+
732+
await Promise.all(allVersions.map(async (version) => {
733+
const featuredTracksPerVersion = (await Promise.all(Object.values(dictionary).map(async (entry) => {
734+
if (!entry.featured_track) return
735+
context.currentVersion = version
736+
return renderContent(entry.featured_track, context, { textOnly: true, encodeEntities: true })
737+
})))
738+
.filter(val => val === 'true')
739+
740+
featuredTracks[version] = featuredTracksPerVersion
741+
}))
742+
743+
Object.entries(featuredTracks).forEach(([version, arrayOfTracks]) => {
744+
const errorMessage = `Featured learning track not found for ${version} in ${yamlAbsPath}`
745+
expect(arrayOfTracks.length, errorMessage).toBe(1)
746+
})
728747
})
729748

730749
it('contains valid liquid', () => {

tests/unit/page.js

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const allVersions = require('../../lib/all-versions')
66
const enterpriseServerReleases = require('../../lib/enterprise-server-releases')
77
const nonEnterpriseDefaultVersion = require('../../lib/non-enterprise-default-version')
88
const { latest } = require('../../lib/enterprise-server-releases')
9+
const enterpriseServerVersions = Object.keys(allVersions).filter(v => v.startsWith('enterprise-server@'))
910

1011
const getLinkData = require('../../lib/get-link-data')
1112
jest.mock('../../lib/get-link-data')
@@ -168,7 +169,7 @@ describe('Page class', () => {
168169
const context = {
169170
currentVersion: `enterprise-server@${enterpriseServerReleases.latest}`,
170171
currentLanguage: 'en',
171-
enterpriseServerVersions: Object.keys(allVersions).filter(id => id.startsWith('enterprise-server@'))
172+
enterpriseServerVersions
172173
}
173174
let rendered = await page.render(context)
174175
let $ = cheerio.load(rendered)
@@ -353,19 +354,22 @@ describe('Page class', () => {
353354
currentLanguage: 'en',
354355
currentProduct: 'snowbird',
355356
currentVersion: nonEnterpriseDefaultVersion,
357+
enterpriseServerVersions,
356358
site: {
357359
data: {
358360
'learning-tracks': {
359361
snowbird: {
360362
track_1: {
361363
title: 'title',
362364
description: 'description',
363-
guides
365+
guides,
366+
featured_track: '{% if currentVersion == "free-pro-team@latest" %}true{% else %}false{% endif %}'
364367
},
365368
track_2: {
366369
title: 'title',
367370
description: 'description',
368-
guides
371+
guides,
372+
featured_track: '{% if enterpriseServerVersions contains currentVersion %}true{% else %}false{% endif %}'
369373
},
370374
dotcom_only_track: {
371375
title: 'title',
@@ -382,19 +386,30 @@ describe('Page class', () => {
382386
}
383387
}
384388
}
389+
// Test that Liquid versioning is respected during rendering.
390+
// Start with Dotcom.
385391
await page.render(context)
386392
// To actually render the guides in this test, we would have to load context.pages and context.redirects;
387393
// To avoid that we can just test that the function was called with the expected data.
388394
expect(getLinkData).toHaveBeenCalledWith(guides, context)
389-
expect(page.learningTracks).toHaveLength(3)
390-
expect(page.learningTracks.find(track => track.trackName === 'dotcom_only_track')).toBeTruthy()
391-
392-
// Test that Liquid versioning is respected
395+
// Tracks for dotcom should exclude enterprise_only_track and the featured track_1.
396+
expect(page.learningTracks).toHaveLength(2)
397+
const dotcomTrackNames = page.learningTracks.map(t => t.trackName)
398+
expect(dotcomTrackNames.includes('track_2')).toBe(true)
399+
expect(dotcomTrackNames.includes('dotcom_only_track')).toBe(true)
400+
expect(page.featuredTrack.trackName === 'track_1').toBeTruthy()
401+
expect(page.featuredTrack.trackName === 'track_2').toBeFalsy()
402+
403+
// Switch to Enterprise.
393404
context.currentVersion = `enterprise-server@${latest}`
394405
await page.render(context)
395-
expect(page.learningTracks).toHaveLength(3)
396-
expect(page.learningTracks.find(track => track.trackName === 'dotcom_only_track')).toBeFalsy()
397-
expect(page.learningTracks.find(track => track.trackName === 'enterprise_only_track')).toBeTruthy()
406+
// Tracks for enterprise should exclude dotcom_only_track and the featured track_2.
407+
expect(page.learningTracks).toHaveLength(2)
408+
const ghesTrackNames = page.learningTracks.map(t => t.trackName)
409+
expect(ghesTrackNames.includes('track_1')).toBe(true)
410+
expect(ghesTrackNames.includes('enterprise_only_track')).toBe(true)
411+
expect(page.featuredTrack.trackName === 'track_1').toBeFalsy()
412+
expect(page.featuredTrack.trackName === 'track_2').toBeTruthy()
398413
})
399414
})
400415

0 commit comments

Comments
 (0)