added pact-node-provider example
This commit is contained in:
@@ -1,21 +1,36 @@
|
||||
var createError = require('http-errors');
|
||||
var express = require('express');
|
||||
var path = require('path');
|
||||
var logger = require('morgan');
|
||||
|
||||
var heroesRouter = require('./routes/heroes');
|
||||
|
||||
var app = express();
|
||||
const createError = require('http-errors');
|
||||
const express = require('express');
|
||||
const path = require('path');
|
||||
const logger = require('morgan');
|
||||
const heroesRouter = require('./routes/heroes');
|
||||
const providerStateRouter = require('./routes/provider_state');
|
||||
const app = express();
|
||||
|
||||
app.use(logger('dev'));
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: false }));
|
||||
app.use(express.urlencoded({extended: false}));
|
||||
|
||||
app.use('/heroes', heroesRouter);
|
||||
|
||||
registerPactEndpoint();
|
||||
|
||||
// catch 404 and forward to error handler
|
||||
app.use(function(req, res, next) {
|
||||
next(createError(404));
|
||||
app.use(function (req, res, next) {
|
||||
next(createError(404));
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
|
||||
/**
|
||||
* Registers a special endpoint for pact provider tests that allows to
|
||||
* set the server into a certain "provider state".
|
||||
*
|
||||
* This endpoint is only registered if the environment variable "PACT_MODE"
|
||||
* is set to "true".
|
||||
*/
|
||||
function registerPactEndpoint() {
|
||||
const pactMode = (process.env.PACT_MODE === 'true');
|
||||
if (pactMode) {
|
||||
app.use('/provider-state', providerStateRouter);
|
||||
}
|
||||
}
|
||||
|
||||
2350
pact/pact-node-provider/package-lock.json
generated
2350
pact/pact-node-provider/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,9 @@
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node ./bin/www.js"
|
||||
"start": "node ./bin/www.js",
|
||||
"pact:providerTests": "node ./pact/provider_tests.js",
|
||||
"test:pact": "start-server-and-test start http://localhost:3000/heroes/42 pact:providerTests"
|
||||
},
|
||||
"dependencies": {
|
||||
"cookie-parser": "~1.4.3",
|
||||
@@ -12,5 +14,9 @@
|
||||
"http-errors": "~1.6.2",
|
||||
"jade": "~1.11.0",
|
||||
"morgan": "~1.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@pact-foundation/pact": "7.0.1",
|
||||
"start-server-and-test": "^1.7.5"
|
||||
}
|
||||
}
|
||||
|
||||
17
pact/pact-node-provider/pact/provider_tests.js
Normal file
17
pact/pact-node-provider/pact/provider_tests.js
Normal file
@@ -0,0 +1,17 @@
|
||||
const { Verifier } = require('@pact-foundation/pact');
|
||||
const packageJson = require('../package.json');
|
||||
|
||||
let opts = {
|
||||
providerBaseUrl: 'http://localhost:3000',
|
||||
provider: 'hero-provider',
|
||||
pactBrokerUrl: 'https://adesso.pact.dius.com.au',
|
||||
pactBrokerUsername: process.env.PACT_USERNAME,
|
||||
pactBrokerPassword: process.env.PACT_PASSWORD,
|
||||
publishVerificationResult: true,
|
||||
providerVersion: packageJson.version,
|
||||
providerStatesSetupUrl: 'http://localhost:3000/provider-state'
|
||||
};
|
||||
|
||||
new Verifier().verifyProvider(opts).then(function () {
|
||||
console.log("Pacts successfully verified!");
|
||||
});
|
||||
@@ -1,27 +1,27 @@
|
||||
var express = require('express');
|
||||
var router = express.Router();
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
router.route('/:hero_id')
|
||||
.get(function (req, res) {
|
||||
var heroId = parseInt(req.params['hero_id']);
|
||||
const heroId = parseInt(req.params['hero_id']);
|
||||
res.status(200);
|
||||
res.json({
|
||||
id: heroId,
|
||||
superpower: 'flying',
|
||||
name: 'Superman',
|
||||
universe: 'DC'
|
||||
});
|
||||
res.status(200);
|
||||
});
|
||||
|
||||
router.route('/')
|
||||
.post(function (req, res) {
|
||||
res.status(201);
|
||||
res.json({
|
||||
id: 42,
|
||||
superpower: 'flying',
|
||||
name: 'Superman',
|
||||
universe: 'DC'
|
||||
});
|
||||
res.status(201);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
13
pact/pact-node-provider/routes/provider_state.js
Normal file
13
pact/pact-node-provider/routes/provider_state.js
Normal file
@@ -0,0 +1,13 @@
|
||||
var express = require('express');
|
||||
var router = express.Router();
|
||||
|
||||
router.route('/')
|
||||
.post(function (req, res) {
|
||||
const consumer = req.query['consumer'];
|
||||
const providerState = req.query['state'];
|
||||
// imagine we're setting the server into a certain state
|
||||
res.send(`changed to provider state "${providerState}" for consumer "${consumer}"`);
|
||||
res.status(200);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -10,7 +10,7 @@ global.provider = new Pact({
|
||||
dir: path.resolve(process.cwd(), 'pacts'),
|
||||
spec: 2,
|
||||
pactfileWriteMode: 'update',
|
||||
consumer: 'react-consumer',
|
||||
provider: 'node-provider',
|
||||
consumer: 'hero-consumer',
|
||||
provider: 'hero-provider',
|
||||
host: '127.0.0.1'
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
import Hero from "./hero";
|
||||
|
||||
const axios = require('axios');
|
||||
import adapter from 'axios/lib/adapters/http';
|
||||
|
||||
class HeroService {
|
||||
|
||||
@@ -18,9 +19,9 @@ class HeroService {
|
||||
url: `/heroes/${heroId}`,
|
||||
baseURL: `${this.baseUrl}:${this.port}`,
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
'Accept': 'application/json; charset=utf-8'
|
||||
}
|
||||
}).then((response) => {
|
||||
}, adapter).then((response) => {
|
||||
const hero = response.data;
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
@@ -40,11 +41,11 @@ class HeroService {
|
||||
url: `/heroes`,
|
||||
baseURL: `${this.baseUrl}:${this.port}`,
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
'Accept': 'application/json; charset=utf-8',
|
||||
'Content-Type': 'application/json; charset=utf-8'
|
||||
},
|
||||
data: hero
|
||||
}).then((response) => {
|
||||
}, adapter).then((response) => {
|
||||
const hero = response.data;
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
|
||||
@@ -6,6 +6,13 @@ describe('HeroService API', () => {
|
||||
|
||||
const heroService = new HeroService('http://localhost', global.port);
|
||||
|
||||
// a matcher for the content type "application/json" in UTF8 charset
|
||||
// that ignores the spaces between the ";2 and "charset"
|
||||
const contentTypeJsonMatcher = Pact.Matchers.term({
|
||||
matcher: "application\\/json; *charset=utf-8",
|
||||
generate: "application/json; charset=utf-8"
|
||||
});
|
||||
|
||||
describe('getHero()', () => {
|
||||
|
||||
beforeEach((done) => {
|
||||
@@ -16,13 +23,13 @@ describe('HeroService API', () => {
|
||||
method: 'GET',
|
||||
path: '/heroes/42',
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
'Accept': contentTypeJsonMatcher
|
||||
}
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
'Content-Type': contentTypeJsonMatcher
|
||||
},
|
||||
body: Pact.Matchers.somethingLike(new Hero('Superman', 'flying', 'DC', 42))
|
||||
}
|
||||
@@ -54,15 +61,18 @@ describe('HeroService API', () => {
|
||||
method: 'POST',
|
||||
path: '/heroes',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
'Accept': contentTypeJsonMatcher,
|
||||
'Content-Type': contentTypeJsonMatcher
|
||||
},
|
||||
body: new Hero('Superman', 'flying', 'DC')
|
||||
},
|
||||
willRespondWith: {
|
||||
status: 201,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
'Content-Type': Pact.Matchers.term({
|
||||
matcher: "application\\/json; *charset=utf-8",
|
||||
generate: "application/json; charset=utf-8"
|
||||
})
|
||||
},
|
||||
body: Pact.Matchers.somethingLike(
|
||||
new Hero('Superman', 'flying', 'DC', 42))
|
||||
|
||||
Reference in New Issue
Block a user