From 7db332556e9994db6569ad64303e6fbe432222c2 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Thu, 3 Jun 2021 15:48:42 +0200 Subject: [PATCH 1/6] feat(contentful): add support for tags --- .../contentful/cypress/integration/tags.js | 41 ++++++++ e2e-tests/contentful/src/pages/index.js | 6 ++ e2e-tests/contentful/src/pages/tags.js | 94 +++++++++++++++++++ .../__fixtures__/restricted-content-type.js | 1 + .../src/__fixtures__/rich-text-data.js | 2 + .../src/__fixtures__/starter-blog-data.js | 5 + .../src/__tests__/fetch-backoff.js | 4 + .../src/__tests__/fetch-network-errors.js | 2 + .../src/__tests__/fetch.js | 44 +++++++++ .../gatsby-source-contentful/src/fetch.js | 28 ++++++ .../src/gatsby-node.js | 40 +++++++- .../gatsby-source-contentful/src/normalize.js | 17 +++- .../gatsby-source-contentful/src/report.js | 5 + 13 files changed, 281 insertions(+), 8 deletions(-) create mode 100644 e2e-tests/contentful/cypress/integration/tags.js create mode 100644 e2e-tests/contentful/src/pages/tags.js diff --git a/e2e-tests/contentful/cypress/integration/tags.js b/e2e-tests/contentful/cypress/integration/tags.js new file mode 100644 index 0000000000000..bb5b50b45e113 --- /dev/null +++ b/e2e-tests/contentful/cypress/integration/tags.js @@ -0,0 +1,41 @@ +describe(`tags`, () => { + beforeEach(() => { + cy.visit("/tags").waitForRouteChange() + }) + it(`Tag list`, () => { + cy.get('[data-cy-id="tag-numberDecimal"] [data-cy-name]').should( + "have.text", + "Number: Decimal" + ) + cy.get('[data-cy-id="tag-numberDecimal"] [data-cy-id]').should( + "have.text", + "numberDecimal" + ) + cy.get('[data-cy-id="tag-numberInteger"] [data-cy-name]').should( + "have.text", + "Number: Integer" + ) + cy.get('[data-cy-id="tag-numberInteger"] [data-cy-id]').should( + "have.text", + "numberInteger" + ) + cy.get('[data-cy-id^="tag-"]').should("have.length", 2) + }) + it(`Filtered Entries`, () => { + cy.get('[data-cy-integers] [data-cy-id="number-integer"]').should( + "have.length", + 1 + ) + cy.get( + '[data-cy-integers] [data-cy-id="number-integer"] [data-cy-value]' + ).should("have.text", 42) + + cy.get('[data-cy-decimals] [data-cy-id="number-decimal"]').should( + "have.length", + 1 + ) + cy.get( + '[data-cy-decimals] [data-cy-id="number-decimal"] [data-cy-value]' + ).should("have.text", 4.2) + }) +}) diff --git a/e2e-tests/contentful/src/pages/index.js b/e2e-tests/contentful/src/pages/index.js index 65dcb2c4dd15a..79cf41c1fbd2a 100644 --- a/e2e-tests/contentful/src/pages/index.js +++ b/e2e-tests/contentful/src/pages/index.js @@ -45,6 +45,12 @@ const IndexPage = () => ( /text +

Metadata

+ ) diff --git a/e2e-tests/contentful/src/pages/tags.js b/e2e-tests/contentful/src/pages/tags.js new file mode 100644 index 0000000000000..6c32f701bffc7 --- /dev/null +++ b/e2e-tests/contentful/src/pages/tags.js @@ -0,0 +1,94 @@ +import { graphql } from "gatsby" +import * as React from "react" +import slugify from "slugify" + +import Layout from "../components/layout" + +const TagsPage = ({ data }) => { + const tags = data.tags.nodes + const integers = data.integers.nodes + const decimals = data.decimals.nodes + + return ( + +

Tag Listing:

+ {tags.map(tag => { + return ( +
+

{tag.name}

+

+ ID: {tag.contentful_id} +

+
+ ) + })} +
+

Filtered Entries:

+

Integers:

+
+ {integers.map(({ title, integer }) => { + const slug = slugify(title, { strict: true, lower: true }) + return ( +
+

{title}

+

{integer}

+
+ ) + })} +
+

Decimals:

+
+ {decimals.map(({ title, decimal }) => { + const slug = slugify(title, { strict: true, lower: true }) + return ( +
+

{title}

+

{decimal}

+
+ ) + })} +
+
+ ) +} + +export default TagsPage + +export const pageQuery = graphql` + query TagsQuery { + tags: allContentfulTag(sort: { fields: contentful_id }) { + nodes { + name + contentful_id + } + } + integers: allContentfulNumber( + sort: { fields: contentful_id } + filter: { + metadata: { + tags: { elemMatch: { contentful_id: { eq: "numberInteger" } } } + } + node_locale: { eq: "en-US" } + } + ) { + nodes { + title + integer + } + } + decimals: allContentfulNumber( + sort: { fields: contentful_id } + filter: { + metadata: { + tags: { elemMatch: { contentful_id: { eq: "numberDecimal" } } } + } + node_locale: { eq: "en-US" } + } + ) { + nodes { + title + decimal + } + } + } +` diff --git a/packages/gatsby-source-contentful/src/__fixtures__/restricted-content-type.js b/packages/gatsby-source-contentful/src/__fixtures__/restricted-content-type.js index 51867029cb443..86c5f7a2a02d2 100644 --- a/packages/gatsby-source-contentful/src/__fixtures__/restricted-content-type.js +++ b/packages/gatsby-source-contentful/src/__fixtures__/restricted-content-type.js @@ -74,5 +74,6 @@ exports.initialSync = () => { }, ], }, + tagItems: [], } } diff --git a/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js b/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js index 9d23588b59277..6a0200de2dc4e 100644 --- a/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js +++ b/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js @@ -789,6 +789,7 @@ exports.initialSync = () => { }, ], }, + tagItems: [], } } exports.deleteLinkedPage = () => { @@ -922,5 +923,6 @@ exports.deleteLinkedPage = () => { }, ], }, + tagItems: [], } } diff --git a/packages/gatsby-source-contentful/src/__fixtures__/starter-blog-data.js b/packages/gatsby-source-contentful/src/__fixtures__/starter-blog-data.js index de0c4827ecc47..eafa7a2723a4d 100644 --- a/packages/gatsby-source-contentful/src/__fixtures__/starter-blog-data.js +++ b/packages/gatsby-source-contentful/src/__fixtures__/starter-blog-data.js @@ -694,6 +694,7 @@ exports.initialSync = () => { }, ], }, + tagItems: [], } } @@ -1083,6 +1084,7 @@ exports.createBlogPost = () => { }, ], }, + tagItems: [], } } @@ -1434,6 +1436,7 @@ exports.updateBlogPost = () => { }, ], }, + tagItems: [], } } @@ -1747,6 +1750,7 @@ exports.removeBlogPost = () => { }, ], }, + tagItems: [], } } @@ -2060,5 +2064,6 @@ exports.removeAsset = () => { }, ], }, + tagItems: [], } } diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js b/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js index cc3658bcf5407..ff7c1d072ff28 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js @@ -87,6 +87,8 @@ describe(`fetch-backoff`, () => { `/spaces/${options.spaceId}/environments/master/content_types?skip=0&limit=1000&order=sys.createdAt` ) .reply(200, { items: [] }) + .get(`/spaces/${options.spaceId}/environments/master/tags`) + .reply(200, { items: [] }) await fetchData({ pluginConfig, reporter }) @@ -130,6 +132,8 @@ describe(`fetch-backoff`, () => { `/spaces/${options.spaceId}/environments/master/content_types?skip=0&limit=1000&order=sys.createdAt` ) .reply(200, { items: [] }) + .get(`/spaces/${options.spaceId}/environments/master/tags`) + .reply(200, { items: [] }) await fetchData({ pluginConfig, reporter }) diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js b/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js index 8f3d0a2db687a..70d8d7b9bd4b6 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js @@ -70,6 +70,8 @@ describe(`fetch-retry`, () => { `/spaces/${options.spaceId}/environments/master/content_types?skip=0&limit=1000&order=sys.createdAt` ) .reply(200, { items: [] }) + .get(`/spaces/${options.spaceId}/environments/master/tags`) + .reply(200, { items: [] }) await fetchData({ pluginConfig, reporter }) diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch.js b/packages/gatsby-source-contentful/src/__tests__/fetch.js index 1d1b5122ac012..b5550acb267b7 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch.js @@ -1,3 +1,11 @@ +/** + * @jest-environment node + */ + +import nock from "nock" + +nock.disableNetConnect() + // disable output coloring for tests process.env.FORCE_COLOR = 0 @@ -106,6 +114,7 @@ beforeEach(() => { mockClient.getLocales.mockClear() formatPluginOptionsForCLI.mockClear() contentful.createClient.mockClear() + nock.cleanAll() }) afterAll(() => { @@ -113,6 +122,11 @@ afterAll(() => { }) it(`calls contentful.createClient with expected params`, async () => { + const scope = nock(`https://${options.host}`) + .get(`/spaces/rocybtov1ozk/environments/env/tags`) + .reply(200, { + items: [], + }) await fetchData({ pluginConfig, reporter }) expect(reporter.panic).not.toBeCalled() expect(contentful.createClient).toBeCalledWith( @@ -124,9 +138,15 @@ it(`calls contentful.createClient with expected params`, async () => { proxy: proxyOption, }) ) + expect(scope.isDone()).toBeTruthy() }) it(`calls contentful.createClient with expected params and default fallbacks`, async () => { + const scope = nock(`https://cdn.contentful.com`) + .get(`/spaces/rocybtov1ozk/environments/master/tags`) + .reply(200, { + items: [], + }) await fetchData({ pluginConfig: createPluginConfig({ accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, @@ -144,9 +164,15 @@ it(`calls contentful.createClient with expected params and default fallbacks`, a space: `rocybtov1ozk`, }) ) + expect(scope.isDone()).toBeTruthy() }) it(`calls contentful.getContentTypes with default page limit`, async () => { + const scope = nock(`https://cdn.contentful.com`) + .get(`/spaces/rocybtov1ozk/environments/master/tags`) + .reply(200, { + items: [], + }) await fetchData({ pluginConfig: createPluginConfig({ accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, @@ -161,9 +187,15 @@ it(`calls contentful.getContentTypes with default page limit`, async () => { order: `sys.createdAt`, skip: 0, }) + expect(scope.isDone()).toBeTruthy() }) it(`calls contentful.getContentTypes with custom plugin option page limit`, async () => { + const scope = nock(`https://cdn.contentful.com`) + .get(`/spaces/rocybtov1ozk/environments/master/tags`) + .reply(200, { + items: [], + }) await fetchData({ pluginConfig: createPluginConfig({ accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, @@ -179,9 +211,21 @@ it(`calls contentful.getContentTypes with custom plugin option page limit`, asyn order: `sys.createdAt`, skip: 0, }) + expect(scope.isDone()).toBeTruthy() }) describe(`Displays troubleshooting tips and detailed plugin options on contentful client error`, () => { + beforeEach(() => { + nock(`https://${options.host}`) + .get(`/spaces/rocybtov1ozk/environments/env/tags`) + .reply(200, { + items: [], + }) + .get(`/spaces/rocybtov1ozk/environments/master/tags`) + .reply(200, { + items: [], + }) + }) it(`Generic fallback error`, async () => { mockClient.getLocales.mockImplementation(() => { throw new Error(`error`) diff --git a/packages/gatsby-source-contentful/src/fetch.js b/packages/gatsby-source-contentful/src/fetch.js index 7bfa57f54a773..b7b1dab24923f 100644 --- a/packages/gatsby-source-contentful/src/fetch.js +++ b/packages/gatsby-source-contentful/src/fetch.js @@ -3,6 +3,7 @@ const _ = require(`lodash`) const chalk = require(`chalk`) const { formatPluginOptionsForCLI } = require(`./plugin-options`) const { CODES } = require(`./report`) +const axios = require(`axios`) /** * Generate a user friendly error message. @@ -297,9 +298,36 @@ ${formatPluginOptionsForCLI(pluginConfig.getOriginalPluginOptions(), errors)}`, const contentTypeItems = contentTypes.items + // We need to fetch tags with the non-sync API as the sync API + // doesn't support this. + let tags + try { + // Temporarily use axios for this till Contentful JS-SDK supports this endpoint + tags = await axios({ + url: `https://${pluginConfig.get(`host`)}/spaces/${pluginConfig.get( + `spaceId` + )}/environments/${pluginConfig.get(`environment`)}/tags`, + headers: { Authorization: `Bearer ${pluginConfig.get(`accessToken`)}` }, + }) + } catch (e) { + reporter.panic({ + id: CODES.FetchTags, + context: { + sourceMessage: `Error fetching tags: ${createContentfulErrorMessage( + e + )}`, + }, + }) + } + + const tagItems = tags.data.items + + reporter.verbose(`Tags fetched ${tagItems.length}`) + const result = { currentSyncData, contentTypeItems, + tagItems, defaultLocale, locales, space, diff --git a/packages/gatsby-source-contentful/src/gatsby-node.js b/packages/gatsby-source-contentful/src/gatsby-node.js index 6ef21cc9652b3..5239974ed5fe5 100644 --- a/packages/gatsby-source-contentful/src/gatsby-node.js +++ b/packages/gatsby-source-contentful/src/gatsby-node.js @@ -24,7 +24,7 @@ const restrictedNodeFields = [ `parent`, ] -const restrictedContentTypes = [`entity`, `reference`] +const restrictedContentTypes = [`entity`, `reference`, `tag`, `asset`] exports.setFieldsOnGraphQLNodeType = require(`./extend-node-type`).extendNodeType @@ -182,6 +182,7 @@ exports.sourceNodes = async ( let currentSyncData let contentTypeItems + let tagItems let defaultLocale let locales let space @@ -241,6 +242,7 @@ exports.sourceNodes = async ( ;({ currentSyncData, contentTypeItems, + tagItems, defaultLocale, locales, space, @@ -285,6 +287,7 @@ exports.sourceNodes = async ( ;({ currentSyncData, contentTypeItems, + tagItems, defaultLocale, locales, space, @@ -362,6 +365,18 @@ exports.sourceNodes = async ( }) } + createTypes( + schema.buildObjectType({ + name: `ContentfulTag`, + fields: { + name: { type: `String!` }, + contentful_id: { type: `String!` }, + id: { type: `ID!` }, + }, + interfaces: [`Node`], + }) + ) + createTypes(` interface ContentfulEntry implements Node { contentful_id: String! @@ -531,7 +546,9 @@ exports.sourceNodes = async ( currentSyncData.deletedAssets.forEach(deleteContentfulNode) const existingNodes = getNodes().filter( - n => n.internal.owner === `gatsby-source-contentful` + n => + n.internal.owner === `gatsby-source-contentful` && + (n?.sys?.type === `Asset` || n?.sys?.type === `Entry`) ) existingNodes.forEach(n => touchNode(n)) @@ -653,7 +670,7 @@ exports.sourceNodes = async ( } if (assets.length) { - reporter.info(`Creating ${assets.length} Contentful asset nodes`) + reporter.info(`Creating ${assets.length} Contentful Asset nodes`) } for (let i = 0; i < assets.length; i++) { @@ -670,6 +687,23 @@ exports.sourceNodes = async ( ) } + // Create tags entities + if (tagItems.length) { + reporter.info(`Creating ${tagItems.length} Contentful Tag nodes`) + + for (const tag of tagItems) { + await createNode({ + id: createNodeId(`ContentfulTag__${space.sys.id}__${tag.sys.id}`), + name: tag.name, + contentful_id: tag.sys.id, + internal: { + type: `ContentfulTag`, + contentDigest: tag.sys.updatedAt, + }, + }) + } + } + creationActivity.end() if (pluginConfig.get(`downloadLocal`)) { diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index fde42f7507e72..53ea3a3acafe8 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -76,11 +76,9 @@ exports.buildResolvableSet = ({ }) => { const resolvable = new Set() existingNodes.forEach(node => { - if (node.internal.owner === `gatsby-source-contentful`) { - // We need to add only root level resolvable (assets and entries) - // Derived nodes (markdown or JSON) will be recreated if needed. - resolvable.add(`${node.contentful_id}___${node.sys.type}`) - } + // We need to add only root level resolvable (assets and entries) + // Derived nodes (markdown or JSON) will be recreated if needed. + resolvable.add(`${node.contentful_id}___${node.sys.type}`) }) entryList.forEach(entries => { @@ -591,6 +589,15 @@ exports.createNodesForContentType = ({ // The content of an entry is guaranteed to be updated if and only if the .sys.updatedAt field changed entryNode.internal.contentDigest = entryItem.sys.updatedAt + // Link tags + if (entryItem?.metadata?.tags) { + entryNode.metadata = { + tags___NODE: entryItem?.metadata?.tags.map(tag => + createNodeId(`ContentfulTag__${space.sys.id}__${tag.sys.id}`) + ), + } + } + return entryNode }) .filter(Boolean) diff --git a/packages/gatsby-source-contentful/src/report.js b/packages/gatsby-source-contentful/src/report.js index 5444a86693f60..d597e6b7ac86f 100644 --- a/packages/gatsby-source-contentful/src/report.js +++ b/packages/gatsby-source-contentful/src/report.js @@ -28,4 +28,9 @@ export const ERROR_MAP = { level: `ERROR`, category: `THIRD_PARTY`, }, + [CODES.FetchTags]: { + text: context => context.sourceMessage, + level: `ERROR`, + category: `THIRD_PARTY`, + }, } From 7f98410fdd2149d268708007a31d7d3bc0091289 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Fri, 11 Jun 2021 12:34:03 +0200 Subject: [PATCH 2/6] migrate to latest Contentful SDK which supports metadata tags endpoint --- .../gatsby-source-contentful/package.json | 4 +- .../src/__tests__/fetch-backoff.js | 8 ++- .../src/__tests__/fetch-network-errors.js | 4 +- .../src/__tests__/fetch.js | 50 +++---------------- .../gatsby-source-contentful/src/fetch.js | 11 +--- yarn.lock | 22 ++++---- 6 files changed, 30 insertions(+), 69 deletions(-) diff --git a/packages/gatsby-source-contentful/package.json b/packages/gatsby-source-contentful/package.json index db1e6707b3e04..e5128c5fe8ca1 100644 --- a/packages/gatsby-source-contentful/package.json +++ b/packages/gatsby-source-contentful/package.json @@ -8,14 +8,14 @@ }, "dependencies": { "@babel/runtime": "^7.14.6", - "@contentful/rich-text-react-renderer": "^14.1.2", + "@contentful/rich-text-react-renderer": "^14.1.3", "@contentful/rich-text-types": "^14.1.2", "@hapi/joi": "^15.1.1", "@vercel/fetch-retry": "^5.0.3", "axios": "^0.21.1", "chalk": "^4.1.1", "common-tags": "^1.8.0", - "contentful": "^8.1.7", + "contentful": "^8.4.0", "fs-extra": "^9.1.0", "gatsby-core-utils": "^2.10.0-next.1", "gatsby-plugin-utils": "^1.10.0-next.1", diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js b/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js index ff7c1d072ff28..8a0b1b97a4aed 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js @@ -87,7 +87,9 @@ describe(`fetch-backoff`, () => { `/spaces/${options.spaceId}/environments/master/content_types?skip=0&limit=1000&order=sys.createdAt` ) .reply(200, { items: [] }) - .get(`/spaces/${options.spaceId}/environments/master/tags`) + .get( + `/spaces/${options.spaceId}/environments/master/tags?skip=0&limit=1000&order=sys.createdAt` + ) .reply(200, { items: [] }) await fetchData({ pluginConfig, reporter }) @@ -132,7 +134,9 @@ describe(`fetch-backoff`, () => { `/spaces/${options.spaceId}/environments/master/content_types?skip=0&limit=1000&order=sys.createdAt` ) .reply(200, { items: [] }) - .get(`/spaces/${options.spaceId}/environments/master/tags`) + .get( + `/spaces/${options.spaceId}/environments/master/tags?skip=0&limit=1000&order=sys.createdAt` + ) .reply(200, { items: [] }) await fetchData({ pluginConfig, reporter }) diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js b/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js index 70d8d7b9bd4b6..b0be150b07e6a 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js @@ -70,7 +70,9 @@ describe(`fetch-retry`, () => { `/spaces/${options.spaceId}/environments/master/content_types?skip=0&limit=1000&order=sys.createdAt` ) .reply(200, { items: [] }) - .get(`/spaces/${options.spaceId}/environments/master/tags`) + .get( + `/spaces/${options.spaceId}/environments/master/tags?skip=0&limit=1000&order=sys.createdAt` + ) .reply(200, { items: [] }) await fetchData({ pluginConfig, reporter }) diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch.js b/packages/gatsby-source-contentful/src/__tests__/fetch.js index b5550acb267b7..da13347e48b91 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch.js @@ -1,11 +1,3 @@ -/** - * @jest-environment node - */ - -import nock from "nock" - -nock.disableNetConnect() - // disable output coloring for tests process.env.FORCE_COLOR = 0 @@ -42,6 +34,12 @@ const mockClient = { total: 0, } }), + getTags: jest.fn(async () => { + return { + items: [], + total: 0, + } + }), } jest.mock(`contentful`, () => { @@ -114,7 +112,6 @@ beforeEach(() => { mockClient.getLocales.mockClear() formatPluginOptionsForCLI.mockClear() contentful.createClient.mockClear() - nock.cleanAll() }) afterAll(() => { @@ -122,11 +119,6 @@ afterAll(() => { }) it(`calls contentful.createClient with expected params`, async () => { - const scope = nock(`https://${options.host}`) - .get(`/spaces/rocybtov1ozk/environments/env/tags`) - .reply(200, { - items: [], - }) await fetchData({ pluginConfig, reporter }) expect(reporter.panic).not.toBeCalled() expect(contentful.createClient).toBeCalledWith( @@ -138,15 +130,9 @@ it(`calls contentful.createClient with expected params`, async () => { proxy: proxyOption, }) ) - expect(scope.isDone()).toBeTruthy() }) it(`calls contentful.createClient with expected params and default fallbacks`, async () => { - const scope = nock(`https://cdn.contentful.com`) - .get(`/spaces/rocybtov1ozk/environments/master/tags`) - .reply(200, { - items: [], - }) await fetchData({ pluginConfig: createPluginConfig({ accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, @@ -164,15 +150,9 @@ it(`calls contentful.createClient with expected params and default fallbacks`, a space: `rocybtov1ozk`, }) ) - expect(scope.isDone()).toBeTruthy() }) it(`calls contentful.getContentTypes with default page limit`, async () => { - const scope = nock(`https://cdn.contentful.com`) - .get(`/spaces/rocybtov1ozk/environments/master/tags`) - .reply(200, { - items: [], - }) await fetchData({ pluginConfig: createPluginConfig({ accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, @@ -187,15 +167,9 @@ it(`calls contentful.getContentTypes with default page limit`, async () => { order: `sys.createdAt`, skip: 0, }) - expect(scope.isDone()).toBeTruthy() }) it(`calls contentful.getContentTypes with custom plugin option page limit`, async () => { - const scope = nock(`https://cdn.contentful.com`) - .get(`/spaces/rocybtov1ozk/environments/master/tags`) - .reply(200, { - items: [], - }) await fetchData({ pluginConfig: createPluginConfig({ accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, @@ -211,21 +185,9 @@ it(`calls contentful.getContentTypes with custom plugin option page limit`, asyn order: `sys.createdAt`, skip: 0, }) - expect(scope.isDone()).toBeTruthy() }) describe(`Displays troubleshooting tips and detailed plugin options on contentful client error`, () => { - beforeEach(() => { - nock(`https://${options.host}`) - .get(`/spaces/rocybtov1ozk/environments/env/tags`) - .reply(200, { - items: [], - }) - .get(`/spaces/rocybtov1ozk/environments/master/tags`) - .reply(200, { - items: [], - }) - }) it(`Generic fallback error`, async () => { mockClient.getLocales.mockImplementation(() => { throw new Error(`error`) diff --git a/packages/gatsby-source-contentful/src/fetch.js b/packages/gatsby-source-contentful/src/fetch.js index b7b1dab24923f..483e2fc01ae28 100644 --- a/packages/gatsby-source-contentful/src/fetch.js +++ b/packages/gatsby-source-contentful/src/fetch.js @@ -3,7 +3,6 @@ const _ = require(`lodash`) const chalk = require(`chalk`) const { formatPluginOptionsForCLI } = require(`./plugin-options`) const { CODES } = require(`./report`) -const axios = require(`axios`) /** * Generate a user friendly error message. @@ -302,13 +301,7 @@ ${formatPluginOptionsForCLI(pluginConfig.getOriginalPluginOptions(), errors)}`, // doesn't support this. let tags try { - // Temporarily use axios for this till Contentful JS-SDK supports this endpoint - tags = await axios({ - url: `https://${pluginConfig.get(`host`)}/spaces/${pluginConfig.get( - `spaceId` - )}/environments/${pluginConfig.get(`environment`)}/tags`, - headers: { Authorization: `Bearer ${pluginConfig.get(`accessToken`)}` }, - }) + tags = await await pagedGet(client, `getTags`, pageLimit) } catch (e) { reporter.panic({ id: CODES.FetchTags, @@ -320,7 +313,7 @@ ${formatPluginOptionsForCLI(pluginConfig.getOriginalPluginOptions(), errors)}`, }) } - const tagItems = tags.data.items + const tagItems = tags.items reporter.verbose(`Tags fetched ${tagItems.length}`) diff --git a/yarn.lock b/yarn.lock index 6c963e5fa3a65..349512271156c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1485,10 +1485,10 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@contentful/rich-text-react-renderer@^14.1.2": - version "14.1.2" - resolved "https://registry.yarnpkg.com/@contentful/rich-text-react-renderer/-/rich-text-react-renderer-14.1.2.tgz#b7fff19faa0512f034f1717774a0d9b348bb07fc" - integrity sha512-UmZ5nNvFXuD4LA2TKDDD52FgzmeMAQUVu5p9UqKDVDG6twHAD4DiWtoXSRM5Bebftlx2UH+UeWHbxIOgF/lV5A== +"@contentful/rich-text-react-renderer@^14.1.3": + version "14.1.3" + resolved "https://registry.npmjs.org/@contentful/rich-text-react-renderer/-/rich-text-react-renderer-14.1.3.tgz#501136677742d0ad3f4b50fa2c12b17fc1d68cc8" + integrity sha512-qieT2qEKlHarlYjDvDHpv6vwf2M9uI0Nf+WgyKBP6SFgakpzxuO5PR9j5CnxyusZ/NzsWcGBu9SDQMnKeM2iZw== dependencies: "@contentful/rich-text-types" "^14.1.2" @@ -8688,12 +8688,12 @@ contentful-sdk-core@^6.5.0, contentful-sdk-core@^6.7.0: fast-copy "^2.1.0" qs "^6.9.4" -contentful@^8.1.7: - version "8.1.7" - resolved "https://registry.yarnpkg.com/contentful/-/contentful-8.1.7.tgz#24786d5eb98118368cafd2a7bf718de9a1f99bae" - integrity sha512-dFlpRjkrTp+TG6kCjERIgzsBRTfjflRnjosE0uQus7dENrz2nrVEYhFO/T3WrKQfAbTyozKcTpWr5pEZiXpm2A== +contentful@^8.4.0: + version "8.4.0" + resolved "https://registry.npmjs.org/contentful/-/contentful-8.4.0.tgz#0bfa29391176e9570fbada272797c07f7b0a6c9a" + integrity sha512-VHVIZMRVMvce949uhDtvxEgHsNzcbYN1YW7Hz4vJKt37qyf42AESvSsRZAKLYgf8b8NeHn07VgV2drBacFm5Tg== dependencies: - axios "^0.21.0" + axios "^0.21.1" contentful-resolve-response "^1.3.0" contentful-sdk-core "^6.5.0" fast-copy "^2.1.0" @@ -9677,7 +9677,7 @@ cssstyle@^2.0.0, cssstyle@^2.3.0: csstype@2.6.17, csstype@^2.5.7, csstype@^2.6.14, csstype@^2.6.4, csstype@^2.6.9, csstype@^3.0.2: version "2.6.17" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.17.tgz#4cf30eb87e1d1a005d8b6510f95292413f6a1c0e" + resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz#4cf30eb87e1d1a005d8b6510f95292413f6a1c0e" integrity sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A== csvtojson@^2.0.10: @@ -26780,7 +26780,7 @@ text-table@0.2.0, text-table@^0.2.0: theme-ui@0.4.0-rc.14, "theme-ui@>= 0.4.0-rc.1", theme-ui@^0.2.49, theme-ui@^0.4.0-rc.14: version "0.4.0-rc.14" - resolved "https://registry.yarnpkg.com/theme-ui/-/theme-ui-0.4.0-rc.14.tgz#67856dd8302e621ad55f7687a18d483b506c0706" + resolved "https://registry.npmjs.org/theme-ui/-/theme-ui-0.4.0-rc.14.tgz#67856dd8302e621ad55f7687a18d483b506c0706" integrity sha512-ciaGwsv9cRskUAukHSzMHdRXhqpweV8xAsywkE61gBg9msAfeI6MyeOU7HCseK4U9/Ppu3NNJExI32CK4BMDtg== dependencies: "@theme-ui/color-modes" "^0.4.0-rc.14" From 651f6ce9f5236cbd9dcc5231b1171820a168e347 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Tue, 6 Jul 2021 13:24:53 +0100 Subject: [PATCH 3/6] move new tags feature behind a flag --- .../gatsby-source-contentful/src/fetch.js | 35 +++++++++---------- .../src/gatsby-node.js | 34 ++++++++++-------- .../gatsby-source-contentful/src/normalize.js | 6 ++-- .../src/plugin-options.js | 1 + 4 files changed, 41 insertions(+), 35 deletions(-) diff --git a/packages/gatsby-source-contentful/src/fetch.js b/packages/gatsby-source-contentful/src/fetch.js index 483e2fc01ae28..136031150d68e 100644 --- a/packages/gatsby-source-contentful/src/fetch.js +++ b/packages/gatsby-source-contentful/src/fetch.js @@ -297,26 +297,25 @@ ${formatPluginOptionsForCLI(pluginConfig.getOriginalPluginOptions(), errors)}`, const contentTypeItems = contentTypes.items - // We need to fetch tags with the non-sync API as the sync API - // doesn't support this. - let tags - try { - tags = await await pagedGet(client, `getTags`, pageLimit) - } catch (e) { - reporter.panic({ - id: CODES.FetchTags, - context: { - sourceMessage: `Error fetching tags: ${createContentfulErrorMessage( - e - )}`, - }, - }) + // We need to fetch tags with the non-sync API as the sync API doesn't support this. + let tagItems = [] + if (pluginConfig.get(`enableTags`)) { + try { + const tagsResult = await pagedGet(client, `getTags`, pageLimit) + tagItems = tagsResult.items + reporter.verbose(`Tags fetched ${tagItems.length}`) + } catch (e) { + reporter.panic({ + id: CODES.FetchTags, + context: { + sourceMessage: `Error fetching tags: ${createContentfulErrorMessage( + e + )}`, + }, + }) + } } - const tagItems = tags.items - - reporter.verbose(`Tags fetched ${tagItems.length}`) - const result = { currentSyncData, contentTypeItems, diff --git a/packages/gatsby-source-contentful/src/gatsby-node.js b/packages/gatsby-source-contentful/src/gatsby-node.js index 5239974ed5fe5..efa1fb000467b 100644 --- a/packages/gatsby-source-contentful/src/gatsby-node.js +++ b/packages/gatsby-source-contentful/src/gatsby-node.js @@ -24,8 +24,6 @@ const restrictedNodeFields = [ `parent`, ] -const restrictedContentTypes = [`entity`, `reference`, `tag`, `asset`] - exports.setFieldsOnGraphQLNodeType = require(`./extend-node-type`).extendNodeType const validateContentfulAccess = async pluginOptions => { @@ -318,6 +316,11 @@ exports.sourceNodes = async ( // Check for restricted content type names const useNameForId = pluginConfig.get(`useNameForId`) + const restrictedContentTypes = [`entity`, `reference`, `asset`] + + if (pluginConfig.get(`enableTags`)) { + restrictedContentTypes.push(`tags`) + } contentTypeItems.forEach(contentTypeItem => { // Establish identifier for content type @@ -365,17 +368,20 @@ exports.sourceNodes = async ( }) } - createTypes( - schema.buildObjectType({ - name: `ContentfulTag`, - fields: { - name: { type: `String!` }, - contentful_id: { type: `String!` }, - id: { type: `ID!` }, - }, - interfaces: [`Node`], - }) - ) + if (pluginConfig.get(`enableTags`)) { + createTypes( + schema.buildObjectType({ + name: `ContentfulTag`, + fields: { + name: { type: `String!` }, + contentful_id: { type: `String!` }, + id: { type: `ID!` }, + }, + interfaces: [`Node`], + extensions: { dontInfer: {} }, + }) + ) + } createTypes(` interface ContentfulEntry implements Node { @@ -652,7 +658,6 @@ exports.sourceNodes = async ( await Promise.all( normalize.createNodesForContentType({ contentTypeItem, - contentTypeItems, restrictedNodeFields, conflictFieldPrefix, entries: entryList[i], @@ -665,6 +670,7 @@ exports.sourceNodes = async ( locales, space, useNameForId: pluginConfig.get(`useNameForId`), + pluginConfig, }) ) } diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 53ea3a3acafe8..944609a942fa8 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -228,7 +228,6 @@ function prepareJSONNode(id, node, key, content) { exports.createNodesForContentType = ({ contentTypeItem, - contentTypeItems, restrictedNodeFields, conflictFieldPrefix, entries, @@ -241,6 +240,7 @@ exports.createNodesForContentType = ({ locales, space, useNameForId, + pluginConfig, }) => { // Establish identifier for content type // Use `name` if specified, otherwise, use internal id (usually a natural-language constant, @@ -590,9 +590,9 @@ exports.createNodesForContentType = ({ entryNode.internal.contentDigest = entryItem.sys.updatedAt // Link tags - if (entryItem?.metadata?.tags) { + if (pluginConfig.get(`enableTags`)) { entryNode.metadata = { - tags___NODE: entryItem?.metadata?.tags.map(tag => + tags___NODE: entryItem.metadata.tags.map(tag => createNodeId(`ContentfulTag__${space.sys.id}__${tag.sys.id}`) ), } diff --git a/packages/gatsby-source-contentful/src/plugin-options.js b/packages/gatsby-source-contentful/src/plugin-options.js index 7319b2432d230..5fe9d96fa3453 100644 --- a/packages/gatsby-source-contentful/src/plugin-options.js +++ b/packages/gatsby-source-contentful/src/plugin-options.js @@ -12,6 +12,7 @@ const defaultOptions = { forceFullSync: false, pageLimit: DEFAULT_PAGE_LIMIT, useNameForId: true, + enableTags: false, } const createPluginConfig = pluginOptions => { From 14857d65f1128efbfe0f9c2b62d6b4935c4cd04f Mon Sep 17 00:00:00 2001 From: axe312ger Date: Tue, 6 Jul 2021 14:12:01 +0100 Subject: [PATCH 4/6] add documentation for tags and a table of content to readme --- packages/gatsby-source-contentful/README.md | 96 +++++++++++++++++++-- 1 file changed, 87 insertions(+), 9 deletions(-) diff --git a/packages/gatsby-source-contentful/README.md b/packages/gatsby-source-contentful/README.md index 155c0be52065a..b54cf221df7ac 100644 --- a/packages/gatsby-source-contentful/README.md +++ b/packages/gatsby-source-contentful/README.md @@ -1,11 +1,42 @@ # gatsby-source-contentful -Source plugin for pulling content types, entries, and assets into Gatsby from -Contentful spaces. It creates links between entry types and asset so they can be -queried in Gatsby using GraphQL. - -An example site for using this plugin is at -https://using-contentful.gatsbyjs.org/ +> Source plugin for pulling content types, entries, and assets into Gatsby from +> Contentful spaces. It creates links between entry types and asset so they can be +> queried in Gatsby using GraphQL. +> +> An example site for using this plugin is at https://using-contentful.gatsbyjs.org/ + +
+Table of contents + +- [gatsby-source-contentful](#gatsby-source-contentful) + - [Install](#install) + - [How to use](#how-to-use) + - [Restrictions and limitations](#restrictions-and-limitations) + - [Using Delivery API](#using-delivery-api) + - [Using Preview API](#using-preview-api) + - [Offline](#offline) + - [Configuration options](#configuration-options) + - [How to query for nodes](#how-to-query-for-nodes) + - [Query for all nodes](#query-for-all-nodes) + - [Query for a single node](#query-for-a-single-node) + - [A note about LongText fields](#a-note-about-longtext-fields) + - [Duplicated entries](#duplicated-entries) + - [Query for Assets in ContentType nodes](#query-for-assets-in-contenttype-nodes) + - [More on Queries with Contentful and Gatsby](#more-on-queries-with-contentful-and-gatsby) + - [Using the new Gatsby image plugin](#using-the-new-gatsby-image-plugin) + - [Contentful Tags](#contentful-tags) + - [List available tags](#list-available-tags) + - [Filter content by tags](#filter-content-by-tags) + - [Contentful Rich Text](#contentful-rich-text) + - [Query Rich Text content and references](#query-rich-text-content-and-references) + - [Rendering](#rendering) + - [Download assets for static distribution](#download-assets-for-static-distribution) + - [Enable the feature with the `downloadLocal: true` option.](#enable-the-feature-with-the-downloadlocal-true-option) + - [Updating Queries for downloadLocal](#updating-queries-for-downloadlocal) + - [Sourcing From Multiple Contentful Spaces](#sourcing-from-multiple-contentful-spaces) + +
## Install @@ -136,6 +167,12 @@ Additional config which will get passed to [Contentfuls JS SDK](https://github.c Use this with caution, you might override values this plugin does set for you to connect to Contentful. +**`enableTags`** [boolean][optional] [default: `false`] + +Enable the new [tags feature](https://www.contentful.com/blog/2021/04/08/governance-tagging-metadata/). This will disallow the content type name `tags` till the next major version of this plugin. + +Learn how to use them at the [Contentful Tags](#contentful-tags) section. + ## How to query for nodes Two standard node types are available from Contentful: `Asset` and `ContentType`. @@ -298,6 +335,11 @@ To get **all** the `CaseStudy` nodes with `ShortText` fields `id`, `slug`, `titl When querying images you can use the `fixed`, `fluid` or `resize` nodes to get different sizes for the image (for example for using [`gatsby-image`](https://www.gatsbyjs.org/packages/gatsby-image/)). Their usage is documented at the [`gatsby-plugin-sharp`](https://www.gatsbyjs.org/packages/gatsby-plugin-sharp/) package. The only difference is that `gatsby-source-contentful` also allows setting only the `width` parameter for these node types, the height will then automatically be calculated according to the aspect ratio. +### More on Queries with Contentful and Gatsby + +It is strongly recommended that you take a look at how data flows in a real Contentful and Gatsby application to fully understand how the queries, Node.js functions and React components all come together. Check out the example site at +[using-contentful.gatsbyjs.org](https://using-contentful.gatsbyjs.org/). + ## Using the new Gatsby image plugin You can now use the beta [gatsby-plugin-image](https://gatsbyjs.com/plugins/gatsby-plugin-image/) to display high-performance, responsive images from Contentful. This plugin is the replacement for gatsby-image, and is currently in beta, but can help deliver improved performance, with a cleaner API. Support in gatsby-source-contentful is still experimental. @@ -336,10 +378,46 @@ module.exports = { } ``` -## More on Queries with Contentful and Gatsby +## [Contentful Tags](https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/content-tags) -It is strongly recommended that you take a look at how data flows in a real Contentful and Gatsby application to fully understand how the queries, Node.js functions and React components all come together. Check out the example site at -[using-contentful.gatsbyjs.org](https://using-contentful.gatsbyjs.org/). +You need to set the `enableTags` flag to `true` to use this new feature. + +### List available tags + +This example lists all available tags. The sorting is optional. + +```graphql +query TagsQuery { + allContentfulTag(sort: { fields: contentful_id }) { + nodes { + name + contentful_id + } + } +} +``` + +### Filter content by tags + +This filters content entries that are tagged with the `numberInteger` tag. + +```graphql +query FilterByTagsQuery { + allContentfulNumber( + sort: { fields: contentful_id } + filter: { + metadata: { + tags: { elemMatch: { contentful_id: { eq: "numberInteger" } } } + } + } + ) { + nodes { + title + integer + } + } +} +``` ## [Contentful Rich Text](https://www.contentful.com/developers/docs/concepts/rich-text/) From 9ed75a4c4b0c4da925378f791dc556222f5a19ce Mon Sep 17 00:00:00 2001 From: axe312ger Date: Sun, 11 Jul 2021 14:30:48 +0100 Subject: [PATCH 5/6] test(e2e): enable tags feature for Contentful test --- e2e-tests/contentful/gatsby-config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e-tests/contentful/gatsby-config.js b/e2e-tests/contentful/gatsby-config.js index 8ffb795393aeb..0050bf41b005a 100644 --- a/e2e-tests/contentful/gatsby-config.js +++ b/e2e-tests/contentful/gatsby-config.js @@ -11,6 +11,7 @@ module.exports = { // Use: https://www.gatsbyjs.com/docs/how-to/local-development/environment-variables/ spaceId: `k8iqpp6u0ior`, accessToken: `hO_7N0bLaCJFbu5nL3QVekwNeB_TNtg6tOCB_9qzKUw`, + enableTags: true, }, }, `gatsby-transformer-remark`, From dbd240d81e88be8e35a8c264199a9ee38c00e5b3 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Sun, 11 Jul 2021 16:56:01 +0100 Subject: [PATCH 6/6] test: align tests for enableTags flag --- .../src/__tests__/fetch-backoff.js | 8 ----- .../src/__tests__/fetch-network-errors.js | 4 --- .../src/__tests__/fetch.js | 34 +++++++++++++++++++ .../src/__tests__/normalize.js | 8 +++++ 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js b/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js index 8a0b1b97a4aed..cc3658bcf5407 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js @@ -87,10 +87,6 @@ describe(`fetch-backoff`, () => { `/spaces/${options.spaceId}/environments/master/content_types?skip=0&limit=1000&order=sys.createdAt` ) .reply(200, { items: [] }) - .get( - `/spaces/${options.spaceId}/environments/master/tags?skip=0&limit=1000&order=sys.createdAt` - ) - .reply(200, { items: [] }) await fetchData({ pluginConfig, reporter }) @@ -134,10 +130,6 @@ describe(`fetch-backoff`, () => { `/spaces/${options.spaceId}/environments/master/content_types?skip=0&limit=1000&order=sys.createdAt` ) .reply(200, { items: [] }) - .get( - `/spaces/${options.spaceId}/environments/master/tags?skip=0&limit=1000&order=sys.createdAt` - ) - .reply(200, { items: [] }) await fetchData({ pluginConfig, reporter }) diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js b/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js index b0be150b07e6a..8f3d0a2db687a 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js @@ -70,10 +70,6 @@ describe(`fetch-retry`, () => { `/spaces/${options.spaceId}/environments/master/content_types?skip=0&limit=1000&order=sys.createdAt` ) .reply(200, { items: [] }) - .get( - `/spaces/${options.spaceId}/environments/master/tags?skip=0&limit=1000&order=sys.createdAt` - ) - .reply(200, { items: [] }) await fetchData({ pluginConfig, reporter }) diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch.js b/packages/gatsby-source-contentful/src/__tests__/fetch.js index da13347e48b91..d9bbbd4479047 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch.js @@ -187,6 +187,40 @@ it(`calls contentful.getContentTypes with custom plugin option page limit`, asyn }) }) +describe(`Tags feature`, () => { + it(`tags are disabled by default`, async () => { + await fetchData({ + pluginConfig: createPluginConfig({ + accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, + spaceId: `rocybtov1ozk`, + pageLimit: 50, + }), + reporter, + }) + + expect(reporter.panic).not.toBeCalled() + expect(mockClient.getTags).not.toBeCalled() + }) + it(`calls contentful.getTags when enabled`, async () => { + await fetchData({ + pluginConfig: createPluginConfig({ + accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, + spaceId: `rocybtov1ozk`, + pageLimit: 50, + enableTags: true, + }), + reporter, + }) + + expect(reporter.panic).not.toBeCalled() + expect(mockClient.getTags).toHaveBeenCalledWith({ + limit: 50, + order: `sys.createdAt`, + skip: 0, + }) + }) +}) + describe(`Displays troubleshooting tips and detailed plugin options on contentful client error`, () => { it(`Generic fallback error`, async () => { mockClient.getLocales.mockImplementation(() => { diff --git a/packages/gatsby-source-contentful/src/__tests__/normalize.js b/packages/gatsby-source-contentful/src/__tests__/normalize.js index 226fc44d69dc2..078eae8c0db8e 100644 --- a/packages/gatsby-source-contentful/src/__tests__/normalize.js +++ b/packages/gatsby-source-contentful/src/__tests__/normalize.js @@ -1,4 +1,6 @@ const normalize = require(`../normalize`) +import { createPluginConfig } from "../plugin-options" + const { currentSyncData, contentTypeItems, @@ -18,6 +20,8 @@ const restrictedNodeFields = [ `internal`, ] +const pluginConfig = createPluginConfig({}) + describe(`Process contentful data (by name)`, () => { let entryList let resolvable @@ -73,6 +77,7 @@ describe(`Process contentful data (by name)`, () => { locales, space, useNameForId: true, + pluginConfig, }) }) expect(createNode.mock.calls).toMatchSnapshot() @@ -155,6 +160,7 @@ describe(`Skip existing nodes in warm build`, () => { locales, space, useNameForId: true, + pluginConfig, }) }) expect(createNode.mock.calls).toMatchSnapshot() @@ -240,6 +246,7 @@ describe(`Process existing mutated nodes in warm build`, () => { locales, space, useNameForId: true, + pluginConfig, }) }) expect(createNode.mock.calls).toMatchSnapshot() @@ -322,6 +329,7 @@ describe(`Process contentful data (by id)`, () => { locales, space, useNameForId: false, + pluginConfig, }) }) expect(createNode.mock.calls).toMatchSnapshot()