diff --git a/plugin/gatsby-node.js b/plugin/gatsby-node.js index 404f160..6072d73 100644 --- a/plugin/gatsby-node.js +++ b/plugin/gatsby-node.js @@ -3,6 +3,24 @@ const { newCloudinary, getResourceOptions } = require('./utils'); const REPORTER_PREFIX = `gatsby-source-cloudinary`; const NODE_TYPE = `CloudinaryMedia`; +exports.pluginOptionsSchema = ({ Joi }) => { + return Joi.object({ + cloudName: Joi.string().required(), + apiKey: Joi.string().required(), + apiSecret: Joi.string().required(), + resourceType: Joi.string().default('image'), + type: Joi.string().default('all'), + maxResults: Joi.number().integer().positive().default(10), + resultsPerPage: Joi.number() + .integer() + .positive() + .default(Joi.ref('maxResults')), + tags: Joi.boolean().default(false), + prefix: Joi.string(), + context: Joi.boolean(), + }); +}; + const getNodeData = (gatsbyUtils, media, cloudName) => { const { createNodeId, createContentDigest } = gatsbyUtils; diff --git a/plugin/gatsby-node.test.js b/plugin/gatsby-node.test.js new file mode 100644 index 0000000..7ee1ad7 --- /dev/null +++ b/plugin/gatsby-node.test.js @@ -0,0 +1,72 @@ +import Joi from 'joi'; +import { testPluginOptionsSchema } from 'gatsby-plugin-utils'; +import { pluginOptionsSchema } from './gatsby-node'; + +describe('pluginOptionsSchema', () => { + test('should validate minimal correct options', async () => { + const options = { + cloudName: 'cloudName', + apiKey: 'apiKey', + apiSecret: 'apiSecret', + }; + + const { isValid } = await testPluginOptionsSchema( + pluginOptionsSchema, + options, + ); + + expect(isValid).toBe(true); + }); + + test('should invalidate incorrect options', async () => { + const options = { + cloudName: 120, + apiKey: '', + resourceType: '', + type: 30, + maxResults: '', + resultsPerPage: 'hello', + tags: 'world', + prefix: 800, + context: '', + }; + + const { isValid, errors } = await testPluginOptionsSchema( + pluginOptionsSchema, + options, + ); + + expect(isValid).toBe(false); + expect(errors).toEqual([ + `"cloudName" must be a string`, + `"apiKey" is not allowed to be empty`, + `"apiSecret" is required`, + `"resourceType" is not allowed to be empty`, + `"type" must be a string`, + `"maxResults" must be a number`, + `"resultsPerPage" must be a number`, + `"tags" must be a boolean`, + `"prefix" must be a string`, + `"context" must be a boolean`, + ]); + }); + + test('should add defaults', async () => { + const schema = pluginOptionsSchema({ Joi }); + const options = { + cloudName: 'cloudName', + apiKey: 'apiKey', + apiSecret: 'apiSecret', + }; + const { value } = schema.validate(options); + + expect(value).toEqual({ + ...options, + resourceType: 'image', + maxResults: 10, + resultsPerPage: 10, + tags: false, + type: 'all', + }); + }); +});