Skip to content

Commit

Permalink
feat(apollo-graphql): add Apollo specific GraphQL interface. Fixes #254
Browse files Browse the repository at this point in the history
  • Loading branch information
mefellows committed Nov 27, 2018
1 parent 5b12512 commit ec46afc
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 12 deletions.
9 changes: 7 additions & 2 deletions examples/graphql/consumer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import * as chai from "chai";
import * as chaiAsPromised from "chai-as-promised";
import { like, term } from "../../src/dsl/matchers";
import { query } from "./consumer";
import { Pact, GraphQLInteraction } from "../../src/pact";
import { Pact, GraphQLInteraction, ApolloGraphQLInteraction } from "../../src/pact";
// import gql from "graphql-tag";

const path = require("path");
const expect = chai.expect;
Expand All @@ -26,7 +27,11 @@ describe("GraphQL example", () => {
before(() => {
const graphqlQuery = new GraphQLInteraction()
.uponReceiving("a hello request")
.withQuery(`query HelloQuery { hello }`)
.withQuery(`
query HelloQuery {
hello
}
`)
.withOperation('HelloQuery')
.withRequest({
path: "/graphql",
Expand Down
2 changes: 1 addition & 1 deletion examples/graphql/consumer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ApolloClient, HttpLink } from "apollo-boost";
import { ApolloClient } from "apollo-boost";
import { InMemoryCache } from "apollo-cache-inmemory";
import gql from "graphql-tag";
import { createHttpLink } from "apollo-link-http";
Expand Down
52 changes: 52 additions & 0 deletions src/dsl/apolloGraphql.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as chai from "chai";
import * as chaiAsPromised from "chai-as-promised";
import { ApolloGraphQLInteraction } from "./apolloGraphql";

chai.use(chaiAsPromised);
const expect = chai.expect;

describe("ApolloGraphQLInteraction", () => {
let interaction: ApolloGraphQLInteraction;

beforeEach(() => {
interaction = new ApolloGraphQLInteraction();
});

describe("#withVariables", () => {
describe("when given a set of variables", () => {
it("should add the variables to the payload", () => {
interaction.uponReceiving("a request");
interaction.withOperation("query");
interaction.withQuery("{ hello }");
interaction.withVariables({
foo: "bar"
});

const json: any = interaction.json();
expect(json.request.body.variables).to.deep.eq({ foo: "bar" });
});
});
describe("when no variables are presented", () => {
it("should add an empty variables property to the payload", () => {
interaction.uponReceiving("a request");
interaction.withOperation("query");
interaction.withQuery("{ hello }");

const json: any = interaction.json();
expect(json.request.body).to.have.property("variables");
});
});
});

describe("#withOperation", () => {
describe("when no operationNaame is presented", () => {
it("should add a null operationName property to the payload", () => {
interaction.uponReceiving("a request");
interaction.withQuery("{ hello }");

const json: any = interaction.json();
expect(json.request.body).to.have.property("operationName");
});
});
});
});
9 changes: 9 additions & 0 deletions src/dsl/apolloGraphql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { GraphQLInteraction } from './graphql'

export class ApolloGraphQLInteraction extends GraphQLInteraction {
constructor() {
super()
this.variables = this.variables || {}
this.operation = this.operation || null
}
}
14 changes: 12 additions & 2 deletions src/dsl/graphql.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import * as chai from "chai";
import * as chaiAsPromised from "chai-as-promised";
import { GraphQLInteraction } from "./graphql";
import { Interaction } from "../pact";
import { isMatcher, regex } from "./matchers";
import { isMatcher } from "./matchers";

chai.use(chaiAsPromised);
const expect = chai.expect;
Expand Down Expand Up @@ -65,6 +64,17 @@ describe("GraphQLInteraction", () => {
expect(json.request.body).to.not.have.property("variables");
});
});
describe("when an empty variables object is presented", () => {
it("should add the variables property to the payload", () => {
interaction.uponReceiving("a request");
interaction.withOperation("query");
interaction.withQuery("{ hello }");
interaction.withVariables({})

const json: any = interaction.json();
expect(json.request.body).to.have.property("variables");
});
});
});

describe("#withQuery", () => {
Expand Down
10 changes: 5 additions & 5 deletions src/dsl/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
import { Interaction, InteractionState } from "../dsl/interaction";
import { regex } from "./matchers";
import { isNil, extend, omitBy, isEmpty } from "lodash";
import { isNil, extend, omitBy, isUndefined } from "lodash";
import gql from "graphql-tag";

export interface GraphQLVariables { [name: string]: any; }
Expand All @@ -14,9 +14,9 @@ export interface GraphQLVariables { [name: string]: any; }
* GraphQL interface
*/
export class GraphQLInteraction extends Interaction {
private operation: string;
private variables: GraphQLVariables = {};
private query: string;
protected operation?: string | null = undefined;
protected variables?: GraphQLVariables = undefined;
protected query: string;

/**
* The type of GraphQL operation. Generally not required.
Expand Down Expand Up @@ -86,7 +86,7 @@ export class GraphQLInteraction extends Interaction {
operationName: this.operation || null,
query: regex({ generate: this.query, matcher: escapeGraphQlQuery(this.query) }),
variables: this.variables,
}, isEmpty),
}, isUndefined),
headers: { "content-type": "application/json" },
method: "POST",
}, this.state.request);
Expand Down
4 changes: 2 additions & 2 deletions src/dsl/matchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,14 @@ export function eachLike<T>(content: T, opts?: { min: number }) {
contents: content,
getValue: () => {
const data = [];
const min = isUndefined(opts) ? 1 : opts.min;
const min = (!opts) ? 1 : opts.min;
for (let i = 0; i < min; i++) {
data[i] = content;
}
return data;
},
json_class: "Pact::ArrayLike",
min: isUndefined(opts) ? 1 : opts.min,
min: (!opts) ? 1 : opts.min,
};
}

Expand Down
1 change: 1 addition & 0 deletions src/pact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ export * from "./dsl/verifier";
* @static
*/
export * from "./dsl/graphql";
export * from "./dsl/apolloGraphql";

/**
* Exposes {@link Matchers}
Expand Down

0 comments on commit ec46afc

Please sign in to comment.