Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mercurius-integration-testing

Package Overview
Dependencies
Maintainers
2
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mercurius-integration-testing

[![npm version](https://badge.fury.io/js/mercurius-integration-testing.svg)](https://badge.fury.io/js/mercurius-integration-testing) [![codecov](https://codecov.io/gh/PabloSzx/mercurius-integration-testing/branch/master/graph/badge.svg)](https://codecov.i

  • 9.0.0
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
3.7K
decreased by-22.91%
Maintainers
2
Weekly downloads
 
Created
Source

mercurius-integration-testing

npm version codecov

pnpm add mercurius-integration-testing
# or
yarn add mercurius-integration-testing
# or
npm install mercurius-integration-testing

Features

  • query, mutation & subscription support.
  • DocumentNode and string support
  • TypeScript support
  • batchQueries support.
  • headers management.
  • cookies management.

Table of Contents

Usage

// app.ts | app.js
import Fastify from 'fastify'
import Mercurius from 'mercurius'
import schema from './schema'
import { buildContext } from './buildContext'

export const app = Fastify()

app.register(Mercurius, {
  schema,
  resolvers: {},
  context: buildContext,
  allowBatchedQueries: true,
})
// integration.test.js | integration.test.ts

import { createMercuriusTestClient } from 'mercurius-integration-testing'
import { app } from '../app'

// ...

const testClient = createMercuriusTestClient(app)

expect(testClient.query('query { helloWorld }')).resolves.toEqual({
  data: {
    helloWorld: 'helloWorld',
  },
})

API

createMercuriusTestClient

Create a testing client instance, you should give it the fastify instance in which Mercurius was already registered, and optionally, some options

const client = createMercuriusTestClient(app, {
  /**
   * Optional, specify headers to be added to every request in the client
   */
  headers: {
    authorization: 'hello-world',
  },
  /**
   * Optional, by default it points to /graphql
   */
  url: '/graphql',
  /**
   * Optional, specify cookies to be added to every request in the client
   */
  cookies: {
    authorization: 'hello-world',
  },
})
query, mutate

.query and .mutate are basically the same function, but for readability, both exists

// You can give it a simple string
const queryResponse = await client.query(`
query {
  helloWorld
}
`)

// Data returned from the API
queryResponse.data

// Possible array of errors from the API
queryResponse.errors

// You can also call `mutate`
// to improve readability for mutations
const mutationResponse = await client.mutate(`
mutation {
  helloWorld
}
`)
DocumentNode support
// You can also give them `DocumentNode`s
// from `graphql-tag` or equivalents
await client.query(gql`
  query {
    helloWorld
  }
`)
Variables
// You can give variables in the second parameter options
await client.query(
  `
  query($foo: String!) {
    hello(foo: $foo)
  }
`,
  {
    variables: {
      foo: 'bar',
    },
  }
)
Other options
await client.query(
  `
  query example {
    helloExample
  }
`,
  {
    // You can specify operation name if the queries
    // are named
    operationName: 'helloExample',
    // Query specific headers
    // These are going to be "merged" with the client set headers
    headers: {
      hello: 'world',
    },

    // Query specific cookies
    // These are going to be "merged" with the client set headers
    cookies: {
      foo: 'bar',
    },
  }
)
setHeaders

You can change the default client headers whenever

client.setHeaders({
  authorization: 'other-header',
})
setCookies

You can change the default client cookies whenever

client.setCookies({
  authorization: 'other-cookie',
})
batchQueries

If allowBatchedQueries is set in the Mercurius registration, you can call some queries together

const batchedResponse = await client.batchQueries(
  [
    {
      query: `
  query {
    helloWorld
  }
  `,
    },
    {
      query: `
  query($name: String!) {
    user(name: $name) {
      email
    }
  }
  `,
      variables: {
        name: 'bob',
      },
      // operationName: "you-can-specify-it-here-if-needed"
    },
  ],
  // Optional
  {
    // Optional request specific cookies
    cookies: {
      foo: 'bar',
    },
    // Optional request specific headers
    headers: {
      foo: 'bar',
    },
  }
)

batchedResponse ===
  [
    { data: { helloWorld: 'foo' } },
    { data: { user: { email: 'hello@world.com' } } },
  ]
subscribe

If you are not already calling .listen(PORT) somewhere, it will automatically call it, assigning a random available port, this means you will have to manually call .close() somewhere

.subscribe returns a promise that resolves when the subscription connection is made

headers & cookies are applied the same as in .query and .mutate

const subscription = await client.subscribe({
  query: `
  subscription {
    notificationAdded {
      id
      message
    }
  }
  `,
  onData(response) {
    // response.errors => array of graphql errors or undefined
    response ==
      { data: { notificationAdded: { id: 1, message: 'hello world' } } }
  },
  // Optional
  variables: { foo: 'bar' },
  // Optional
  operationName: 'name_if_is_named_query',
  // Optional, initialization payload, usually for authorization
  initPayload: { authorization: '<token>' },
  // Optional, subscription specific cookies
  cookies: {
    authorization: '<token>',
  },
  // Optional, subscription specific headers
  headers: {
    authorization: '<token>',
  },
})

// You can manually call the unsubscribe

subscription.unsubscribe()

// You will need to manually close the fastify instance somewhere

app.close()
getFederatedEntity

In a federated service it's useful to test if a service is extending the entity correctly.

This function is a wrapper around _entities query.

An entity can be federated on a single field:

import { mercuriusFederationPlugin } from '@mercuriusjs/federation'

const schema = `
    type Post @key(fields: "id") {
      id: ID! @external
      description: String!
    }
  
    extend type User @key(fields: "id") {
      id: ID! @external
      posts: [Post!]!
    }
  `

const app = fastify()
app.register(mercuriusFederationPlugin, {
  schema,
  resolvers: {
    User: {
      posts: () => [{ id: 'post-id', description: 'Post description' }],
    },
  },
})

const client = createMercuriusTestClient(app)

const entity = await client.getFederatedEntity({
  typename: 'User',
  keys: { id: 'user1' },
  typeQuery: `
        id
        posts {
          id
          description
        }`,
})

entity ===
  {
    __typename: 'User',
    id: 'user1',
    posts: [
      {
        id: 'post-id',
        description: 'Post description',
      },
    ],
  }

or on multiple fields:

const schema = `
      type ProductCategory {
        id: ID!
        name: String!
      }
    
      extend type Product @key(fields: "sku") @key(fields: "upc") {
        upc: String! @external
        sku: Int! @external
        category: ProductCategory
      }
    `

const app = fastify()
app.register(mercuriusFederationPlugin, {
  schema,
  resolvers: {
    Product: {
      category: () => ({ id: 'product-category', name: 'Stub category' }),
    },
  },
})

const client = createMercuriusTestClient(app)

const entity = await client.getFederatedEntity({
  typename: 'Product',
  keys: { sku: 1, upc: 'upc' },
  typeQuery: `
          upc
          sku
          category {
            id
            name
          }`,
})

entity ===
  {
    __typename: 'Product',
    upc: 'upc',
    sku: 1,
    category: {
      id: 'product-category',
      name: 'Stub category',
    },
  }
TypeScript
const dataResponse = await client.query<{
  helloWorld: string
}>(`
query {
  helloWorld
}
`)

// string
dataResponse.data.helloWorld

const variablesResponse = await client.query<
  {
    user: {
      email: string
    }
  },
  {
    name: string
  }
>(
  `
  query($name: String!) {
    user(name: $name) {
      email
    }
  }
`,
  {
    variables: {
      name: 'bob',
    },
  }
)

// string
variablesResponse.data.user.email

await client.subscribe<
  {
    helloWorld: string
  },
  {
    foo: string
  }
>({
  query: `
  subscription($foo: String!) {
    helloWorld(foo: $foo)
  }
  `,
  variables: {
    // Error, Type 'number' is not assignable to type 'string'.
    foo: 123,
  },
  onData(response) {
    // string
    response.data.helloWorld
  },
})

License

MIT

Keywords

FAQs

Package last updated on 18 Sep 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc