diff --git a/pact/pact-node-provider/app.js b/pact/pact-node-provider/app.js index a9e8b94..9f601a1 100644 --- a/pact/pact-node-provider/app.js +++ b/pact/pact-node-provider/app.js @@ -6,6 +6,7 @@ const logger = require('morgan'); const indexRouter = require('./routes/index'); const usersRouter = require('./routes/users'); const heroesRouter = require('./routes/heroes'); +const graphqlRouter = require('./routes/graphql'); const providerStateRouter = require ('./routes/provider_state'); const app = express(); @@ -19,6 +20,7 @@ app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); app.use('/users', usersRouter); app.use('/heroes', heroesRouter); +app.use('/graphql', graphqlRouter); if (process.env.PACT_MODE === 'true') { app.use('/provider-state', providerStateRouter); diff --git a/pact/pact-node-provider/package-lock.json b/pact/pact-node-provider/package-lock.json index c53b195..c869908 100644 --- a/pact/pact-node-provider/package-lock.json +++ b/pact/pact-node-provider/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@pact-foundation/pact": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@pact-foundation/pact/-/pact-7.0.1.tgz", - "integrity": "sha512-kIJ5iRqajmJ88Zt1+BWkuVh31ei1yc3XgjT2cGTejna26J9U1GeE7SMLfi2aB+CbLmNClNwih+rD+degXMAlGw==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@pact-foundation/pact/-/pact-7.0.3.tgz", + "integrity": "sha512-i2btZMCv77g71+oPZ7vHe+g+50zeUau2jp4sJ26cJ5wq6c38cccwCxi8SoiB7eDavI1BZYAmPhCF4sCaY7DgXA==", "dev": true, "requires": { "@pact-foundation/pact-node": "6.20.0", @@ -64,7 +64,7 @@ "dev": true, "requires": { "@types/connect": "3.4.32", - "@types/node": "10.12.0" + "@types/node": "10.12.3" } }, "@types/bunyan": { @@ -73,7 +73,7 @@ "integrity": "sha512-baISkYt/F2U7vQAhojiVz/EZGdws2OQyOH5EPbr41gcvfTLjYDsLR8mEcX2Ufq3vwgJ3ViLGXhy7mMXWg076zw==", "dev": true, "requires": { - "@types/node": "10.12.0" + "@types/node": "10.12.3" } }, "@types/connect": { @@ -82,7 +82,7 @@ "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", "dev": true, "requires": { - "@types/node": "10.12.0" + "@types/node": "10.12.3" } }, "@types/events": { @@ -109,7 +109,7 @@ "dev": true, "requires": { "@types/events": "1.2.0", - "@types/node": "10.12.0", + "@types/node": "10.12.3", "@types/range-parser": "1.2.2" } }, @@ -121,7 +121,7 @@ "requires": { "@types/events": "1.2.0", "@types/minimatch": "3.0.3", - "@types/node": "10.12.0" + "@types/node": "10.12.3" } }, "@types/mime": { @@ -142,13 +142,13 @@ "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", "dev": true, "requires": { - "@types/node": "10.12.0" + "@types/node": "10.12.3" } }, "@types/node": { - "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.0.tgz", - "integrity": "sha512-3TUHC3jsBAB7qVRGxT6lWyYo2v96BMmD2PTcl47H25Lu7UXtFH/2qqmKiVrnel6Ne//0TFYf6uvNX+HW2FRkLQ==", + "version": "10.12.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.3.tgz", + "integrity": "sha512-sfGmOtSMSbQ/AKG8V9xD1gmjquC9awIIZ/Kj309pHb2n3bcRAcGMQv5nJ6gCXZVsneGE4+ve8DXKRCsrg3TFzg==", "dev": true }, "@types/q": { @@ -170,7 +170,7 @@ "dev": true, "requires": { "@types/glob": "7.1.1", - "@types/node": "10.12.0" + "@types/node": "10.12.3" } }, "@types/serve-static": { @@ -212,7 +212,7 @@ }, "ansi-escapes": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", "dev": true }, @@ -690,7 +690,7 @@ }, "d": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { @@ -724,7 +724,7 @@ "decompress-tarbz2": "4.1.1", "decompress-targz": "4.1.1", "decompress-unzip": "4.0.1", - "graceful-fs": "4.1.11", + "graceful-fs": "4.1.15", "make-dir": "1.3.0", "pify": "2.3.0", "strip-dirs": "2.1.0" @@ -1027,6 +1027,36 @@ "vary": "1.1.2" } }, + "express-graphql": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/express-graphql/-/express-graphql-0.7.1.tgz", + "integrity": "sha512-YpheAqTbSKpb5h57rV2yu2dPNUBi4FvZDspZ5iEV3ov34PBRgnM4lEBkv60+vZRJ6SweYL14N8AGYdov7g6ooQ==", + "requires": { + "accepts": "1.3.5", + "content-type": "1.0.4", + "http-errors": "1.7.1", + "raw-body": "2.3.3" + }, + "dependencies": { + "http-errors": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.1.tgz", + "integrity": "sha512-jWEUgtZWGSMba9I1N3gc1HmvpBUaNC9vDdA46yScAdp+C5rdEuKWUBLWTQpW9FwSWSbYYs++b6SDCxf9UEJzfw==", + "requires": { + "depd": "1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": "1.5.0", + "toidentifier": "1.0.0" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + } + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -1220,9 +1250,9 @@ } }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, "graceful-readlink": { @@ -1816,7 +1846,7 @@ }, "next-tick": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, @@ -1909,7 +1939,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, @@ -1926,7 +1956,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -2454,7 +2484,7 @@ }, "tar": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.0.tgz", + "resolved": "http://registry.npmjs.org/tar/-/tar-4.4.0.tgz", "integrity": "sha512-gJlTiiErwo96K904FnoYWl+5+FBgS+FimU6GMh66XLdLa55al8+d4jeDfPoGwSNHdtWI5FJP6xurmVqhBuGJpQ==", "dev": true, "requires": { @@ -2512,6 +2542,11 @@ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", "dev": true }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, "topo": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.0.tgz", diff --git a/pact/pact-node-provider/package.json b/pact/pact-node-provider/package.json index 9540cf7..e178d99 100644 --- a/pact/pact-node-provider/package.json +++ b/pact/pact-node-provider/package.json @@ -5,16 +5,19 @@ "scripts": { "start": "node ./bin/www", "pact:providerTests": "node ./pact/provider_tests.js", - "test:pact": "start-server-and-test start http://localhost:3000 pact:providerTests" + "pact:providerTests:graphql": "node ./pact/provider_tests_graphql.js", + "test:pact": "start-server-and-test start http://localhost:3000 pact:providerTests", + "test:pact:graphql": "start-server-and-test start http://localhost:3000 pact:providerTests:graphql" }, "dependencies": { "cookie-parser": "~1.4.3", "debug": "~2.6.9", "express": "~4.16.0", + "express-graphql": "^0.7.1", "morgan": "~1.9.0" }, "devDependencies": { - "@pact-foundation/pact": "7.0.1", + "@pact-foundation/pact": "7.0.3", "start-server-and-test": "^1.7.5" } } diff --git a/pact/pact-node-provider/pact/provider_tests_graphql.js b/pact/pact-node-provider/pact/provider_tests_graphql.js new file mode 100644 index 0000000..27fd754 --- /dev/null +++ b/pact/pact-node-provider/pact/provider_tests_graphql.js @@ -0,0 +1,16 @@ +const { Verifier } = require('@pact-foundation/pact'); +const packageJson = require('../package.json'); + +let opts = { + providerBaseUrl: 'http://localhost:3000', + provider: 'graphql-hero-provider', + pactBrokerUrl: 'https://adesso.pact.dius.com.au', + pactBrokerUsername: process.env.PACT_USERNAME, + pactBrokerPassword: process.env.PACT_PASSWORD, + publishVerificationResult: true, + providerVersion: packageJson.version, +}; + +new Verifier().verifyProvider(opts).then(function () { + console.log("Pacts successfully verified!"); +}); \ No newline at end of file diff --git a/pact/pact-node-provider/routes/graphql.js b/pact/pact-node-provider/routes/graphql.js new file mode 100644 index 0000000..42ef682 --- /dev/null +++ b/pact/pact-node-provider/routes/graphql.js @@ -0,0 +1,36 @@ +const graphqlHTTP = require('express-graphql'); +const {buildSchema} = require("graphql"); + +const heroesSchema = buildSchema(` + type Query { + hero(id: Int!): Hero + } + + type Hero { + id: Int! + name: String! + superpower: String! + universe: String! + } +`); + +const getHero = function () { + return { + id: 42, + name: "Superman", + superpower: "Flying", + universe: "DC" + } +}; + +const root = { + hero: getHero +}; + +const router = graphqlHTTP({ + schema: heroesSchema, + graphiql: true, + rootValue: root +}); + +module.exports = router; diff --git a/pact/pact-react-consumer/src/graphql/hero.service.graphql.js b/pact/pact-react-consumer/src/graphql/hero.service.graphql.js index 95eb451..72f5225 100644 --- a/pact/pact-react-consumer/src/graphql/hero.service.graphql.js +++ b/pact/pact-react-consumer/src/graphql/hero.service.graphql.js @@ -23,7 +23,7 @@ class GraphQLHeroService { } return this.client.query({ query: gql` - query GetHero($heroId: Int) { + query GetHero($heroId: Int!) { hero(id: $heroId) { name superpower diff --git a/pact/pact-react-consumer/src/graphql/hero.service.test.graphql.pact.js b/pact/pact-react-consumer/src/graphql/hero.service.test.graphql.pact.js index 24f6659..c1ab412 100644 --- a/pact/pact-react-consumer/src/graphql/hero.service.test.graphql.pact.js +++ b/pact/pact-react-consumer/src/graphql/hero.service.test.graphql.pact.js @@ -24,7 +24,7 @@ describe('HeroService GraphQL API', () => { }) .withOperation("GetHero") .withQuery(` - query GetHero($heroId: Int) { + query GetHero($heroId: Int!) { hero(id: $heroId) { name superpower