diff --git a/packages/gatsby-source-contentful/src/__fixtures__/unpublished-fields-delivery.js b/packages/gatsby-source-contentful/src/__fixtures__/unpublished-fields-delivery.js new file mode 100644 index 0000000000000..e65336c76bb58 --- /dev/null +++ b/packages/gatsby-source-contentful/src/__fixtures__/unpublished-fields-delivery.js @@ -0,0 +1,415 @@ +exports.contentTypeItems = () => [ + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + id: `typeWithTextField`, + type: `ContentType`, + createdAt: `2022-04-07T12:36:29.252Z`, + updatedAt: `2022-04-07T12:51:05.868Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 4, + }, + displayField: `title`, + name: `Type With Text Field`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `textFieldNotRequired`, + name: `Text Field Not Required`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `textFieldRequired`, + name: `Text Field Required`, + type: `Symbol`, + localized: false, + required: true, + disabled: false, + omitted: false, + }, + { + id: `localizedTextFieldRequired`, + name: `Localized Text Field Required`, + type: `Symbol`, + localized: true, + required: true, + disabled: false, + omitted: false, + }, + { + id: `localizedTextFieldNotRequired`, + name: `Localized Text Field Not Required`, + type: `Symbol`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + ], + }, +] + +exports.initialSync = () => { + return { + currentSyncData: { + entries: [ + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + id: `ffDHCCwSEeozSX521OENf`, + type: `Entry`, + createdAt: `2022-04-07T12:41:07.377Z`, + updatedAt: `2022-04-07T12:55:23.315Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 2, + contentType: { + sys: { + type: `Link`, + linkType: `ContentType`, + id: `typeWithTextField`, + }, + }, + }, + fields: { + title: { + "en-US": `Published With Valid Changes`, + }, + textFieldNotRequired: { + "en-US": `This value is not required.`, + }, + textFieldRequired: { + "en-US": `This value is required.`, + }, + localizedTextFieldRequired: { + "en-US": `This value is required.`, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + id: `3PmbzmeujVtZ9DzWb8gKC6`, + type: `Entry`, + createdAt: `2022-04-07T12:41:35.787Z`, + updatedAt: `2022-04-07T12:54:46.551Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 3, + contentType: { + sys: { + type: `Link`, + linkType: `ContentType`, + id: `typeWithTextField`, + }, + }, + }, + fields: { + title: { + "en-US": `Published With Invalid Changes`, + }, + textFieldNotRequired: { + "en-US": `This value is not required.`, + }, + textFieldRequired: { + "en-US": `This field is required.`, + }, + localizedTextFieldRequired: { + "en-US": `This field is required.`, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + id: `5bVDAzKgE3EcBQChWzYKWD`, + type: `Entry`, + createdAt: `2022-04-07T12:40:02.490Z`, + updatedAt: `2022-04-07T12:51:59.500Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 2, + contentType: { + sys: { + type: `Link`, + linkType: `ContentType`, + id: `typeWithTextField`, + }, + }, + }, + fields: { + title: { + "en-US": `Published`, + }, + textFieldNotRequired: { + "en-US": `This value is not required.`, + }, + textFieldRequired: { + "en-US": `This value is required.`, + }, + localizedTextFieldRequired: { + "en-US": `This field is required. Only english locale has a value.`, + }, + localizedTextFieldNotRequired: { + nl: `This field is not required. Only dutch locale has a value.`, + }, + }, + }, + ], + assets: [ + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + id: `GNeUY0UXLjICCg858dL4u`, + type: `Asset`, + createdAt: `2022-04-07T13:02:24.201Z`, + updatedAt: `2022-04-07T13:02:24.201Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 1, + }, + fields: { + title: { + "en-US": `Published With Invalid Changes`, + }, + file: { + "en-US": { + url: `//images.ctfassets.net/gher8kc6pxn0/GNeUY0UXLjICCg858dL4u/e9be37dbd109c51598562267eb522d31/Gatsby_Monogram.png`, + details: { + size: 77907, + image: { + width: 2000, + height: 2000, + }, + }, + fileName: `Gatsby_Monogram.png`, + contentType: `image/png`, + }, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + id: `63n9F33sETxyat165EXfiA`, + type: `Asset`, + createdAt: `2022-04-07T13:01:34.502Z`, + updatedAt: `2022-04-07T13:01:34.502Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 1, + }, + fields: { + title: { + "en-US": `Published With Valid Changes`, + }, + file: { + "en-US": { + url: `//images.ctfassets.net/gher8kc6pxn0/63n9F33sETxyat165EXfiA/ca1a1c68dc0252ac3468234cc7c3209e/Gatsby_Monogram_Black.png`, + details: { + size: 74574, + image: { + width: 2000, + height: 2000, + }, + }, + fileName: `Gatsby_Monogram_Black.png`, + contentType: `image/png`, + }, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + id: `5lDlIqBwlFPGJNoeaImMd3`, + type: `Asset`, + createdAt: `2022-04-07T13:00:29.381Z`, + updatedAt: `2022-04-07T13:00:29.381Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 1, + }, + fields: { + title: { + "en-US": `Published`, + }, + file: { + "en-US": { + url: `//images.ctfassets.net/gher8kc6pxn0/5lDlIqBwlFPGJNoeaImMd3/8624358d3433eca3a4a0dede0c47097a/Gatsby_Logo-png`, + details: { + size: 37313, + image: { + width: 2000, + height: 555, + }, + }, + fileName: `Gatsby_Logo-png`, + contentType: `image/png`, + }, + }, + }, + }, + ], + deletedEntries: [], + deletedAssets: [], + nextSyncToken: `dDFSNcK6bMO7woHDuMK7A8O_KWQDPl1Kw7TDkX_CvcOnwrBpwqnDqR7Ci8OSHURwNsK4wrZaw4pzwqllPw1zA2AJdMKfw7pte8OSPwNBwoNqw6DCrMKiNUVgw58TWcKYw61pWAFew4fCjMKWwrbCl2DCjA`, + }, + tagItems: [], + defaultLocale: `en-US`, + locales: [ + { + code: `en-US`, + name: `English (United States)`, + default: true, + fallbackCode: null, + sys: { + id: `5lKTAsR93lyeuMvcgKno5T`, + type: `Locale`, + version: 1, + }, + }, + { + code: `nl`, + name: `Dutch`, + default: false, + fallbackCode: null, + sys: { + id: `6VMQWqPJPxb8RZf93jGdvQ`, + type: `Locale`, + version: 1, + }, + }, + ], + space: { + sys: { + type: `Space`, + id: `gher8kc6pxn0`, + }, + name: `Gatsby Test Preview API`, + locales: [ + { + code: `en-US`, + default: true, + name: `English (United States)`, + fallbackCode: null, + }, + { + code: `nl`, + default: false, + name: `Dutch`, + fallbackCode: null, + }, + ], + }, + } +} diff --git a/packages/gatsby-source-contentful/src/__fixtures__/unpublished-fields-preview.js b/packages/gatsby-source-contentful/src/__fixtures__/unpublished-fields-preview.js new file mode 100644 index 0000000000000..4d21e7820ee07 --- /dev/null +++ b/packages/gatsby-source-contentful/src/__fixtures__/unpublished-fields-preview.js @@ -0,0 +1,587 @@ +exports.contentTypeItems = () => [ + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `ContentType`, + id: `typeWithTextField`, + revision: 4, + createdAt: `2022-04-07T12:36:28.853Z`, + updatedAt: `2022-04-07T12:51:05.868Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + displayField: `title`, + name: `Type With Text Field`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `textFieldNotRequired`, + name: `Text Field Not Required`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `textFieldRequired`, + name: `Text Field Required`, + type: `Symbol`, + localized: false, + required: true, + disabled: false, + omitted: false, + }, + { + id: `localizedTextFieldRequired`, + name: `Localized Text Field Required`, + type: `Symbol`, + localized: true, + required: true, + disabled: false, + omitted: false, + }, + { + id: `localizedTextFieldNotRequired`, + name: `Localized Text Field Not Required`, + type: `Symbol`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + ], + }, +] + +exports.initialSync = () => { + return { + currentSyncData: { + entries: [ + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `Entry`, + id: `ffDHCCwSEeozSX521OENf`, + contentType: { + sys: { + type: `Link`, + linkType: `ContentType`, + id: `typeWithTextField`, + }, + }, + revision: 2, + createdAt: `2022-04-07T12:40:07.338Z`, + updatedAt: `2022-04-07T12:55:34.729Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + fields: { + title: { + "en-US": `Published With Valid Changes`, + }, + textFieldNotRequired: { + "en-US": `This value is not required and changed.`, + }, + textFieldRequired: { + "en-US": `This value is required and changed`, + }, + localizedTextFieldRequired: { + "en-US": `This value is required and changed.`, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `Entry`, + id: `3PmbzmeujVtZ9DzWb8gKC6`, + contentType: { + sys: { + type: `Link`, + linkType: `ContentType`, + id: `typeWithTextField`, + }, + }, + revision: 3, + createdAt: `2022-04-07T12:40:33.039Z`, + updatedAt: `2022-04-07T12:55:04.122Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + fields: { + title: { + "en-US": `Published With Invalid Changes`, + }, + textFieldNotRequired: { + "en-US": `This value is not required but changed.`, + }, + localizedTextFieldRequired: { + nl: `This field has only a dutch value. But english is required.`, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `Entry`, + id: `6Ytmg0WgzqwcHCEiNxAoOF`, + contentType: { + sys: { + type: `Link`, + linkType: `ContentType`, + id: `typeWithTextField`, + }, + }, + revision: 0, + createdAt: `2022-04-07T12:45:39.600Z`, + updatedAt: `2022-04-07T12:52:16.910Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + fields: { + title: { + "en-US": `Unpublished With Valid Data`, + }, + textFieldRequired: { + "en-US": `This field is required.`, + }, + localizedTextFieldRequired: { + "en-US": `This field is required.`, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `Entry`, + id: `5bVDAzKgE3EcBQChWzYKWD`, + contentType: { + sys: { + type: `Link`, + linkType: `ContentType`, + id: `typeWithTextField`, + }, + }, + revision: 2, + createdAt: `2022-04-07T12:39:42.322Z`, + updatedAt: `2022-04-07T12:51:59.500Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + fields: { + title: { + "en-US": `Published`, + }, + textFieldNotRequired: { + "en-US": `This value is not required.`, + }, + textFieldRequired: { + "en-US": `This value is required.`, + }, + localizedTextFieldRequired: { + "en-US": `This field is required. Only english locale has a value.`, + }, + localizedTextFieldNotRequired: { + nl: `This field is not required. Only dutch locale has a value.`, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `Entry`, + id: `7yv71seYFiyVvFu16pvzBU`, + contentType: { + sys: { + type: `Link`, + linkType: `ContentType`, + id: `typeWithTextField`, + }, + }, + revision: 0, + createdAt: `2022-04-07T12:45:59.812Z`, + updatedAt: `2022-04-07T12:46:27.576Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + fields: { + title: { + "en-US": `Unpublished With Invalid Data`, + }, + textFieldNotRequired: { + "en-US": `This field is not required.`, + }, + }, + }, + ], + assets: [ + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `Asset`, + id: `GNeUY0UXLjICCg858dL4u`, + revision: 1, + createdAt: `2022-04-07T13:01:58.258Z`, + updatedAt: `2022-04-07T13:04:39.045Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + fields: { + title: { + "en-US": `Published With Invalid Data`, + nl: `Gatsby Monogram`, + }, + file: { + nl: { + url: `//images.ctfassets.net/gher8kc6pxn0/GNeUY0UXLjICCg858dL4u/88f73151cd9cbf2b75bdbe79e1fe1911/Gatsby_Monogram.png`, + details: { + size: 77907, + image: { + width: 2000, + height: 2000, + }, + }, + fileName: `Gatsby_Monogram.png`, + contentType: `image/png`, + }, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `Asset`, + id: `63n9F33sETxyat165EXfiA`, + revision: 1, + createdAt: `2022-04-07T13:00:33.684Z`, + updatedAt: `2022-04-07T13:04:29.449Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + fields: { + title: { + "en-US": `Published With Valid Data`, + nl: `Gatsby Logo Black`, + }, + file: { + "en-US": { + url: `//images.ctfassets.net/gher8kc6pxn0/63n9F33sETxyat165EXfiA/ca1a1c68dc0252ac3468234cc7c3209e/Gatsby_Monogram_Black.png`, + details: { + size: 74574, + image: { + width: 2000, + height: 2000, + }, + }, + fileName: `Gatsby_Monogram_Black.png`, + contentType: `image/png`, + }, + nl: { + url: `//images.ctfassets.net/gher8kc6pxn0/63n9F33sETxyat165EXfiA/c1129b9b36d1d2113c5708efb180d083/Gatsby_Logo_Black.png`, + details: { + size: 36793, + image: { + width: 2000, + height: 555, + }, + }, + fileName: `Gatsby_Logo_Black.png`, + contentType: `image/png`, + }, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `Asset`, + id: `1e1EpEOdZCZELT8UZAk8mD`, + revision: 0, + createdAt: `2022-04-07T13:02:47.259Z`, + updatedAt: `2022-04-07T13:04:04.909Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + fields: { + title: { + "en-US": `Unpublished With Valid Data`, + }, + file: { + "en-US": { + url: `//images.ctfassets.net/gher8kc6pxn0/1e1EpEOdZCZELT8UZAk8mD/0fcf3d8a72a9cbd90f4b1d4de0d99881/Gatsby_Logo-png`, + details: { + size: 37313, + image: { + width: 2000, + height: 555, + }, + }, + fileName: `Gatsby_Logo-png`, + contentType: `image/png`, + }, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `Asset`, + id: `3mtrGQlrFJTvpulIisyVuJ`, + revision: 0, + createdAt: `2022-04-07T13:03:29.938Z`, + updatedAt: `2022-04-07T13:03:42.990Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + fields: { + title: { + "en-US": `Unpublished With Invalid Data`, + }, + }, + }, + { + metadata: { + tags: [], + }, + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `gher8kc6pxn0`, + }, + }, + type: `Asset`, + id: `5lDlIqBwlFPGJNoeaImMd3`, + revision: 1, + createdAt: `2022-04-07T12:55:45.496Z`, + updatedAt: `2022-04-07T13:00:29.381Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + }, + fields: { + title: { + "en-US": `Published`, + }, + file: { + "en-US": { + url: `//images.ctfassets.net/gher8kc6pxn0/5lDlIqBwlFPGJNoeaImMd3/8624358d3433eca3a4a0dede0c47097a/Gatsby_Logo-png`, + details: { + size: 37313, + image: { + width: 2000, + height: 555, + }, + }, + fileName: `Gatsby_Logo-png`, + contentType: `image/png`, + }, + }, + }, + }, + ], + deletedEntries: [], + deletedAssets: [], + nextSyncToken: `dDFSNcK6bMO7woHDuMK7A8O_KWQDPl1Kw7TDkX_CvcOnwrBpwqnDqR7Ci8OSHURla8OTIQYqZD_Cl2F6ZcK5TcKMwp8hw7fDojYtLTkUwofCisKjwrvDu1AxPsOMPMK9KyPDoiXDlnrDuWfCqXJzWsO-`, + }, + tagItems: [], + defaultLocale: `en-US`, + locales: [ + { + code: `en-US`, + name: `English (United States)`, + default: true, + fallbackCode: null, + sys: { + id: `5lKTAsR93lyeuMvcgKno5T`, + type: `Locale`, + version: 1, + }, + }, + { + code: `nl`, + name: `Dutch`, + default: false, + fallbackCode: null, + sys: { + id: `6VMQWqPJPxb8RZf93jGdvQ`, + type: `Locale`, + version: 1, + }, + }, + ], + space: { + sys: { + type: `Space`, + id: `gher8kc6pxn0`, + }, + name: `Gatsby Test Preview API`, + locales: [ + { + code: `en-US`, + default: true, + name: `English (United States)`, + fallbackCode: null, + }, + { + code: `nl`, + default: false, + name: `Dutch`, + fallbackCode: null, + }, + ], + }, + } +} diff --git a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js index ca08c3debf782..6b796fc4449bb 100644 --- a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js +++ b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js @@ -12,6 +12,8 @@ import { makeId } from "../normalize" import startersBlogFixture from "../__fixtures__/starter-blog-data" import richTextFixture from "../__fixtures__/rich-text-data" import restrictedContentTypeFixture from "../__fixtures__/restricted-content-type" +import unpublishedFieldDelivery from "../__fixtures__/unpublished-fields-delivery" +import unpublishedFieldPreview from "../__fixtures__/unpublished-fields-preview" jest.mock(`../fetch`) jest.mock(`gatsby-core-utils`, () => { @@ -120,14 +122,30 @@ describe(`gatsby-node`, () => { const getNodes = () => Array.from(currentNodeMap.values()).map(_.cloneDeep) const getNode = id => _.cloneDeep(currentNodeMap.get(id)) - const getFieldValue = (value, locale, defaultLocale) => - value[locale] ?? value[defaultLocale] + const getFieldValue = ( + value, + locale, + defaultLocale, + localized = false, + noLocaleFallback = false + ) => { + if (!value) { + return null + } + if (!localized) { + return value[defaultLocale] + } + if (noLocaleFallback) { + return value[locale] ?? null + } + return value[locale] ?? value[defaultLocale] + } const simulateGatsbyBuild = async function ( pluginOptions = defaultPluginOptions ) { await createSchemaCustomization( - { schema, actions, reporter, cache, store }, + { schema, actions, reporter, cache }, pluginOptions ) @@ -158,7 +176,12 @@ describe(`gatsby-node`, () => { }) } - const testIfEntriesExists = (entries, contentTypes, locales) => { + const testIfEntriesExists = ( + entries, + contentTypes, + locales, + noLocaleFallback = false + ) => { const defaultLocale = locales[0] const nodeMap = new Map() @@ -181,15 +204,18 @@ describe(`gatsby-node`, () => { const matchedObject = {} Object.keys(entry.fields).forEach(field => { + const fieldDefinition = currentContentType.fields.find( + cField => cField.id === field + ) + const value = getFieldValue( entry.fields[field], locale, - defaultLocale + defaultLocale, + fieldDefinition.localized, + noLocaleFallback ) - const fieldDefinition = currentContentType.fields.find( - cField => cField.id === field - ) switch (fieldDefinition.type) { case `Link`: { const linkId = createNodeId( @@ -229,7 +255,7 @@ describe(`gatsby-node`, () => { break } default: - matchedObject[field] = value + matchedObject[field] = value ?? null } }) @@ -303,7 +329,11 @@ describe(`gatsby-node`, () => { }) } - const testIfAssetsExistsAndMatch = (assets, locales) => { + const testIfAssetsExistsAndMatch = ( + assets, + locales, + noLocaleFallback = false + ) => { const defaultLocale = locales[0] locales.forEach(locale => { assets.forEach(asset => { @@ -317,15 +347,35 @@ describe(`gatsby-node`, () => { }) ) + const file = getFieldValue( + asset.fields.file, + locale, + defaultLocale, + true, + noLocaleFallback + ) + if (!file) { + return + } + // check if asset exists expect(getNode(assetId)).toMatchObject({ - title: getFieldValue(asset.fields.title, locale, defaultLocale), - description: getFieldValue( - asset.fields.description, + title: getFieldValue( + asset.fields.title, locale, - defaultLocale + defaultLocale, + true, + noLocaleFallback ), - file: getFieldValue(asset.fields.file, locale, defaultLocale), + description: + getFieldValue( + asset.fields.description, + locale, + defaultLocale, + true, + noLocaleFallback + ) || ``, + file, }) }) }) @@ -973,6 +1023,138 @@ describe(`gatsby-node`, () => { }) }) + it(`is able to render unpublished fields in Delivery API`, async () => { + const locales = [`en-US`, `nl`] + + // @ts-ignore + fetchContent.mockImplementationOnce(unpublishedFieldDelivery.initialSync) + // @ts-ignore + fetchContentTypes.mockImplementationOnce( + unpublishedFieldDelivery.contentTypeItems + ) + + // initial sync + await simulateGatsbyBuild() + + testIfContentTypesExists(unpublishedFieldDelivery.contentTypeItems()) + testIfEntriesExists( + unpublishedFieldDelivery.initialSync().currentSyncData.entries, + unpublishedFieldDelivery.contentTypeItems(), + locales, + true + ) + + testIfAssetsExistsAndMatch( + unpublishedFieldDelivery.initialSync().currentSyncData.assets, + locales, + true + ) + + expect(actions.createNode).toHaveBeenCalledTimes(10) + expect(actions.deleteNode).toHaveBeenCalledTimes(0) + expect(actions.touchNode).toHaveBeenCalledTimes(0) + expect(reporter.info.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + "Contentful: 0 new entries", + ], + Array [ + "Contentful: 3 updated entries", + ], + Array [ + "Contentful: 0 deleted entries", + ], + Array [ + "Contentful: 0 cached entries", + ], + Array [ + "Contentful: 3 new assets", + ], + Array [ + "Contentful: 0 updated assets", + ], + Array [ + "Contentful: 0 cached assets", + ], + Array [ + "Contentful: 0 deleted assets", + ], + Array [ + "Creating 3 Contentful Type With Text Field nodes", + ], + Array [ + "Creating 3 Contentful asset nodes", + ], + ] + `) + }) + + it(`is able to render unpublished fields in Preview API`, async () => { + const locales = [`en-US`, `nl`] + + // @ts-ignore + fetchContent.mockImplementationOnce(unpublishedFieldPreview.initialSync) + // @ts-ignore + fetchContentTypes.mockImplementationOnce( + unpublishedFieldPreview.contentTypeItems + ) + + // initial sync + await simulateGatsbyBuild() + + testIfContentTypesExists(unpublishedFieldPreview.contentTypeItems()) + testIfEntriesExists( + unpublishedFieldPreview.initialSync().currentSyncData.entries, + unpublishedFieldPreview.contentTypeItems(), + locales, + true + ) + + testIfAssetsExistsAndMatch( + unpublishedFieldPreview.initialSync().currentSyncData.assets, + locales, + true + ) + + expect(actions.createNode).toHaveBeenCalledTimes(16) + expect(actions.deleteNode).toHaveBeenCalledTimes(0) + expect(actions.touchNode).toHaveBeenCalledTimes(0) + expect(reporter.info.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + "Contentful: 0 new entries", + ], + Array [ + "Contentful: 5 updated entries", + ], + Array [ + "Contentful: 0 deleted entries", + ], + Array [ + "Contentful: 0 cached entries", + ], + Array [ + "Contentful: 3 new assets", + ], + Array [ + "Contentful: 2 updated assets", + ], + Array [ + "Contentful: 0 cached assets", + ], + Array [ + "Contentful: 0 deleted assets", + ], + Array [ + "Creating 5 Contentful Type With Text Field nodes", + ], + Array [ + "Creating 5 Contentful asset nodes", + ], + ] + `) + }) + it(`panics when localeFilter reduces locale list to 0`, async () => { // @ts-ignore fetchContent.mockImplementationOnce(startersBlogFixture.initialSync) diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index f0d7dad2b4056..7bf50e21fc85d 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -15,6 +15,9 @@ const shouldUpgradeGatsbyVersion = lt(gatsbyVersion, GATSBY_VERSION_MANIFEST_V2) && !gatsbyVersionIsPrerelease export const getLocalizedField = ({ field, locale, localesFallback }) => { + if (!field) { + return null + } if (!_.isUndefined(field[locale.code])) { return field[locale.code] } else if ( @@ -717,7 +720,13 @@ export const createAssetNodes = ({ localesFallback, }) - const file = assetItem.fields.file ? getField(assetItem.fields.file) : {} + const file = getField(assetItem.fields?.file) ?? null + + // Skip empty and unprocessed assets in Preview API + if (!file || !file.url || !file.contentType || !file.fileName) { + return + } + const assetNode = { contentful_id: assetItem.sys.id, spaceId: space.sys.id, @@ -740,10 +749,12 @@ export const createAssetNodes = ({ }, url: `https:${file.url}`, placeholderUrl: `https:${file.url}?w=%width%&h=%height%`, + // These fields are optional for edge cases in the Preview API and Contentfuls asset processing mimeType: file.contentType, filename: file.fileName, - width: file.details?.image?.width, - height: file.details?.image?.height, + width: file.details?.image?.width ?? null, + height: file.details?.image?.height ?? null, + size: file.details?.size ?? null, } // Link tags