Back to Repositories

Validating WordPress Plugin Options Schema in GatsbyJS

This test suite validates the plugin options schema for the Gatsby WordPress source plugin, ensuring proper configuration validation and error handling. It verifies both minimal and comprehensive plugin configurations while testing required parameters and custom settings.

Test Coverage Overview

The test suite provides comprehensive coverage of the plugin options schema validation.

  • Tests minimal valid configuration with required URL parameter
  • Validates error handling for missing required variables
  • Verifies extensive custom configuration options including debug settings, authentication, media handling, and type-specific configurations
  • Covers edge cases in configuration validation

Implementation Analysis

The implementation uses Jest’s describe/it pattern for structured test organization. The tests leverage the testPluginOptionsSchema utility from gatsby-plugin-utils to validate configuration objects against the defined schema.

Each test case follows a consistent pattern of schema validation and assertion checking, utilizing Jest’s expect statements for verification.

Technical Details

  • Testing Framework: Jest
  • Key Dependencies: gatsby-plugin-utils, gatsby-source-wordpress
  • Test Utilities: testPluginOptionsSchema
  • Configuration Validation: Checks against pluginOptionsSchema
  • Assertion Methods: expect().toEqual()

Best Practices Demonstrated

The test suite exhibits several testing best practices for configuration validation.

  • Isolated test cases for specific validation scenarios
  • Clear test descriptions that indicate purpose
  • Comprehensive validation of both success and error cases
  • Structured assertion checking for validity and error messages
  • Progressive complexity in test cases from minimal to full configuration

gatsbyjs/gatsby

packages/gatsby-source-wordpress/__tests__/plugin-options-schema.test.js

            
import { testPluginOptionsSchema } from "gatsby-plugin-utils"
import { pluginOptionsSchema } from "gatsby-source-wordpress/dist/steps/declare-plugin-options-schema"

describe(`pluginOptionsSchema`, () => {
  it(`should validate a minimal, valid config`, async () => {
    const { isValid, errors } = await testPluginOptionsSchema(pluginOptionsSchema, {
      url: `http://localhost:8000/graphql`,
    })

    expect(isValid).toEqual(true)
    expect(errors).toEqual([])
  })

  it(`should invalidate a config missing required vars`, async () => {
    const expectedErrors = [`"url" is required`,]

    const { isValid, errors } = await testPluginOptionsSchema(
      pluginOptionsSchema,
      {}
    )

    expect(isValid).toEqual(false)
    expect(errors).toEqual(expectedErrors)
  })

  it(`should validate a fully custom config`, async () => {
    const { isValid, errors } = await testPluginOptionsSchema(
      pluginOptionsSchema,
      {
        url: `https://fakeurl.com/graphql`,
        verbose: false,
        debug: {
          throwRefetchErrors: true,
          graphql: {
            showQueryOnError: false,
            showQueryVarsOnError: false,
            copyQueryOnError: false,
            panicOnError: false,
            onlyReportCriticalErrors: true,
            copyNodeSourcingQueryAndExit: false,
            writeQueriesToDisk: false,
          },
          timeBuildSteps: false,
          disableCompatibilityCheck: false,
        },
        develop: {
          nodeUpdateInterval: 300,
          hardCacheMediaFiles: false,
          hardCacheData: false,
        },
        production: {
          hardCacheMediaFiles: false,
        },
        auth: {
          htaccess: {
            username: `test`,
            password: `test`,
          },
        },
        schema: {
          queryDepth: 15,
          circularQueryLimit: 5,
          typePrefix: `Wp`,
          timeout: 30 * 1000, // 30 seconds
          perPage: 100,
        },
        excludeFieldNames: [],
        html: {
          useGatsbyImage: true,
          imageMaxWidth: null,
          fallbackImageMaxWidth: 100,
          imageQuality: 90,
          createStaticFiles: true,
        },
        type: {
          __all: {
            excludeFieldNames: [`viewer`],
          },
          RootQuery: {
            excludeFieldNames: [`schemaMd5`],
          },
          MediaItem: {
            lazyNodes: true,
            localFile: {
              excludeByMimeTypes: [`video/mp4`],
              maxFileSizeBytes: 1400000,
            },
          },
          ContentNode: {
            nodeInterface: true,
          },
          Menu: {
            beforeChangeNode: () => {},
          },
          MenuItem: {
            beforeChangeNode: null,
          },
          Page: {
            beforeChangeNode: `./docs-generation.test.js`,
          },
          Post: {
            beforeChangeNode: () => {
              console.log(`Hi from an inline fn!`)
            },
          },
          EnqueuedScript: {
            exclude: true,
          },
          EnqueuedThing: {
            exclude: null,
          },
        },
      }
    )

    expect(isValid).toEqual(true)
    expect(errors).toEqual([])
  })
})