Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gatsby-plugin-page-creator): update pages when nodes change #36623

Merged
merged 15 commits into from
Sep 21, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,51 @@
describe(`collection-routing`, () => {
beforeEach(() => {
cy.visit(`/collection-routing`).waitForRouteChange()
const prefixes = [``, `child-`, `computed-`, `child-computed-`]

function assert404(slug) {
for (const prefix of prefixes) {
cy.visit(`/collection-routing/mutations/${prefix}${slug}/`, {
failOnStatusCode: false,
}).waitForRouteChange()

// page doesn't exist yet
cy.get(`h1`).invoke(`text`).should(`eq`, `Gatsby.js development 404 page`)
}
}

function assertPageExist(slug, content) {
for (const prefix of prefixes) {
cy.visit(
`/collection-routing/mutations/${prefix}${slug}/`
).waitForRouteChange()
cy.contains(content)
}
}

function refresh(setup) {
cy.then(() => {
return fetch(
`http://localhost:8000/__refresh/gatsby-source-fs-route-mutations`,
{
method: `POST`,
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ setup }),
}
)
})

cy.wait(5000)
}

describe(`collection-routing`, () => {
it(`can create simplest collection route that also has a number as an identifier`, () => {
cy.visit(`/collection-routing/1/`).waitForRouteChange()
cy.findByTestId(`slug`).should(`have.text`, `/preview/1`)
cy.findByTestId(`pagecontext`).should(`have.text`, `1`)
})

it(`can navigate to a collection route and see its content rendered`, () => {
cy.visit(`/collection-routing`).waitForRouteChange()
// this test depends on the alphabetical sorting of markdown files
cy.findByTestId(`collection-routing-blog-0`)
.should(`have.attr`, `data-testslug`, `/2018-12-14-hello-world/`)
Expand All @@ -24,6 +60,7 @@ describe(`collection-routing`, () => {
})

it(`can navigate to a collection route that uses unions and see its content rendered`, () => {
cy.visit(`/collection-routing`).waitForRouteChange()
// this test depends on the alphabetical sorting of image files
cy.findByTestId(`collection-routing-image-0`)
.should(`have.attr`, `data-testimagename`, `citrus-fruits`)
Expand Down Expand Up @@ -61,4 +98,49 @@ describe(`collection-routing`, () => {
cy.findByTestId(`title`)
cy.should(`have.text`, `Named SPLAT Nested with Collection Route!`)
})

describe(`data updates`, () => {
before(() => {
refresh(`reset`)
})
after(() => {
refresh(`reset`)
})

it(`creates a page when new node is created`, () => {
assert404(`new-node`)
assert404(`updated-node`)

refresh(`create`)

assertPageExist(`new-node`, `This is node that was just created`)
assert404(`updated-node`)
})

it(`remove previous page and add a new one when slug changes`, () => {
assertPageExist(`new-node`, `This is node that was just created`)
assert404(`updated-node`)

refresh(`update`)

assertPageExist(
`updated-node`,
`This is node that had slug and content updated`
)
assert404(`new-node`)
})

it(`remove a page when node is deleted`, () => {
assertPageExist(
`updated-node`,
`This is node that had slug and content updated`
)
assert404(`new-node`)

refresh(`delete`)

assert404(`new-node`)
assert404(`updated-node`)
})
})
})
1 change: 1 addition & 0 deletions e2e-tests/development-runtime/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module.exports = {
`gatsby-source-fake-data`,
`gatsby-source-pinc-data`,
`gatsby-source-query-on-demand-data`,
`gatsby-source-fs-route-mutations`,
`gatsby-browser-tsx`,
`gatsby-node-typegen`,
`gatsby-transformer-sharp`,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { GatsbyNode } from "gatsby"

let createdNodes = new Set<string>()

export const sourceNodes: GatsbyNode["sourceNodes"] = ({
actions,
webhookBody,
getNode,
createContentDigest,
reporter,
}) => {
const handledNodes = new Set(createdNodes)
function addNode(data: { id: string; slug: string; content: string }): void {
const node = {
...data,
parent: null,
children: [],
internal: {
type: `FilesystemRoutesMutation`,
contentDigest: createContentDigest(data),
},
}

createdNodes.add(node.id)
handledNodes.delete(node.id)

actions.createNode(node)

const childNode = {
...data,
id: `${node.id} << childNode`,
parent: node.id,
internal: {
type: `FilesystemRoutesMutationChild`,
contentDigest: node.internal.contentDigest,
},
}
actions.createNode(childNode)
const parent = getNode(node.id)

if (!parent) {
throw new Error(`Could not find parent node`)
}

actions.createParentChildLink({
parent: parent,
child: childNode,
})
}

if (webhookBody?.setup === `create`) {
reporter.verbose(`[gatsby-source-fs-route-mutation] create a new node`)
addNode({
id: `fs-route-mutation-test`,
slug: `new-node`,
content: `This is node that was just created`,
})
} else if (webhookBody?.setup === `update`) {
reporter.verbose(`[gatsby-source-fs-route-mutation] update a node`)
addNode({
id: `fs-route-mutation-test`,
slug: `updated-node`,
content: `This is node that had slug and content updated`,
})
} else if (webhookBody?.setup === `delete`) {
reporter.verbose(`[gatsby-source-fs-route-mutation] delete a node`)
} else {
reporter.verbose(`[gatsby-source-fs-route-mutation] initial setup`)
}

addNode({
id: `fs-route-mutation-stable`,
slug: `stable`,
content: `This is stable node`,
})

for (const nodeIdToDelete of handledNodes) {
const nodeToDelete = getNode(nodeIdToDelete)
if (nodeToDelete) {
createdNodes.delete(nodeIdToDelete)
actions.deleteNode(nodeToDelete)
}
}
}

export const createResolvers: GatsbyNode["createResolvers"] = ({
createResolvers,
}) => {
createResolvers({
FilesystemRoutesMutation: {
computed: {
type: `String`,
resolve(source: { slug?: string }): string {
return `computed-${source.slug}`
},
},
},
FilesystemRoutesMutationChild: {
computed: {
type: `String`,
resolve(source: { slug?: string }): string {
return `computed-${source.slug}`
},
},
},
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// noop
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from "react"
import { graphql } from "gatsby"

export default function FSRoutesMutationTemplate({ data }) {
return (
<>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}

export const query = graphql`
query($id: String!) {
filesystemRoutesMutationChild(id: { eq: $id }) {
content
}
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from "react"
import { graphql } from "gatsby"

export default function FSRoutesMutationTemplate({ data }) {
return (
<>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}

export const query = graphql`
query($id: String!) {
filesystemRoutesMutationChild(id: { eq: $id }) {
content
}
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from "react"
import { graphql } from "gatsby"

export default function FSRoutesMutationTemplate({ data }) {
return (
<>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}

export const query = graphql`
query($id: String!) {
filesystemRoutesMutation(id: { eq: $id }) {
content
}
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from "react"
import { graphql } from "gatsby"

export default function FSRoutesMutationTemplate({ data }) {
return (
<>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}

export const query = graphql`
query($id: String!) {
filesystemRoutesMutation(id: { eq: $id }) {
content
}
}
`
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { CODES, prefixId } from "./error-utils"
// This Function opens up the actual collection file and extracts the queryString used in the
export function collectionExtractQueryString(
absolutePath: string,
reporter: Reporter
reporter: Reporter,
nodeIds?: Array<string>
): string | null {
let queryString: string | null = null

Expand Down Expand Up @@ -38,7 +39,7 @@ export function collectionExtractQueryString(

// 3 This is important, we get the model or query, but we have to create a real graphql
// query from it. This generateQueryFromString call does all of that magic
queryString = generateQueryFromString(modelType, absolutePath)
queryString = generateQueryFromString(modelType, absolutePath, nodeIds)

return queryString
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export function createPage(
graphql: CreatePagesArgs["graphql"],
reporter: Reporter,
trailingSlash: TrailingSlash,
pagesPath: string,
ignore?: IPathIgnoreOptions | string | Array<string> | null,
slugifyOptions?: ISlugifyOptions
): void {
Expand All @@ -48,15 +49,16 @@ export function createPage(
// If the page includes a `{}` in it, then we create it as a collection builder
if (pathIsCollectionBuilder(absolutePath)) {
trackFeatureIsUsed(`UnifiedRoutes:collection-page-builder`)
createPagesFromCollectionBuilder(
createPagesFromCollectionBuilder({
filePath,
absolutePath,
pagesPath,
actions,
graphql,
reporter,
trailingSlash,
slugifyOptions
)
slugifyOptions,
})
return
}

Expand Down
Loading