Skip to content

Commit 3380c59

Browse files
gatsbybotpieh
andauthoredDec 4, 2023
fix(gatsby-source-contentful): don't apply parent node links to child nodes (#38728) (#38730)
* test: add test case asserting child nodes don't 'inherit' parent's links * fix(gatsby-source-contentful): don't apply parent node links to child nodes (cherry picked from commit be36b4a) Co-authored-by: Michal Piechowiak <misiek.piechowiak@gmail.com>
1 parent 4d78fba commit 3380c59

File tree

3 files changed

+407
-3
lines changed

3 files changed

+407
-3
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
exports.contentTypeItems = () => [
2+
{
3+
sys: {
4+
space: {
5+
sys: {
6+
type: `Link`,
7+
linkType: `Space`,
8+
id: `8itggr1zebzx`,
9+
},
10+
},
11+
id: `blogPost`,
12+
type: `ContentType`,
13+
createdAt: `2023-01-11T14:52:56.250Z`,
14+
updatedAt: `2023-01-11T14:54:56.940Z`,
15+
environment: {
16+
sys: {
17+
id: `master`,
18+
type: `Link`,
19+
linkType: `Environment`,
20+
},
21+
},
22+
revision: 4,
23+
},
24+
displayField: `title`,
25+
name: `Blog Post`,
26+
description: ``,
27+
fields: [
28+
{
29+
id: `title`,
30+
name: `Title`,
31+
type: `Symbol`,
32+
localized: false,
33+
required: true,
34+
disabled: false,
35+
omitted: false,
36+
},
37+
{
38+
id: `slug`,
39+
name: `Slug`,
40+
type: `Symbol`,
41+
localized: false,
42+
required: true,
43+
disabled: false,
44+
omitted: false,
45+
},
46+
{
47+
id: `category`,
48+
name: `Category`,
49+
type: `Link`,
50+
localized: false,
51+
required: false,
52+
disabled: false,
53+
omitted: false,
54+
linkType: `Entry`,
55+
validations: [
56+
{
57+
linkContentType: [`blogCategory`],
58+
},
59+
],
60+
},
61+
],
62+
},
63+
{
64+
sys: {
65+
space: {
66+
sys: {
67+
type: `Link`,
68+
linkType: `Space`,
69+
id: `8itggr1zebzx`,
70+
},
71+
},
72+
id: `blogCategory`,
73+
type: `ContentType`,
74+
createdAt: `2023-01-11T14:54:22.680Z`,
75+
updatedAt: `2023-01-11T14:54:22.680Z`,
76+
environment: {
77+
sys: {
78+
id: `master`,
79+
type: `Link`,
80+
linkType: `Environment`,
81+
},
82+
},
83+
revision: 1,
84+
},
85+
displayField: `title`,
86+
name: `Blog Category`,
87+
description: ``,
88+
fields: [
89+
{
90+
id: `title`,
91+
name: `Title`,
92+
type: `Symbol`,
93+
localized: false,
94+
required: true,
95+
disabled: false,
96+
omitted: false,
97+
},
98+
{
99+
id: `slug`,
100+
name: `Slug`,
101+
type: `Symbol`,
102+
localized: false,
103+
required: true,
104+
disabled: false,
105+
omitted: false,
106+
},
107+
{
108+
id: `body`,
109+
name: `Body`,
110+
type: `Text`,
111+
localized: false,
112+
required: true,
113+
disabled: false,
114+
omitted: false,
115+
},
116+
],
117+
},
118+
]
119+
120+
exports.initialSync = () => {
121+
return {
122+
currentSyncData: {
123+
entries: [
124+
{
125+
metadata: {
126+
tags: [],
127+
},
128+
sys: {
129+
space: {
130+
sys: {
131+
type: `Link`,
132+
linkType: `Space`,
133+
id: `8itggr1zebzx`,
134+
},
135+
},
136+
id: `3jXBlUgXmubzPI3I6d9hLr`,
137+
type: `Entry`,
138+
createdAt: `2023-01-11T14:56:37.418Z`,
139+
updatedAt: `2023-01-11T15:04:37.640Z`,
140+
environment: {
141+
sys: {
142+
id: `master`,
143+
type: `Link`,
144+
linkType: `Environment`,
145+
},
146+
},
147+
revision: 3,
148+
contentType: {
149+
sys: {
150+
type: `Link`,
151+
linkType: `ContentType`,
152+
id: `blogCategory`,
153+
},
154+
},
155+
},
156+
fields: {
157+
title: {
158+
"en-US": `CMS`,
159+
},
160+
slug: {
161+
"en-US": `cms`,
162+
},
163+
body: {
164+
"en-US": `cms`,
165+
},
166+
},
167+
},
168+
{
169+
metadata: {
170+
tags: [],
171+
},
172+
sys: {
173+
space: {
174+
sys: {
175+
type: `Link`,
176+
linkType: `Space`,
177+
id: `8itggr1zebzx`,
178+
},
179+
},
180+
id: `3oTFYoNKoVZcp8svbn8P2z`,
181+
type: `Entry`,
182+
createdAt: `2023-01-11T14:56:42.655Z`,
183+
updatedAt: `2023-01-11T14:56:42.655Z`,
184+
environment: {
185+
sys: {
186+
id: `master`,
187+
type: `Link`,
188+
linkType: `Environment`,
189+
},
190+
},
191+
revision: 1,
192+
contentType: {
193+
sys: {
194+
type: `Link`,
195+
linkType: `ContentType`,
196+
id: `blogPost`,
197+
},
198+
},
199+
},
200+
fields: {
201+
title: {
202+
"en-US": `Hello World`,
203+
},
204+
slug: {
205+
"en-US": `hello-world`,
206+
},
207+
},
208+
},
209+
],
210+
assets: [],
211+
deletedEntries: [],
212+
deletedAssets: [],
213+
nextSyncToken: `dDFSNcK6bMO7woHDuMK7A8O_KWQDPkhAwpF6w7ovw49fQjrDj2gKH0xvwofCkMKDJcKgBMKCYcK9wr3DoVozwqEUC8OwWlVJBBt-F8K0BMKTP8OAwr8Xw6bCkcO2w6MpwqBmVX7CmsOwM3DDvWZvw5Q`,
214+
},
215+
tagItems: [],
216+
defaultLocale: `en-US`,
217+
locales: [
218+
{
219+
code: `en-US`,
220+
name: `English (United States)`,
221+
default: true,
222+
fallbackCode: null,
223+
sys: {
224+
id: `2jpGtQkqT01zpSIqC9UQOS`,
225+
type: `Locale`,
226+
version: 1,
227+
},
228+
},
229+
],
230+
space: {
231+
sys: {
232+
type: `Space`,
233+
id: `8itggr1zebzx`,
234+
},
235+
name: `test`,
236+
locales: [
237+
{
238+
code: `en-US`,
239+
default: true,
240+
name: `English (United States)`,
241+
fallbackCode: null,
242+
},
243+
],
244+
},
245+
}
246+
}
247+
248+
exports.addALink = () => {
249+
return {
250+
currentSyncData: {
251+
entries: [
252+
{
253+
metadata: {
254+
tags: [],
255+
},
256+
sys: {
257+
space: {
258+
sys: {
259+
type: `Link`,
260+
linkType: `Space`,
261+
id: `8itggr1zebzx`,
262+
},
263+
},
264+
id: `3oTFYoNKoVZcp8svbn8P2z`,
265+
type: `Entry`,
266+
createdAt: `2023-01-11T14:56:42.655Z`,
267+
updatedAt: `2023-01-11T14:56:42.655Z`,
268+
environment: {
269+
sys: {
270+
id: `master`,
271+
type: `Link`,
272+
linkType: `Environment`,
273+
},
274+
},
275+
revision: 1,
276+
contentType: {
277+
sys: {
278+
type: `Link`,
279+
linkType: `ContentType`,
280+
id: `blogPost`,
281+
},
282+
},
283+
},
284+
fields: {
285+
title: {
286+
"en-US": `Hello World`,
287+
},
288+
slug: {
289+
"en-US": `hello-world`,
290+
},
291+
category: {
292+
"en-US": {
293+
sys: {
294+
type: `Link`,
295+
linkType: `Entry`,
296+
id: `3jXBlUgXmubzPI3I6d9hLr`,
297+
},
298+
},
299+
},
300+
},
301+
},
302+
],
303+
assets: [],
304+
deletedEntries: [],
305+
deletedAssets: [],
306+
nextSyncToken: `dDFSNcK6bMO7woHDuMK7A8O_KWQDPkhAwpF6w7ovw49fQjrDj2gKH0xvQMODwpLDkMK3Oj9Jw6jDkSoBMkc4woTCtMOFwoTDisKlT8O1w4AaKsOjasK1wrVSwrU3YsKVE8KPVMKyw4_CmVpwPsOew4IVwoA`,
307+
},
308+
tagItems: [],
309+
defaultLocale: `en-US`,
310+
locales: [
311+
{
312+
code: `en-US`,
313+
name: `English (United States)`,
314+
default: true,
315+
fallbackCode: null,
316+
sys: {
317+
id: `2jpGtQkqT01zpSIqC9UQOS`,
318+
type: `Locale`,
319+
version: 1,
320+
},
321+
},
322+
],
323+
space: {
324+
sys: {
325+
type: `Space`,
326+
id: `8itggr1zebzx`,
327+
},
328+
name: `test`,
329+
locales: [
330+
{
331+
code: `en-US`,
332+
default: true,
333+
name: `English (United States)`,
334+
fallbackCode: null,
335+
},
336+
],
337+
},
338+
}
339+
}

‎packages/gatsby-source-contentful/src/__tests__/gatsby-node.js

+65
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import restrictedContentTypeFixture from "../__fixtures__/restricted-content-typ
1616
import unpublishedFieldDelivery from "../__fixtures__/unpublished-fields-delivery"
1717
import unpublishedFieldPreview from "../__fixtures__/unpublished-fields-preview"
1818
import preserveBackLinks from "../__fixtures__/preserve-back-links"
19+
import editingNodeReferecingNodeWithChildLink from "../__fixtures__/editing-node-referencing-nodes-with-child-links"
1920

2021
jest.mock(`../fetch`)
2122
jest.mock(`gatsby-core-utils`, () => {
@@ -1422,4 +1423,68 @@ describe(`gatsby-node`, () => {
14221423
])
14231424
expect(blogCategoryNodes[0][`title`]).toEqual(`CMS edit #1`)
14241425
})
1426+
1427+
it(`should not apply parent node links to child nodes`, async () => {
1428+
// @ts-ignore
1429+
fetchContentTypes.mockImplementation(
1430+
editingNodeReferecingNodeWithChildLink.contentTypeItems
1431+
)
1432+
fetchContent
1433+
// @ts-ignore
1434+
.mockImplementationOnce(
1435+
editingNodeReferecingNodeWithChildLink.initialSync
1436+
)
1437+
.mockImplementationOnce(editingNodeReferecingNodeWithChildLink.addALink)
1438+
1439+
let blogPostNodes
1440+
let blogCategoryNodes
1441+
let blogCategoryChildNodes
1442+
await simulateGatsbyBuild()
1443+
1444+
blogPostNodes = getNodes().filter(
1445+
node => node.internal.type === `ContentfulBlogPost`
1446+
)
1447+
blogCategoryNodes = getNodes().filter(
1448+
node => node.internal.type === `ContentfulBlogCategory`
1449+
)
1450+
blogCategoryChildNodes = blogCategoryNodes.flatMap(node =>
1451+
node.children.map(childId => getNode(childId))
1452+
)
1453+
1454+
expect(blogPostNodes.length).toEqual(1)
1455+
expect(blogCategoryNodes.length).toEqual(1)
1456+
expect(blogCategoryChildNodes.length).toEqual(1)
1457+
// no backref yet
1458+
expect(blogCategoryNodes[0][`blog post___NODE`]).toBeUndefined()
1459+
expect(blogCategoryNodes[0][`title`]).toEqual(`CMS`)
1460+
1461+
// `body` field on child node is concrete value and not a link
1462+
expect(blogCategoryChildNodes[0][`body`]).toEqual(`cms`)
1463+
expect(blogCategoryChildNodes[0][`body___NODE`]).toBeUndefined()
1464+
1465+
await simulateGatsbyBuild()
1466+
1467+
blogPostNodes = getNodes().filter(
1468+
node => node.internal.type === `ContentfulBlogPost`
1469+
)
1470+
blogCategoryNodes = getNodes().filter(
1471+
node => node.internal.type === `ContentfulBlogCategory`
1472+
)
1473+
blogCategoryChildNodes = blogCategoryNodes.flatMap(node =>
1474+
node.children.map(childId => getNode(childId))
1475+
)
1476+
1477+
expect(blogPostNodes.length).toEqual(1)
1478+
expect(blogCategoryNodes.length).toEqual(1)
1479+
expect(blogCategoryChildNodes.length).toEqual(1)
1480+
// backref was added when entries were linked
1481+
expect(blogCategoryNodes[0][`blog post___NODE`]).toEqual([
1482+
blogPostNodes[0].id,
1483+
])
1484+
expect(blogCategoryNodes[0][`title`]).toEqual(`CMS`)
1485+
1486+
// `body` field on child node is concrete value and not a link
1487+
expect(blogCategoryChildNodes[0][`body`]).toEqual(`cms`)
1488+
expect(blogCategoryChildNodes[0][`body___NODE`]).toBeUndefined()
1489+
})
14251490
})

‎packages/gatsby-source-contentful/src/source-nodes.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -463,13 +463,13 @@ export async function sourceNodes(
463463

464464
// memory cached nodes are mutated during back reference checks
465465
// so we need to carry over the changes to the updated node
466-
if (node.__memcache) {
467-
for (const key of Object.keys(node)) {
466+
if (nodeToUpdateOriginal.__memcache) {
467+
for (const key of Object.keys(nodeToUpdateOriginal)) {
468468
if (!key.endsWith(`___NODE`)) {
469469
continue
470470
}
471471

472-
newNode[key] = node[key]
472+
newNode[key] = nodeToUpdateOriginal[key]
473473
}
474474
}
475475

0 commit comments

Comments
 (0)
Please sign in to comment.