@pact-foundation/pact 16.3.1 → 16.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/CONTRIBUTING.md +2 -2
- package/package.json +16 -24
- package/src/common/graphQL/configurationError.js +2 -22
- package/src/common/graphQL/configurationError.js.map +1 -1
- package/src/common/graphQL/graphQL.d.ts +2 -2
- package/src/common/graphQL/graphQL.js +11 -14
- package/src/common/graphQL/graphQL.js.map +1 -1
- package/src/common/graphQL/graphQLQueryError.js +2 -22
- package/src/common/graphQL/graphQLQueryError.js.map +1 -1
- package/src/common/logger.js +9 -9
- package/src/common/logger.js.map +1 -1
- package/src/common/matchingRules.d.ts +1 -1
- package/src/common/matchingRules.js +21 -21
- package/src/common/matchingRules.js.map +1 -1
- package/src/common/net.js +36 -42
- package/src/common/net.js.map +1 -1
- package/src/common/net.spec.js +41 -53
- package/src/common/net.spec.js.map +1 -1
- package/src/common/request.js +33 -82
- package/src/common/request.js.map +1 -1
- package/src/common/request.spec.js +26 -26
- package/src/common/request.spec.js.map +1 -1
- package/src/common/spec.js +3 -4
- package/src/common/spec.js.map +1 -1
- package/src/dsl/apolloGraphql.js +7 -25
- package/src/dsl/apolloGraphql.js.map +1 -1
- package/src/dsl/apolloGraphql.spec.js +21 -18
- package/src/dsl/apolloGraphql.spec.js.map +1 -1
- package/src/dsl/graphql.d.ts +2 -2
- package/src/dsl/graphql.js +29 -48
- package/src/dsl/graphql.js.map +1 -1
- package/src/dsl/graphql.spec.js +81 -66
- package/src/dsl/graphql.spec.js.map +1 -1
- package/src/dsl/interaction.d.ts +2 -2
- package/src/dsl/interaction.js +41 -48
- package/src/dsl/interaction.js.map +1 -1
- package/src/dsl/interaction.spec.js +77 -70
- package/src/dsl/interaction.spec.js.map +1 -1
- package/src/dsl/matchers.d.ts +1 -1
- package/src/dsl/matchers.js +19 -31
- package/src/dsl/matchers.js.map +1 -1
- package/src/dsl/matchers.spec.js +199 -208
- package/src/dsl/matchers.spec.js.map +1 -1
- package/src/dsl/message.d.ts +3 -3
- package/src/dsl/options.d.ts +3 -3
- package/src/dsl/verifier/proxy/hooks.d.ts +2 -2
- package/src/dsl/verifier/proxy/hooks.js +42 -112
- package/src/dsl/verifier/proxy/hooks.js.map +1 -1
- package/src/dsl/verifier/proxy/hooks.spec.js +84 -199
- package/src/dsl/verifier/proxy/hooks.spec.js.map +1 -1
- package/src/dsl/verifier/proxy/messages.d.ts +2 -2
- package/src/dsl/verifier/proxy/messages.js +88 -106
- package/src/dsl/verifier/proxy/messages.js.map +1 -1
- package/src/dsl/verifier/proxy/parseBody.d.ts +1 -1
- package/src/dsl/verifier/proxy/parseBody.js +2 -2
- package/src/dsl/verifier/proxy/parseBody.js.map +1 -1
- package/src/dsl/verifier/proxy/parseBody.spec.js +31 -76
- package/src/dsl/verifier/proxy/parseBody.spec.js.map +1 -1
- package/src/dsl/verifier/proxy/proxy.d.ts +2 -2
- package/src/dsl/verifier/proxy/proxy.js +22 -26
- package/src/dsl/verifier/proxy/proxy.js.map +1 -1
- package/src/dsl/verifier/proxy/proxy.spec.js +14 -14
- package/src/dsl/verifier/proxy/proxy.spec.js.map +1 -1
- package/src/dsl/verifier/proxy/proxyRequest.d.ts +3 -3
- package/src/dsl/verifier/proxy/proxyRequest.js +7 -7
- package/src/dsl/verifier/proxy/proxyRequest.js.map +1 -1
- package/src/dsl/verifier/proxy/proxyRequest.spec.js +49 -64
- package/src/dsl/verifier/proxy/proxyRequest.spec.js.map +1 -1
- package/src/dsl/verifier/proxy/stateHandler/setupStates.d.ts +3 -3
- package/src/dsl/verifier/proxy/stateHandler/setupStates.js +14 -18
- package/src/dsl/verifier/proxy/stateHandler/setupStates.js.map +1 -1
- package/src/dsl/verifier/proxy/stateHandler/setupStates.spec.js +76 -159
- package/src/dsl/verifier/proxy/stateHandler/setupStates.spec.js.map +1 -1
- package/src/dsl/verifier/proxy/stateHandler/stateHandler.d.ts +2 -2
- package/src/dsl/verifier/proxy/stateHandler/stateHandler.js +23 -72
- package/src/dsl/verifier/proxy/stateHandler/stateHandler.js.map +1 -1
- package/src/dsl/verifier/proxy/stateHandler/stateHandler.spec.js +37 -85
- package/src/dsl/verifier/proxy/stateHandler/stateHandler.spec.js.map +1 -1
- package/src/dsl/verifier/proxy/tracer.d.ts +1 -1
- package/src/dsl/verifier/proxy/tracer.js +42 -35
- package/src/dsl/verifier/proxy/tracer.js.map +1 -1
- package/src/dsl/verifier/proxy/types.d.ts +5 -5
- package/src/dsl/verifier/types.d.ts +3 -3
- package/src/dsl/verifier/verifier.d.ts +1 -1
- package/src/dsl/verifier/verifier.js +49 -56
- package/src/dsl/verifier/verifier.js.map +1 -1
- package/src/dsl/verifier/verifier.spec.js +76 -93
- package/src/dsl/verifier/verifier.spec.js.map +1 -1
- package/src/errors/configurationError.js +2 -22
- package/src/errors/configurationError.js.map +1 -1
- package/src/errors/graphQLQueryError.js +2 -22
- package/src/errors/graphQLQueryError.js.map +1 -1
- package/src/errors/matcherError.js +2 -22
- package/src/errors/matcherError.js.map +1 -1
- package/src/errors/verificationError.js +2 -22
- package/src/errors/verificationError.js.map +1 -1
- package/src/httpPact/ffi.d.ts +2 -2
- package/src/httpPact/ffi.js +28 -29
- package/src/httpPact/ffi.js.map +1 -1
- package/src/httpPact/ffi.spec.js +30 -31
- package/src/httpPact/ffi.spec.js.map +1 -1
- package/src/httpPact/index.d.ts +3 -3
- package/src/httpPact/index.js +92 -149
- package/src/httpPact/index.js.map +1 -1
- package/src/httpPact/index.spec.js +75 -125
- package/src/httpPact/index.spec.js.map +1 -1
- package/src/httpPact/tracing.js +20 -28
- package/src/httpPact/tracing.js.map +1 -1
- package/src/index.js +1 -1
- package/src/index.js.map +1 -1
- package/src/messageConsumerPact.d.ts +3 -3
- package/src/messageConsumerPact.js +50 -51
- package/src/messageConsumerPact.js.map +1 -1
- package/src/messageConsumerPact.spec.js +50 -49
- package/src/messageConsumerPact.spec.js.map +1 -1
- package/src/messageProviderPact.d.ts +3 -3
- package/src/messageProviderPact.js +68 -85
- package/src/messageProviderPact.js.map +1 -1
- package/src/messageProviderPact.spec.js +75 -66
- package/src/messageProviderPact.spec.js.map +1 -1
- package/src/pact.integration.spec.js +243 -313
- package/src/pact.integration.spec.js.map +1 -1
- package/src/v3/display.d.ts +1 -1
- package/src/v3/display.js +44 -58
- package/src/v3/display.js.map +1 -1
- package/src/v3/ffi.js +15 -15
- package/src/v3/ffi.js.map +1 -1
- package/src/v3/ffi.spec.js +8 -8
- package/src/v3/ffi.spec.js.map +1 -1
- package/src/v3/graphql/graphQL.d.ts +4 -4
- package/src/v3/graphql/graphQL.js +50 -75
- package/src/v3/graphql/graphQL.js.map +1 -1
- package/src/v3/matchers.d.ts +2 -2
- package/src/v3/matchers.js +112 -147
- package/src/v3/matchers.js.map +1 -1
- package/src/v3/matchers.spec.js +168 -187
- package/src/v3/matchers.spec.js.map +1 -1
- package/src/v3/pact.d.ts +2 -2
- package/src/v3/pact.js +103 -151
- package/src/v3/pact.js.map +1 -1
- package/src/v3/types.d.ts +1 -1
- package/src/v3/xml/xmlBuilder.d.ts +1 -3
- package/src/v3/xml/xmlBuilder.js +7 -9
- package/src/v3/xml/xmlBuilder.js.map +1 -1
- package/src/v3/xml/xmlElement.d.ts +2 -2
- package/src/v3/xml/xmlElement.js +24 -41
- package/src/v3/xml/xmlElement.js.map +1 -1
- package/src/v3/xml/xmlElement.spec.js +23 -25
- package/src/v3/xml/xmlElement.spec.js.map +1 -1
- package/src/v3/xml/xmlNode.js +2 -5
- package/src/v3/xml/xmlNode.js.map +1 -1
- package/src/v3/xml/xmlText.d.ts +1 -1
- package/src/v3/xml/xmlText.js +9 -25
- package/src/v3/xml/xmlText.js.map +1 -1
- package/src/v4/graphql/graphQLInteractionWithRequest.d.ts +4 -4
- package/src/v4/graphql/graphQLInteractionWithRequest.js +21 -17
- package/src/v4/graphql/graphQLInteractionWithRequest.js.map +1 -1
- package/src/v4/graphql/graphQLRequestBuilder.d.ts +3 -3
- package/src/v4/graphql/graphQLRequestBuilder.js +18 -20
- package/src/v4/graphql/graphQLRequestBuilder.js.map +1 -1
- package/src/v4/graphql/index.d.ts +6 -6
- package/src/v4/graphql/index.js +21 -17
- package/src/v4/graphql/index.js.map +1 -1
- package/src/v4/graphql/types.d.ts +5 -5
- package/src/v4/http/index.d.ts +2 -2
- package/src/v4/http/index.js +48 -93
- package/src/v4/http/index.js.map +1 -1
- package/src/v4/http/interactionWithCompleteRequest.d.ts +4 -7
- package/src/v4/http/interactionWithCompleteRequest.js +6 -10
- package/src/v4/http/interactionWithCompleteRequest.js.map +1 -1
- package/src/v4/http/interactionWithPlugin.d.ts +3 -3
- package/src/v4/http/interactionWithPlugin.js +14 -11
- package/src/v4/http/interactionWithPlugin.js.map +1 -1
- package/src/v4/http/interactionWithPluginRequest.d.ts +2 -2
- package/src/v4/http/interactionWithPluginRequest.js +11 -8
- package/src/v4/http/interactionWithPluginRequest.js.map +1 -1
- package/src/v4/http/interactionWithPluginResponse.d.ts +2 -2
- package/src/v4/http/interactionWithPluginResponse.js +10 -48
- package/src/v4/http/interactionWithPluginResponse.js.map +1 -1
- package/src/v4/http/interactionWithRequest.d.ts +2 -2
- package/src/v4/http/interactionWithRequest.js +11 -8
- package/src/v4/http/interactionWithRequest.js.map +1 -1
- package/src/v4/http/interactionWithResponse.d.ts +2 -2
- package/src/v4/http/interactionWithResponse.js +10 -48
- package/src/v4/http/interactionWithResponse.js.map +1 -1
- package/src/v4/http/requestBuilder.d.ts +3 -3
- package/src/v4/http/requestBuilder.js +32 -34
- package/src/v4/http/requestBuilder.js.map +1 -1
- package/src/v4/http/requestWithPluginBuilder.d.ts +2 -2
- package/src/v4/http/requestWithPluginBuilder.js +26 -46
- package/src/v4/http/requestWithPluginBuilder.js.map +1 -1
- package/src/v4/http/responseBuilder.d.ts +3 -3
- package/src/v4/http/responseBuilder.js +24 -25
- package/src/v4/http/responseBuilder.js.map +1 -1
- package/src/v4/http/responseWithPluginBuilder.d.ts +1 -1
- package/src/v4/http/responseWithPluginBuilder.js +5 -25
- package/src/v4/http/responseWithPluginBuilder.js.map +1 -1
- package/src/v4/http/types.d.ts +3 -2
- package/src/v4/http/unconfiguredInteraction.d.ts +6 -5
- package/src/v4/http/unconfiguredInteraction.js +31 -26
- package/src/v4/http/unconfiguredInteraction.js.map +1 -1
- package/src/v4/index.d.ts +4 -4
- package/src/v4/index.js +31 -35
- package/src/v4/index.js.map +1 -1
- package/src/v4/message/asynchronousMessage.d.ts +7 -6
- package/src/v4/message/asynchronousMessage.js +157 -190
- package/src/v4/message/asynchronousMessage.js.map +1 -1
- package/src/v4/message/index.d.ts +7 -6
- package/src/v4/message/index.js +188 -217
- package/src/v4/message/index.js.map +1 -1
- package/src/v4/message/types.d.ts +5 -3
- package/src/v4/types.d.ts +3 -3
|
@@ -32,90 +32,92 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
45
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
46
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
47
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
48
|
-
function step(op) {
|
|
49
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
50
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
51
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
52
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
53
|
-
switch (op[0]) {
|
|
54
|
-
case 0: case 1: t = op; break;
|
|
55
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
56
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
57
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
58
|
-
default:
|
|
59
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
60
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
61
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
62
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
63
|
-
if (t[2]) _.ops.pop();
|
|
64
|
-
_.trys.pop(); continue;
|
|
65
|
-
}
|
|
66
|
-
op = body.call(thisArg, _);
|
|
67
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
68
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
72
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
73
37
|
};
|
|
74
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
var v3_1 = require("./v3");
|
|
86
|
-
var expect = chai.expect;
|
|
39
|
+
const chai = __importStar(require("chai"));
|
|
40
|
+
const chai_as_promised_1 = __importDefault(require("chai-as-promised"));
|
|
41
|
+
const sinon_chai_1 = __importDefault(require("sinon-chai"));
|
|
42
|
+
const axios_1 = __importDefault(require("axios"));
|
|
43
|
+
const fs = require("node:fs");
|
|
44
|
+
const net = require("node:net");
|
|
45
|
+
const path = require("node:path");
|
|
46
|
+
const v4_1 = require("./v4");
|
|
47
|
+
const v3_1 = require("./v3");
|
|
48
|
+
const { expect } = chai;
|
|
87
49
|
chai.use(sinon_chai_1.default);
|
|
88
50
|
chai.use(chai_as_promised_1.default);
|
|
89
|
-
describe('V4 Pact',
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
expect(matches,
|
|
96
|
-
|
|
51
|
+
describe('V4 Pact', () => {
|
|
52
|
+
let pact;
|
|
53
|
+
const pactFilePath = path.resolve(process.cwd(), 'pacts', 'v4consumer-v4provider.json');
|
|
54
|
+
const interactionByDescription = (description) => {
|
|
55
|
+
const pactJson = JSON.parse(fs.readFileSync(pactFilePath, 'utf8'));
|
|
56
|
+
const matches = pactJson.interactions.filter((item) => item.description === description);
|
|
57
|
+
expect(matches, `expected exactly one interaction for "${description}"`).to.have.lengthOf(1);
|
|
58
|
+
const [interaction] = matches;
|
|
97
59
|
return interaction;
|
|
98
60
|
};
|
|
99
|
-
|
|
100
|
-
|
|
61
|
+
const expectCommentsToContain = (interaction, reason, textComment, testName) => {
|
|
62
|
+
const comments = interaction.comments;
|
|
101
63
|
expect(comments.reason).to.equal(reason);
|
|
102
64
|
expect(comments.text).to.include(textComment);
|
|
103
65
|
expect(comments.testname).to.equal(testName);
|
|
104
66
|
};
|
|
105
|
-
|
|
67
|
+
const expectReferenceToEqual = (interaction, group, name, value) => {
|
|
68
|
+
const comments = interaction.comments;
|
|
69
|
+
const references = comments.references;
|
|
70
|
+
expect(references[group][name]).to.equal(value);
|
|
71
|
+
};
|
|
72
|
+
beforeEach(() => {
|
|
106
73
|
pact = new v4_1.PactV4({
|
|
107
74
|
consumer: 'v4consumer',
|
|
108
75
|
provider: 'v4provider',
|
|
109
76
|
});
|
|
110
77
|
});
|
|
111
|
-
describe('HTTP req/res contract',
|
|
112
|
-
it('generates a pact',
|
|
113
|
-
|
|
78
|
+
describe('HTTP req/res contract', () => {
|
|
79
|
+
it('generates a pact', () => pact
|
|
80
|
+
.addInteraction()
|
|
81
|
+
.given('some state')
|
|
82
|
+
.given('a second state')
|
|
83
|
+
.uponReceiving('a standard HTTP req/res')
|
|
84
|
+
.withRequest('POST', '/', (builder) => {
|
|
85
|
+
builder
|
|
86
|
+
.jsonBody({
|
|
87
|
+
foo: 'bar',
|
|
88
|
+
})
|
|
89
|
+
.headers({
|
|
90
|
+
'x-foo': 'x-bar',
|
|
91
|
+
});
|
|
92
|
+
})
|
|
93
|
+
.willRespondWith(200, (builder) => {
|
|
94
|
+
builder
|
|
95
|
+
.jsonBody({
|
|
96
|
+
foo: 'bar',
|
|
97
|
+
})
|
|
98
|
+
.headers({
|
|
99
|
+
'x-foo': 'x-bar',
|
|
100
|
+
});
|
|
101
|
+
})
|
|
102
|
+
.executeTest(async (server) => axios_1.default.post(server.url, {
|
|
103
|
+
foo: 'bar',
|
|
104
|
+
}, {
|
|
105
|
+
headers: {
|
|
106
|
+
'x-foo': 'x-bar',
|
|
107
|
+
},
|
|
108
|
+
})));
|
|
109
|
+
it('generates a pact with interaction metadata', async () => {
|
|
110
|
+
const description = 'v4 metadata http req/res interaction';
|
|
111
|
+
await pact
|
|
114
112
|
.addInteraction()
|
|
115
113
|
.given('some state')
|
|
116
114
|
.given('a second state')
|
|
117
|
-
.uponReceiving(
|
|
118
|
-
.
|
|
115
|
+
.uponReceiving(description)
|
|
116
|
+
.pending()
|
|
117
|
+
.comment({ key: 'reason', value: 'covered by HTTP metadata test' })
|
|
118
|
+
.comment('second note from HTTP metadata test')
|
|
119
|
+
.testName('http metadata test name')
|
|
120
|
+
.withRequest('POST', '/', (builder) => {
|
|
119
121
|
builder
|
|
120
122
|
.jsonBody({
|
|
121
123
|
foo: 'bar',
|
|
@@ -124,7 +126,7 @@ describe('V4 Pact', function () {
|
|
|
124
126
|
'x-foo': 'x-bar',
|
|
125
127
|
});
|
|
126
128
|
})
|
|
127
|
-
.willRespondWith(200,
|
|
129
|
+
.willRespondWith(200, (builder) => {
|
|
128
130
|
builder
|
|
129
131
|
.jsonBody({
|
|
130
132
|
foo: 'bar',
|
|
@@ -133,264 +135,200 @@ describe('V4 Pact', function () {
|
|
|
133
135
|
'x-foo': 'x-bar',
|
|
134
136
|
});
|
|
135
137
|
})
|
|
136
|
-
.executeTest(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}); });
|
|
138
|
+
.executeTest(async (server) => axios_1.default.post(server.url, {
|
|
139
|
+
foo: 'bar',
|
|
140
|
+
}, {
|
|
141
|
+
headers: {
|
|
142
|
+
'x-foo': 'x-bar',
|
|
143
|
+
},
|
|
144
|
+
}));
|
|
145
|
+
const interaction = interactionByDescription(description);
|
|
146
|
+
expect(interaction.pending).to.equal(true);
|
|
147
|
+
expectCommentsToContain(interaction, 'covered by HTTP metadata test', 'second note from HTTP metadata test', 'http metadata test name');
|
|
147
148
|
});
|
|
148
|
-
it('
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
switch (_a.label) {
|
|
152
|
-
case 0:
|
|
153
|
-
description = 'v4 metadata http req/res interaction';
|
|
154
|
-
return [4 /*yield*/, pact
|
|
155
|
-
.addInteraction()
|
|
156
|
-
.given('some state')
|
|
157
|
-
.given('a second state')
|
|
158
|
-
.uponReceiving(description)
|
|
159
|
-
.pending()
|
|
160
|
-
.comment({ key: 'reason', value: 'covered by HTTP metadata test' })
|
|
161
|
-
.comment('second note from HTTP metadata test')
|
|
162
|
-
.testName('http metadata test name')
|
|
163
|
-
.withRequest('POST', '/', function (builder) {
|
|
164
|
-
builder
|
|
165
|
-
.jsonBody({
|
|
166
|
-
foo: 'bar',
|
|
167
|
-
})
|
|
168
|
-
.headers({
|
|
169
|
-
'x-foo': 'x-bar',
|
|
170
|
-
});
|
|
171
|
-
})
|
|
172
|
-
.willRespondWith(200, function (builder) {
|
|
173
|
-
builder
|
|
174
|
-
.jsonBody({
|
|
175
|
-
foo: 'bar',
|
|
176
|
-
})
|
|
177
|
-
.headers({
|
|
178
|
-
'x-foo': 'x-bar',
|
|
179
|
-
});
|
|
180
|
-
})
|
|
181
|
-
.executeTest(function (server) { return __awaiter(void 0, void 0, void 0, function () {
|
|
182
|
-
return __generator(this, function (_a) {
|
|
183
|
-
return [2 /*return*/, axios_1.default.post(server.url, {
|
|
184
|
-
foo: 'bar',
|
|
185
|
-
}, {
|
|
186
|
-
headers: {
|
|
187
|
-
'x-foo': 'x-bar',
|
|
188
|
-
},
|
|
189
|
-
})];
|
|
190
|
-
});
|
|
191
|
-
}); })];
|
|
192
|
-
case 1:
|
|
193
|
-
_a.sent();
|
|
194
|
-
interaction = interactionByDescription(description);
|
|
195
|
-
expect(interaction.pending).to.equal(true);
|
|
196
|
-
expectCommentsToContain(interaction, 'covered by HTTP metadata test', 'second note from HTTP metadata test', 'http metadata test name');
|
|
197
|
-
return [2 /*return*/];
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
}); });
|
|
201
|
-
it('supports regex matcher for response content-type with optional charset', function () {
|
|
202
|
-
return pact
|
|
149
|
+
it('records interaction references in the pact file', async () => {
|
|
150
|
+
const description = 'v4 http interaction with references';
|
|
151
|
+
await pact
|
|
203
152
|
.addInteraction()
|
|
204
|
-
.uponReceiving(
|
|
153
|
+
.uponReceiving(description)
|
|
154
|
+
.reference('Jira', 'TICKET-123', 'https://jira.example.com/TICKET-123')
|
|
205
155
|
.withRequest('GET', '/')
|
|
206
|
-
.willRespondWith(200
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
156
|
+
.willRespondWith(200)
|
|
157
|
+
.executeTest(async (server) => axios_1.default.get(server.url));
|
|
158
|
+
const interaction = interactionByDescription(description);
|
|
159
|
+
expectReferenceToEqual(interaction, 'Jira', 'TICKET-123', 'https://jira.example.com/TICKET-123');
|
|
160
|
+
});
|
|
161
|
+
it('supports regex matcher for response content-type with optional charset', () => pact
|
|
162
|
+
.addInteraction()
|
|
163
|
+
.uponReceiving('a response with regex content-type header matcher')
|
|
164
|
+
.withRequest('GET', '/')
|
|
165
|
+
.willRespondWith(200, (builder) => {
|
|
166
|
+
builder
|
|
167
|
+
.headers({
|
|
168
|
+
'Content-Type': v3_1.MatchersV3.regex(/^application\/json(;\s?charset=[\w-]+)?$/i, 'application/json'),
|
|
214
169
|
})
|
|
215
|
-
.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
170
|
+
.jsonBody({
|
|
171
|
+
foo: 'bar',
|
|
172
|
+
});
|
|
173
|
+
})
|
|
174
|
+
.executeTest(async (server) => {
|
|
175
|
+
const response = await axios_1.default.get(server.url);
|
|
176
|
+
expect(response.data).to.deep.equal({ foo: 'bar' });
|
|
177
|
+
}));
|
|
178
|
+
it('supports regex matcher for request content-type with optional charset', () => pact
|
|
179
|
+
.addInteraction()
|
|
180
|
+
.uponReceiving('a request with regex content-type header matcher')
|
|
181
|
+
.withRequest('POST', '/', (builder) => {
|
|
182
|
+
builder
|
|
183
|
+
.headers({
|
|
184
|
+
'Content-Type': v3_1.MatchersV3.regex(/^application\/json(;\s?charset=[\w-]+)?$/i, 'application/json'),
|
|
185
|
+
})
|
|
186
|
+
.jsonBody({
|
|
187
|
+
foo: 'bar',
|
|
188
|
+
});
|
|
189
|
+
})
|
|
190
|
+
.willRespondWith(200, (builder) => {
|
|
191
|
+
builder.jsonBody({
|
|
192
|
+
ok: true,
|
|
193
|
+
});
|
|
194
|
+
})
|
|
195
|
+
.executeTest((server) => axios_1.default.post(server.url, {
|
|
196
|
+
foo: 'bar',
|
|
197
|
+
})));
|
|
198
|
+
});
|
|
199
|
+
describe('Asynchronous message contract', () => {
|
|
200
|
+
it('generates a pact with interaction metadata', async () => {
|
|
201
|
+
const description = 'v4 metadata async interaction message';
|
|
202
|
+
await pact
|
|
203
|
+
.addAsynchronousInteraction()
|
|
204
|
+
.given('an async message state')
|
|
205
|
+
.pending()
|
|
206
|
+
.comment({ key: 'reason', value: 'covered by async metadata test' })
|
|
207
|
+
.comment('second note from async metadata test')
|
|
208
|
+
.testName('async metadata test name')
|
|
209
|
+
.expectsToReceive(description, (builder) => {
|
|
210
|
+
builder.withJSONContent({
|
|
211
|
+
event: 'user.created',
|
|
225
212
|
});
|
|
226
|
-
})
|
|
213
|
+
})
|
|
214
|
+
.executeTest(async () => Promise.resolve());
|
|
215
|
+
const interaction = interactionByDescription(description);
|
|
216
|
+
expect(interaction.pending).to.equal(true);
|
|
217
|
+
expectCommentsToContain(interaction, 'covered by async metadata test', 'second note from async metadata test', 'async metadata test name');
|
|
227
218
|
});
|
|
228
|
-
it('
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
.
|
|
232
|
-
.
|
|
233
|
-
builder
|
|
234
|
-
|
|
235
|
-
'Content-Type': v3_1.MatchersV3.regex(/^application\/json(;\s?charset=[\w-]+)?$/i, 'application/json'),
|
|
236
|
-
})
|
|
237
|
-
.jsonBody({
|
|
238
|
-
foo: 'bar',
|
|
239
|
-
});
|
|
219
|
+
it('records interaction references in the pact file', async () => {
|
|
220
|
+
const description = 'v4 async interaction with references';
|
|
221
|
+
await pact
|
|
222
|
+
.addAsynchronousInteraction()
|
|
223
|
+
.reference('GitHub', 'PR-456', 'https://github.com/example/repo/pull/456')
|
|
224
|
+
.expectsToReceive(description, (builder) => {
|
|
225
|
+
builder.withJSONContent({ event: 'user.created' });
|
|
240
226
|
})
|
|
241
|
-
.
|
|
242
|
-
|
|
243
|
-
|
|
227
|
+
.executeTest(async () => Promise.resolve());
|
|
228
|
+
const interaction = interactionByDescription(description);
|
|
229
|
+
expectReferenceToEqual(interaction, 'GitHub', 'PR-456', 'https://github.com/example/repo/pull/456');
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
describe('Synchronous message contract', () => {
|
|
233
|
+
it('generates a pact with interaction metadata', async () => {
|
|
234
|
+
const description = 'v4 metadata sync interaction message';
|
|
235
|
+
await pact
|
|
236
|
+
.addSynchronousInteraction(description)
|
|
237
|
+
.given('a synchronous message state')
|
|
238
|
+
.pending()
|
|
239
|
+
.comment({ key: 'reason', value: 'covered by sync metadata test' })
|
|
240
|
+
.comment('second note from sync metadata test')
|
|
241
|
+
.testName('sync metadata test name')
|
|
242
|
+
.withRequest((builder) => {
|
|
243
|
+
builder.withJSONContent({
|
|
244
|
+
request: 'ping',
|
|
244
245
|
});
|
|
245
246
|
})
|
|
246
|
-
.
|
|
247
|
-
|
|
248
|
-
|
|
247
|
+
.withResponse((builder) => {
|
|
248
|
+
builder.withJSONContent({
|
|
249
|
+
response: 'pong',
|
|
249
250
|
});
|
|
250
|
-
})
|
|
251
|
+
})
|
|
252
|
+
.executeTest(async () => Promise.resolve());
|
|
253
|
+
const interaction = interactionByDescription(description);
|
|
254
|
+
expect(interaction.pending).to.equal(true);
|
|
255
|
+
expectCommentsToContain(interaction, 'covered by sync metadata test', 'second note from sync metadata test', 'sync metadata test name');
|
|
256
|
+
});
|
|
257
|
+
it('records interaction references in the pact file', async () => {
|
|
258
|
+
const description = 'v4 sync interaction with references';
|
|
259
|
+
await pact
|
|
260
|
+
.addSynchronousInteraction(description)
|
|
261
|
+
.reference('Jira', 'TICKET-789', 'https://jira.example.com/TICKET-789')
|
|
262
|
+
.withRequest((builder) => {
|
|
263
|
+
builder.withJSONContent({ request: 'ping' });
|
|
264
|
+
})
|
|
265
|
+
.withResponse((builder) => {
|
|
266
|
+
builder.withJSONContent({ response: 'pong' });
|
|
267
|
+
})
|
|
268
|
+
.executeTest(async () => Promise.resolve());
|
|
269
|
+
const interaction = interactionByDescription(description);
|
|
270
|
+
expectReferenceToEqual(interaction, 'Jira', 'TICKET-789', 'https://jira.example.com/TICKET-789');
|
|
251
271
|
});
|
|
252
272
|
});
|
|
253
|
-
describe('
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
case 0:
|
|
291
|
-
description = 'v4 metadata sync interaction message';
|
|
292
|
-
return [4 /*yield*/, pact
|
|
293
|
-
.addSynchronousInteraction(description)
|
|
294
|
-
.given('a synchronous message state')
|
|
295
|
-
.pending()
|
|
296
|
-
.comment({ key: 'reason', value: 'covered by sync metadata test' })
|
|
297
|
-
.comment('second note from sync metadata test')
|
|
298
|
-
.testName('sync metadata test name')
|
|
299
|
-
.withRequest(function (builder) {
|
|
300
|
-
builder.withJSONContent({
|
|
301
|
-
request: 'ping',
|
|
302
|
-
});
|
|
303
|
-
})
|
|
304
|
-
.withResponse(function (builder) {
|
|
305
|
-
builder.withJSONContent({
|
|
306
|
-
response: 'pong',
|
|
307
|
-
});
|
|
308
|
-
})
|
|
309
|
-
.executeTest(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
310
|
-
return [2 /*return*/, Promise.resolve()];
|
|
311
|
-
}); }); })];
|
|
312
|
-
case 1:
|
|
313
|
-
_a.sent();
|
|
314
|
-
interaction = interactionByDescription(description);
|
|
315
|
-
expect(interaction.pending).to.equal(true);
|
|
316
|
-
expectCommentsToContain(interaction, 'covered by sync metadata test', 'second note from sync metadata test', 'sync metadata test name');
|
|
317
|
-
return [2 /*return*/];
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
}); });
|
|
321
|
-
});
|
|
322
|
-
describe('Plugin test', function () {
|
|
323
|
-
describe('Using the MATT plugin', function () {
|
|
324
|
-
var parseMattMessage = function (raw) {
|
|
325
|
-
return raw.replace(/(MATT)+/g, '').trim();
|
|
326
|
-
};
|
|
327
|
-
var generateMattMessage = function (raw) { return "MATT".concat(raw, "MATT"); };
|
|
328
|
-
describe('HTTP interface', function () {
|
|
329
|
-
it('generates a pact', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
330
|
-
var mattRequest, mattResponse;
|
|
331
|
-
return __generator(this, function (_a) {
|
|
332
|
-
switch (_a.label) {
|
|
333
|
-
case 0:
|
|
334
|
-
mattRequest = "{\"request\": {\"body\": \"hello\"}}";
|
|
335
|
-
mattResponse = "{\"response\":{\"body\":\"world\"}}";
|
|
336
|
-
return [4 /*yield*/, pact
|
|
337
|
-
.addInteraction()
|
|
338
|
-
.given('the Matt protocol exists')
|
|
339
|
-
.uponReceiving('an HTTP request to /matt')
|
|
340
|
-
.usingPlugin({
|
|
341
|
-
plugin: 'matt',
|
|
342
|
-
version: '0.1.1',
|
|
343
|
-
})
|
|
344
|
-
.withRequest('POST', '/matt', function (builder) {
|
|
345
|
-
builder.pluginContents('application/matt', mattRequest);
|
|
346
|
-
})
|
|
347
|
-
.willRespondWith(200, function (builder) {
|
|
348
|
-
builder.pluginContents('application/matt', mattResponse);
|
|
349
|
-
})
|
|
350
|
-
.executeTest(function (mockserver) {
|
|
351
|
-
return axios_1.default
|
|
352
|
-
.request({
|
|
353
|
-
baseURL: mockserver.url,
|
|
354
|
-
headers: {
|
|
355
|
-
'content-type': 'application/matt',
|
|
356
|
-
Accept: 'application/matt',
|
|
357
|
-
},
|
|
358
|
-
data: generateMattMessage('hello'),
|
|
359
|
-
method: 'POST',
|
|
360
|
-
url: '/matt',
|
|
361
|
-
})
|
|
362
|
-
.then(function (res) {
|
|
363
|
-
expect(parseMattMessage(res.data)).to.eq('world');
|
|
364
|
-
});
|
|
365
|
-
})];
|
|
366
|
-
case 1:
|
|
367
|
-
_a.sent();
|
|
368
|
-
return [2 /*return*/];
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
}); });
|
|
273
|
+
describe('Plugin test', () => {
|
|
274
|
+
describe('Using the MATT plugin', () => {
|
|
275
|
+
const parseMattMessage = (raw) => raw.replace(/(MATT)+/g, '').trim();
|
|
276
|
+
const generateMattMessage = (raw) => `MATT${raw}MATT`;
|
|
277
|
+
describe('HTTP interface', () => {
|
|
278
|
+
it('generates a pact', async () => {
|
|
279
|
+
const mattRequest = `{"request": {"body": "hello"}}`;
|
|
280
|
+
const mattResponse = `{"response":{"body":"world"}}`;
|
|
281
|
+
await pact
|
|
282
|
+
.addInteraction()
|
|
283
|
+
.given('the Matt protocol exists')
|
|
284
|
+
.uponReceiving('an HTTP request to /matt')
|
|
285
|
+
.usingPlugin({
|
|
286
|
+
plugin: 'matt',
|
|
287
|
+
version: '0.1.1',
|
|
288
|
+
})
|
|
289
|
+
.withRequest('POST', '/matt', (builder) => {
|
|
290
|
+
builder.pluginContents('application/matt', mattRequest);
|
|
291
|
+
})
|
|
292
|
+
.willRespondWith(200, (builder) => {
|
|
293
|
+
builder.pluginContents('application/matt', mattResponse);
|
|
294
|
+
})
|
|
295
|
+
.executeTest((mockserver) => axios_1.default
|
|
296
|
+
.request({
|
|
297
|
+
baseURL: mockserver.url,
|
|
298
|
+
headers: {
|
|
299
|
+
'content-type': 'application/matt',
|
|
300
|
+
Accept: 'application/matt',
|
|
301
|
+
},
|
|
302
|
+
data: generateMattMessage('hello'),
|
|
303
|
+
method: 'POST',
|
|
304
|
+
url: '/matt',
|
|
305
|
+
})
|
|
306
|
+
.then((res) => {
|
|
307
|
+
expect(parseMattMessage(res.data)).to.eq('world');
|
|
308
|
+
}));
|
|
309
|
+
});
|
|
372
310
|
});
|
|
373
|
-
describe('Synchronous Message (TCP) ',
|
|
374
|
-
describe('with MATT protocol',
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
port
|
|
379
|
-
host
|
|
311
|
+
describe('Synchronous Message (TCP) ', () => {
|
|
312
|
+
describe('with MATT protocol', () => {
|
|
313
|
+
const HOST = '127.0.0.1';
|
|
314
|
+
const sendMattMessageTCP = (message, host, port) => {
|
|
315
|
+
const socket = net.connect({
|
|
316
|
+
port,
|
|
317
|
+
host,
|
|
380
318
|
});
|
|
381
|
-
|
|
319
|
+
const res = socket.write(`${generateMattMessage(message)}\n`);
|
|
382
320
|
if (!res) {
|
|
383
321
|
throw Error('unable to connect to host');
|
|
384
322
|
}
|
|
385
|
-
return new Promise(
|
|
386
|
-
socket.on('data',
|
|
323
|
+
return new Promise((resolve) => {
|
|
324
|
+
socket.on('data', (data) => {
|
|
387
325
|
resolve(parseMattMessage(data.toString()));
|
|
388
326
|
socket.destroy();
|
|
389
327
|
});
|
|
390
328
|
});
|
|
391
329
|
};
|
|
392
|
-
it('generates a pact',
|
|
393
|
-
|
|
330
|
+
it('generates a pact', () => {
|
|
331
|
+
const mattMessage = `{"request": {"body": "hellotcp"}, "response":{"body":"tcpworld"}}`;
|
|
394
332
|
return pact
|
|
395
333
|
.addSynchronousInteraction('a MATT message')
|
|
396
334
|
.usingPlugin({
|
|
@@ -399,18 +337,10 @@ describe('V4 Pact', function () {
|
|
|
399
337
|
})
|
|
400
338
|
.withPluginContents(mattMessage, 'application/matt')
|
|
401
339
|
.startTransport('matt', HOST)
|
|
402
|
-
.executeTest(
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
case 0: return [4 /*yield*/, sendMattMessageTCP('hellotcp', HOST, tc.port)];
|
|
407
|
-
case 1:
|
|
408
|
-
message = _a.sent();
|
|
409
|
-
expect(message).to.eq('tcpworld');
|
|
410
|
-
return [2 /*return*/];
|
|
411
|
-
}
|
|
412
|
-
});
|
|
413
|
-
}); });
|
|
340
|
+
.executeTest(async (tc) => {
|
|
341
|
+
const message = await sendMattMessageTCP('hellotcp', HOST, tc.port);
|
|
342
|
+
expect(message).to.eq('tcpworld');
|
|
343
|
+
});
|
|
414
344
|
});
|
|
415
345
|
});
|
|
416
346
|
});
|