Skip to content

Commit a4e750c

Browse files
authored
fix changelog heading slugs (#58455)
1 parent 32c1990 commit a4e750c

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

src/graphql/components/Changelog.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react'
22
import cx from 'classnames'
3+
import GithubSlugger from 'github-slugger'
34

45
import { HeadingLink } from '@/frame/components/article/HeadingLink'
56
import { ChangelogItemT } from './types'
@@ -10,14 +11,19 @@ type Props = {
1011
}
1112

1213
export function Changelog({ changelogItems }: Props) {
13-
const changes = changelogItems.map((item) => {
14+
const slugger = new GithubSlugger()
15+
16+
const changes = changelogItems.map((item, index) => {
1417
const heading = `Schema changes for ${item.date}`
18+
const slug = slugger.slug(heading)
1519

1620
return (
17-
<div key={item.date}>
18-
<HeadingLink as="h2">{heading}</HeadingLink>
19-
{(item.schemaChanges || []).map((change, index) => (
20-
<React.Fragment key={index}>
21+
<div key={`${item.date}-${index}`}>
22+
<HeadingLink as="h2" slug={slug}>
23+
{heading}
24+
</HeadingLink>
25+
{(item.schemaChanges || []).map((change, changeIndex) => (
26+
<React.Fragment key={changeIndex}>
2127
<p>{change.title}</p>
2228
<ul>
2329
{change.changes.map((changeItem) => (
@@ -26,8 +32,8 @@ export function Changelog({ changelogItems }: Props) {
2632
</ul>
2733
</React.Fragment>
2834
))}
29-
{(item.previewChanges || []).map((change, index) => (
30-
<React.Fragment key={index}>
35+
{(item.previewChanges || []).map((change, changeIndex) => (
36+
<React.Fragment key={changeIndex}>
3137
<p>{change.title}</p>
3238
<ul>
3339
{change.changes.map((changeItem) => (
@@ -36,8 +42,8 @@ export function Changelog({ changelogItems }: Props) {
3642
</ul>
3743
</React.Fragment>
3844
))}
39-
{(item.upcomingChanges || []).map((change, index) => (
40-
<React.Fragment key={index}>
45+
{(item.upcomingChanges || []).map((change, changeIndex) => (
46+
<React.Fragment key={changeIndex}>
4147
<p>{change.title}</p>
4248
{change.changes.map((changeItem) => (
4349
<li key={changeItem} dangerouslySetInnerHTML={{ __html: changeItem }} />

src/graphql/tests/server-rendering.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@ describe('server rendering certain GraphQL pages', () => {
2323
expect.assertions(hrefs.length + 1)
2424
})
2525

26+
test('minitoc hrefs on changelog match and verify slugger behavior', async () => {
27+
// Testing the minitoc links match the heading ids but also validating
28+
// slugger behavior see docs-engineering/issues#5792.
29+
// Little funky because we need to make 2 requests to the page to test
30+
// the problem behavior where slugger state accumulates across
31+
// requests, it won't fail the first time around.
32+
await getDOM('/graphql/overview/changelog')
33+
const $ = await getDOM('/graphql/overview/changelog')
34+
const links = $('[data-testid="minitoc"] a[href]')
35+
const hrefs = links.map((i, link) => $(link).attr('href')).get()
36+
const headings = $('#article-contents h2')
37+
const headingIds = headings.map((i, heading) => `#${$(heading).attr('id')}`).get()
38+
39+
expect(hrefs.length).toBe(headingIds.length)
40+
41+
for (let i = 0; i < hrefs.length; i++) {
42+
expect(hrefs[i]).toBe(headingIds[i])
43+
}
44+
})
45+
2646
const autogeneratedPages = pageList.filter(
2747
(page) => page.autogenerated === 'graphql' && page.relativePath.includes('reference'),
2848
)

0 commit comments

Comments
 (0)