UNPKG

@pact-foundation/pact

Version:
257 lines (256 loc) 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const graphql_1 = require("./graphql"); const matchers_1 = require("./matchers"); describe('GraphQLInteraction', () => { let interaction; beforeEach(() => { interaction = new graphql_1.GraphQLInteraction(); }); describe('#withOperation', () => { describe('when given a valid operation', () => { it('creates a GraphQL Interaction', () => { interaction.uponReceiving('a request'); interaction.withRequest({ path: '/graphql', method: 'POST', }); interaction.withOperation('query'); interaction.withQuery('{ hello }'); interaction.willRespondWith({ status: 200, body: { data: {} }, }); // biome-ignore lint/suspicious/noExplicitAny: body sub-properties (query/variables/operationName) are typed as AnyTemplate and need runtime assertions const json = interaction.json(); expect(json.request.body.operationName).toBe('query'); }); }); describe('when given an invalid operation', () => { it('fails with an error', () => { expect(interaction.withOperation.bind('aoeu')).toThrow(Error); }); }); describe('when given a null operation', () => { it('creates a GrphQL Interaction', () => { interaction.uponReceiving('a request'); interaction.withRequest({ path: '/graphql', method: 'POST', }); interaction.withOperation(null); interaction.withQuery('{ hello }'); interaction.willRespondWith({ status: 200, body: { data: {} }, }); // biome-ignore lint/suspicious/noExplicitAny: body sub-properties (query/variables/operationName) are typed as AnyTemplate and need runtime assertions const json = interaction.json(); expect(json.request.body.operationName).toBeNull(); }); }); }); describe('#withVariables', () => { describe('when given a set of variables', () => { it('adds the variables to the payload', () => { interaction.uponReceiving('a request'); interaction.withRequest({ path: '/graphql', method: 'POST', }); interaction.withOperation('query'); interaction.withQuery('{ hello }'); interaction.withVariables({ foo: 'bar', }); interaction.willRespondWith({ status: 200, body: { data: {} }, }); // biome-ignore lint/suspicious/noExplicitAny: body sub-properties (query/variables/operationName) are typed as AnyTemplate and need runtime assertions const json = interaction.json(); expect(json.request.body.variables).toEqual({ foo: 'bar' }); }); }); describe('when no variables are provided', () => { it('does not add the variables property to the payload', () => { interaction.uponReceiving('a request'); interaction.withRequest({ path: '/graphql', method: 'POST', }); interaction.withOperation('query'); interaction.withQuery('{ hello }'); interaction.willRespondWith({ status: 200, body: { data: {} }, }); // biome-ignore lint/suspicious/noExplicitAny: body sub-properties (query/variables/operationName) are typed as AnyTemplate and need runtime assertions const json = interaction.json(); expect(json.request.body).not.toHaveProperty('variables'); }); }); describe('when an empty variables object is presented', () => { it('adds the variables property to the payload', () => { interaction.uponReceiving('a request'); interaction.withRequest({ path: '/graphql', method: 'POST', }); interaction.withOperation('query'); interaction.withQuery('{ hello }'); interaction.withVariables({}); interaction.willRespondWith({ status: 200, body: { data: {} }, }); // biome-ignore lint/suspicious/noExplicitAny: body sub-properties (query/variables/operationName) are typed as AnyTemplate and need runtime assertions const json = interaction.json(); expect(json.request.body).toHaveProperty('variables'); }); }); }); describe('#withQuery', () => { beforeEach(() => { interaction.uponReceiving('a request'); interaction.withRequest({ path: '/graphql', method: 'POST', }); interaction.withOperation('query'); interaction.withQuery('{ hello }'); interaction.withVariables({ foo: 'bar', }); interaction.willRespondWith({ status: 200, body: { data: {} }, }); }); describe('when given an empty query', () => { it('fails with an error', () => { // biome-ignore lint/suspicious/noExplicitAny: deliberately passing null to test error handling on invalid input expect(() => interaction.withQuery(null)).toThrow(); }); }); describe('when given an invalid query', () => { it('fails with an error', () => { expect(() => interaction.withQuery('{ not properly terminated')).toThrow(Error); }); }); describe('when given a valid query', () => { describe('without variables', () => { it('adds regular expressions for the whitespace in the query', () => { interaction.uponReceiving('a request'); interaction.withRequest({ path: '/graphql', method: 'POST', }); interaction.withOperation('query'); interaction.withQuery('{ hello }'); interaction.willRespondWith({ status: 200, body: { data: {} }, }); // biome-ignore lint/suspicious/noExplicitAny: body sub-properties (query/variables/operationName) are typed as AnyTemplate and need runtime assertions const json = interaction.json(); expect((0, matchers_1.isMatcher)(json.request.body.query)).toBe(true); const r = new RegExp(json.request.body.query.regex, 'g'); const lotsOfWhitespace = `{ hello }`; expect(r.test(lotsOfWhitespace)).toBe(true); }); }); describe('and variables', () => { it('adds regular expressions for the whitespace in the query', () => { interaction.withQuery(`{ Hello(id: $id) { name } }`); interaction.withVariables({ name: 'bar', }); // biome-ignore lint/suspicious/noExplicitAny: body sub-properties (query/variables/operationName) are typed as AnyTemplate and need runtime assertions const json = interaction.json(); expect((0, matchers_1.isMatcher)(json.request.body.query)).toBe(true); const r = new RegExp(json.request.body.query.regex, 'g'); const lotsOfWhitespace = `{ Hello(id: $id) { name } }`; expect(r.test(lotsOfWhitespace)).toBe(true); }); }); }); }); describe('#json', () => { describe('when query is empty', () => { it('fails with an error', () => { expect(() => interaction.json()).toThrow(); }); }); describe('when description is empty', () => { it('fails with an error', () => { interaction.withQuery('{ hello }'); return expect(() => interaction.json()).toThrow(); }); }); describe('when no operation is provided', () => { it('does not be present in unmarshaled body', () => { interaction.uponReceiving('a request'); interaction.withRequest({ path: '/graphql', method: 'POST', }); interaction.withQuery('{ hello }'); interaction.willRespondWith({ status: 200, body: { data: {} }, }); // biome-ignore lint/suspicious/noExplicitAny: body sub-properties (query/variables/operationName) are typed as AnyTemplate and need runtime assertions const json = interaction.json(); expect(json.request.body).not.toHaveProperty('operationName'); }); }); }); describe('when given a valid query', () => { it('marshals the query to JSON', () => { interaction.uponReceiving('a request'); interaction.withRequest({ path: '/graphql', method: 'POST', }); interaction.withOperation('query'); interaction.withQuery('{ hello }'); interaction.willRespondWith({ status: 200, body: { data: {} }, }); // biome-ignore lint/suspicious/noExplicitAny: body sub-properties (query/variables/operationName) are typed as AnyTemplate and need runtime assertions const json = interaction.json(); expect((0, matchers_1.isMatcher)(json.request.body.query)).toBe(true); expect(json.request.body.query.getValue()).toBe('{ hello }'); }); }); describe('headers are not duplicated', () => { describe('headers are properly cased', () => { it('content-type header is properly cased', () => { interaction.uponReceiving('a request'); interaction.withRequest({ path: '/graphql', method: 'POST', }); interaction.withOperation('query'); interaction.withQuery('{ hello }'); interaction.willRespondWith({ status: 200, body: { data: {} }, }); // biome-ignore lint/suspicious/noExplicitAny: body sub-properties (query/variables/operationName) are typed as AnyTemplate and need runtime assertions const json = interaction.json(); expect(json.request.headers).toEqual({ 'Content-Type': 'application/json', }); }); }); }); }); //# sourceMappingURL=graphql.spec.js.map