From 30e22a1d2a91d17c2f5a7d3e253e18d3cb4d14e5 Mon Sep 17 00:00:00 2001 From: Jude Agboola Date: Fri, 30 Sep 2022 11:28:30 +0100 Subject: [PATCH 01/12] initial --- .../slices/slice-via-create-page.js | 25 ++++++++++ .../cypress/integration/slices/slices.js | 33 +++++++++++++ e2e-tests/development-runtime/gatsby-node.js | 47 +++++++++++++++++-- e2e-tests/development-runtime/package.json | 2 +- .../development-runtime/shared-data/slices.js | 25 ++++++++++ .../src/components/footer.js | 23 +++++++++ .../src/components/layout.js | 8 +++- .../src/components/recipe-author.js | 15 ++++++ .../src/context-for-slices.js | 25 ++++++++++ .../src/templates/recipe.js | 15 ++++++ .../src/wrap-root-element.js | 5 +- .../slices/slice-via-create-page.js | 25 ++++++++++ .../cypress/integration/slices/slices.js | 33 +++++++++++++ e2e-tests/production-runtime/gatsby-node.ts | 10 +++- e2e-tests/production-runtime/package.json | 2 +- .../production-runtime/shared-data/slices.js | 25 ++++++++++ .../src/components/footer.js | 23 +++++++++ .../src/components/layout.js | 6 ++- .../src/components/recipe-author.js | 15 ++++++ .../src/context-for-slices.js | 25 ++++++++++ .../src/templates/recipe.js | 15 ++++++ .../src/wrap-root-element.js | 5 +- 22 files changed, 394 insertions(+), 13 deletions(-) create mode 100644 e2e-tests/development-runtime/cypress/integration/slices/slice-via-create-page.js create mode 100644 e2e-tests/development-runtime/cypress/integration/slices/slices.js create mode 100644 e2e-tests/development-runtime/shared-data/slices.js create mode 100644 e2e-tests/development-runtime/src/components/footer.js create mode 100644 e2e-tests/development-runtime/src/components/recipe-author.js create mode 100644 e2e-tests/development-runtime/src/context-for-slices.js create mode 100644 e2e-tests/development-runtime/src/templates/recipe.js create mode 100644 e2e-tests/production-runtime/cypress/integration/slices/slice-via-create-page.js create mode 100644 e2e-tests/production-runtime/cypress/integration/slices/slices.js create mode 100644 e2e-tests/production-runtime/shared-data/slices.js create mode 100644 e2e-tests/production-runtime/src/components/footer.js create mode 100644 e2e-tests/production-runtime/src/components/recipe-author.js create mode 100644 e2e-tests/production-runtime/src/context-for-slices.js create mode 100644 e2e-tests/production-runtime/src/templates/recipe.js diff --git a/e2e-tests/development-runtime/cypress/integration/slices/slice-via-create-page.js b/e2e-tests/development-runtime/cypress/integration/slices/slice-via-create-page.js new file mode 100644 index 0000000000000..3e0b4cd6cecb5 --- /dev/null +++ b/e2e-tests/development-runtime/cypress/integration/slices/slice-via-create-page.js @@ -0,0 +1,25 @@ +import { allRecipes, allRecipeAuthors } from "../../../shared-data/slices" + +/** + * Test behaviour when a slice is created and passed `slices` option to createPage + */ + +describe("Slice passed via createPage", () => { + it("Pages created with slices mapping have correct content", () => { + allRecipes.forEach(recipe => { + cy.visit(`recipe/${recipe.id}`).waitForRouteChange() + + cy.getTestElement(`recipe-name`) + .invoke(`text`) + .should(`contain`, recipe.name) + + cy.getTestElement(`recipe-description`) + .invoke(`text`) + .should(`contain`, recipe.description) + + cy.getTestElement(`recipe-author-name`) + .invoke(`text`) + .should(`contain`, allRecipeAuthors.find(author => recipe.authorId === author.id).name) + }) + }) +}) diff --git a/e2e-tests/development-runtime/cypress/integration/slices/slices.js b/e2e-tests/development-runtime/cypress/integration/slices/slices.js new file mode 100644 index 0000000000000..5e2ec4156b110 --- /dev/null +++ b/e2e-tests/development-runtime/cypress/integration/slices/slices.js @@ -0,0 +1,33 @@ +/** + * Test basic Slices API behaviour like context, props, .... + */ + +describe(`Slices`, () => { + beforeEach(() => { + cy.visit(`/`).waitForRouteChange() + }) + + it(`Slice content show on screen`, () => { + cy.getTestElement(`footer-static-text`) + .invoke(`text`) + .should(`contain`, `Built with`) + }) + + it(`Slice recieves context passed via createSlice`, () => { + cy.getTestElement(`footer-slice-context-value`) + .invoke(`text`) + .should(`contain`, `Gatsby`) + }) + + it(`Slice can take in props`, () => { + cy.getTestElement(`footer-props`) + .invoke(`text`) + .should(`contains`, `Gatsbyjs`) + }) + + it(`Slice can consume a context wrapped in WrapRootElement`, () => { + cy.getTestElement(`footer-context-derieved-value`) + .invoke(`text`) + .should(`contain`, `2`) + }) +}) diff --git a/e2e-tests/development-runtime/gatsby-node.js b/e2e-tests/development-runtime/gatsby-node.js index df74a650d67d9..e6cc2dbc5dbf8 100644 --- a/e2e-tests/development-runtime/gatsby-node.js +++ b/e2e-tests/development-runtime/gatsby-node.js @@ -1,6 +1,7 @@ const path = require(`path`) const { createFilePath } = require(`gatsby-source-filesystem`) const headFunctionExportSharedData = require("./shared-data/head-function-export") +const slicesData = require("./shared-data/slices") const { addRemoteFilePolyfillInterface, polyfillImageServiceDevRoutes, @@ -37,7 +38,8 @@ exports.sourceNodes = ({ actions, createNodeId, createContentDigest }) => { const items = [ { name: "photoA.jpg", - url: "https://images.unsplash.com/photo-1517849845537-4d257902454a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2000&q=80", + url: + "https://images.unsplash.com/photo-1517849845537-4d257902454a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2000&q=80", placeholderUrl: "https://images.unsplash.com/photo-1517849845537-4d257902454a?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=%width%&h=%height%", mimeType: "image/jpg", @@ -47,7 +49,8 @@ exports.sourceNodes = ({ actions, createNodeId, createContentDigest }) => { }, { name: "photoB.jpg", - url: "https://images.unsplash.com/photo-1552053831-71594a27632d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&h=2000&q=10", + url: + "https://images.unsplash.com/photo-1552053831-71594a27632d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&h=2000&q=10", mimeType: "image/jpg", filename: "photo-1552053831.jpg", width: 1247, @@ -55,7 +58,8 @@ exports.sourceNodes = ({ actions, createNodeId, createContentDigest }) => { }, { name: "photoC.jpg", - url: "https://images.unsplash.com/photo-1561037404-61cd46aa615b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2000&q=80", + url: + "https://images.unsplash.com/photo-1561037404-61cd46aa615b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2000&q=80", placeholderUrl: "https://images.unsplash.com/photo-1561037404-61cd46aa615b?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=%width%&h=%height%", mimeType: "image/jpg", @@ -122,7 +126,7 @@ exports.onCreateNode = function onCreateNode({ * @type {import('gatsby').createPages} */ exports.createPages = async function createPages({ - actions: { createPage, createRedirect }, + actions: { createPage, createRedirect, createSlice }, graphql, }) { const { data } = await graphql(` @@ -172,6 +176,41 @@ exports.createPages = async function createPages({ }) }) + //-------------------------Slice API---------------------------- + createSlice({ + id: `footer`, + component: path.resolve(`./src/components/footer.js`), + context: { + framework: slicesData.framework, + }, + }) + + slicesData.allRecipeAuthors.forEach(({ id, name }) => { + createSlice({ + id: `author-${id}`, + component: path.resolve(`./src/components/recipe-author.js`), + context: { + name, + id, + }, + }) + }) + + slicesData.allRecipes.forEach(({ authorId, id, name, description }) => { + createPage({ + path: `/recipe/${id}`, + component: path.resolve(`./src/templates/recipe.js`), + context: { + description: description, + name, + }, + slices: { + author: `author-${authorId}`, + }, + }) + }) + //--------------------------------------------------------------- + createPage({ path: `/안녕`, component: path.resolve(`src/pages/page-2.js`), diff --git a/e2e-tests/development-runtime/package.json b/e2e-tests/development-runtime/package.json index 64ec2ab4eb89e..d3e20fa0ee709 100644 --- a/e2e-tests/development-runtime/package.json +++ b/e2e-tests/development-runtime/package.json @@ -5,7 +5,7 @@ "author": "Dustin Schau ", "dependencies": { "babel-plugin-search-and-replace": "^1.1.0", - "gatsby": "next", + "gatsby": "^4.23.0-alpha-preview-slices.78", "gatsby-image": "next", "gatsby-plugin-image": "next", "gatsby-plugin-less": "next", diff --git a/e2e-tests/development-runtime/shared-data/slices.js b/e2e-tests/development-runtime/shared-data/slices.js new file mode 100644 index 0000000000000..651111121772e --- /dev/null +++ b/e2e-tests/development-runtime/shared-data/slices.js @@ -0,0 +1,25 @@ +const allRecipes = [ + { + id: "r1", + name: "Jollof Rice", + description: + "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).", + authorId: "a-1", + }, + { + id: "r2", + name: "Ewa Agoyin", + description: + "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).", + authorId: "a-2", + }, +] + +const allRecipeAuthors = [ + { id: "a-1", name: "Jude" }, + { id: "a-2", name: "Ty" }, +] + +const framework = "Gatsby" + +module.exports = { allRecipes, allRecipeAuthors, framework } diff --git a/e2e-tests/development-runtime/src/components/footer.js b/e2e-tests/development-runtime/src/components/footer.js new file mode 100644 index 0000000000000..d95fc72ff6266 --- /dev/null +++ b/e2e-tests/development-runtime/src/components/footer.js @@ -0,0 +1,23 @@ +import React, { useContext } from "react" +import { ContextForSlices } from "../context-for-slices" + +// Use as a Slice +function Footer({ framework, lang, sliceContext: { framework: frameworkViaContext }}) { + const { posts } = useContext(ContextForSlices) + + return ( +
+ {frameworkViaContext} + Built with {` `} + {`${framework}${lang}`} + {` `}Posts Count: {`${posts.length}`} +
+ ) +} + +export default Footer diff --git a/e2e-tests/development-runtime/src/components/layout.js b/e2e-tests/development-runtime/src/components/layout.js index ce4f8f7938738..f834dc8d6b563 100644 --- a/e2e-tests/development-runtime/src/components/layout.js +++ b/e2e-tests/development-runtime/src/components/layout.js @@ -1,6 +1,6 @@ import React from "react" import PropTypes from "prop-types" -import { StaticQuery, graphql } from "gatsby" +import { StaticQuery, graphql, Slice } from "gatsby" import Header from "./header" import "./layout.css" @@ -29,6 +29,12 @@ const Layout = ({ children }) => ( > {children} + + + {/** The slice below doesn't exist but it shouldn't break build */} + + + {/** Insert this here and expect it to fail */} )} /> diff --git a/e2e-tests/development-runtime/src/components/recipe-author.js b/e2e-tests/development-runtime/src/components/recipe-author.js new file mode 100644 index 0000000000000..7d5f0ec09ba53 --- /dev/null +++ b/e2e-tests/development-runtime/src/components/recipe-author.js @@ -0,0 +1,15 @@ +import React from "react" + +// Use as a Slice +function RecipeAuthor({ sliceContext: { name } }) { + return ( +
+ Written by{" "} + + {name} + +
+ ) +} + +export default RecipeAuthor diff --git a/e2e-tests/development-runtime/src/context-for-slices.js b/e2e-tests/development-runtime/src/context-for-slices.js new file mode 100644 index 0000000000000..ac82422b7635f --- /dev/null +++ b/e2e-tests/development-runtime/src/context-for-slices.js @@ -0,0 +1,25 @@ +import React from "react" + +const ContextForSlices = React.createContext() + +const ContextForSlicesProvider = ({ children }) => { + const contextValue = { + posts: [ + { + title: "My first blog post", + content: "This is my first blog post", + }, + { + title: "My second blog post", + content: "This is my second blog post", + }, + ], + } + return ( + + {children} + + ) +} + +export { ContextForSlices, ContextForSlicesProvider } diff --git a/e2e-tests/development-runtime/src/templates/recipe.js b/e2e-tests/development-runtime/src/templates/recipe.js new file mode 100644 index 0000000000000..5f2f3377e29b4 --- /dev/null +++ b/e2e-tests/development-runtime/src/templates/recipe.js @@ -0,0 +1,15 @@ +import React from "react" +import { Slice } from "gatsby" +import Layout from "../components/layout" + +const Recipe = ({ pageContext: { description, name } }) => { + return ( + +

{name}

+

{description}

+ +
+ ) +} + +export default Recipe diff --git a/e2e-tests/development-runtime/src/wrap-root-element.js b/e2e-tests/development-runtime/src/wrap-root-element.js index 0eadae8422525..a136c16c29094 100644 --- a/e2e-tests/development-runtime/src/wrap-root-element.js +++ b/e2e-tests/development-runtime/src/wrap-root-element.js @@ -1,6 +1,7 @@ import React from "react" import { StaticQuery, graphql, Script } from "gatsby" import { scripts } from "../gatsby-script-scripts" +import { ContextForSlicesProvider } from "./context-for-slices" const WrapRootElement = ({ element }) => ( ( siteMetadata: { title }, }, }) => ( - <> + {element}