Documentation example

Uses the schema.graphql definition from the main content-api to create mock content for development / testing.

This mock server is created using Apollo Server's mocking functionality. The mock data is defined inside the mock folder

The mocking definition files use the casual package to generate useful mock data (any fields that do not use casual will generate a basic response based on the type of field defined, e.g. String)

Specifying response structure

Some responses can be controlled by using specific urls and query parameters

Content Blocks

To control what content blocks are returned on a specific content type page append the query param ?contentBlocks to the url with the value <CONTENTBLOCKTYPE>*<NUMBEROFITEMS> concatenated with the + sign

E.G.

/article?contentBlocks=TextBlock*4+ImageBlock*2+HeaderBlock+TextBlock*5
  

The above will return 4 Text Blocks, 2 Image blocks, 1 Header block and 5 Text blocks

Content Block Arguments

Certain content blocks have been configured so that they can accept arguments in a JSON structure. Examples are below

TextBlock

Global Settings

For any sites using the getSettings(url: $url) query (including the url param) any of the results can be overriden by passing the getSettings param a JSON string. Any items specified in the string will be overridden (the rest will be mocked as usual)

e.g.

 /article?getSettings={"adSettings":{"beforeInlineDesktopAds":100,"betweenInlineDesktopAds":40}}
  

Will override the beforeInlineDesktopAds and betweenInlineDesktopAds values from the mock server

When used in conjunction with the ContentBlock arguments above we will be able to mock the ad injection logic (and automate tests for it)

e.g.

/article?contentBlocks=TextBlock({"wordCount":50})*4&getSettings={"adSettings":{"beforeInlineDesktopAds":0,"betweenInlineDesktopAds":40}}
  

Code example

ContentBlocks Mock Resolver


    import { parseUrl } from 'query-string';
    import { contentBlockRenderer } from './ContentBlocks';

    const ContentEntity = () => ({
      body: (args) => {
        if (args.url) {
          const {
            query = {},
          } = parseUrl(args.url);
          const {
            contentBlocks,
          } = query;
          if (contentBlocks) {
            return contentBlockRenderer(contentBlocks);
          }
        }
        return new MockList([8, 20]);
      },
    );
  

ContentBlocks Mocking Logic


    import casual from 'casual';
    import { MockList } from 'graphql-tools';
    import { Image } from './Media';

    export const blocks = {
      TextBlock: (args = {}) => {
        const {
          wordCount = casual.integer(50, 150),
        } = args;
        return {
          type: 'TEXT',
          data: JSON.stringify(`

${casual.words(wordCount)} (paragraph wordcount: ${wordCount})

`), wordCount, } }, HeaderBlock: () => ({ type: 'HEADER', data: JSON.stringify({ size: casual.integer(1, 6), text: casual.title, }), }), ImageBlock: () => ({ type: 'IMAGE', data: JSON.stringify(Image()), }), } const prepareBlock = ( data = casual.random_value(blocks), args = {}, ) => { const typename = data.name; return { ...data(args), typename, __typename: typename, }; } export const ContentBlock = () => prepareBlock(); const splitItem = item => { const itemSplit = item.split('*'); const count = parseInt(itemSplit[1] ? parseInt(itemSplit[1]) : 1); const args = item.substring( item.lastIndexOf("(") + 1, item.lastIndexOf(")") ); const type = itemSplit[0].split('(')[0]; return { type, count, args: args && JSON.parse(args), } } export const contentBlockRenderer = (contentBlocks) => { const blockArray = []; contentBlocks.split(' ').forEach(item => { const { type, count, args } = splitItem(item); if (blocks[type]) { for (var i = 0; i < count; i++) blockArray.push(prepareBlock(blocks[type], args)); } }); return blockArray; }

GlobalSettings Mock Resolver



    import merge from 'lodash.merge';

    export const GlobalSettings = (_, args = {}) => {
    
      const defaultSettings = {
        adSettings: {
          beforeInlineDesktopAds: 50,
          betweenInlineDesktopAds: 20,
        },
      }
      if (args.url) {
        const {
          query = {},
        } = parseUrl(args.url);
        const {
          getSettings,
        } = query;
        if (getSettings) {
          return merge(defaultSettings, JSON.parse(getSettings));
        }
      }
      return defaultSettings
    };