Sebastian Suarez
04/12/2022, 3:47 PMSebastian Suarez
04/12/2022, 3:50 PM"use strict"
const { getRequest } = require("../../../helpers/sendRequest")
const identity_data = require("../../data/identity/get.identity.data")
const { PactV3, MatchersV3 } = require('@pact-foundation/pact/v3');
const { string, integer, url2, regex, datetime, fromProviderState, like } =
MatchersV3;
const { createOptsConsumer } = require("../../../helpers/createOpts")
const provider = new PactV3(createOptsConsumer(identity_data));
describe("Validate pact of identity", () => {
describe("Validate pact get identity", () => {
test("Validate successful get of an identity without QR associated", async () => {
provider
.given('A message with a 200 OK without QR associated', { id: '45' })
.uponReceiving('I want to get a new identity without QR')
.withRequest({
method: 'GET',
path: fromProviderState('/public/v2/posts/${id}/comments', '/public/v2/posts/100/comments'),
headers: {
"Content-Type": "application/json",
"authorization": `Bearer c71a5d82d1d52eb305b9302363ff68502737cca35426d880cc9a5c934f0c1730`
}
})
.willRespondWith({
status: 200,
body: [
{
"id": 107,
"post_id": 100,
"name": "Rakesh Nair",
"email": "<mailto:nair_rakesh@schoen.io|nair_rakesh@schoen.io>",
"body": "Sed vel ad. Ea similique tempora. In a iusto."
}
]
});
return provider.executeTest(async (mockserver) => {
const response = await getRequest(mockserver.url, identity_data.successfulDataWithoutQR.interaction.withRequest);
expect(response.status).toEqual(identity_data.successfulDataWithoutQR.interaction.willRespondWith.status)
});
})
test("Validate successful get of an identity with QR associated", async () => {
provider
.given('A message with a 200 OK with QR associated', { id: '50' })
.uponReceiving('I want to get a new identity with QR')
.withRequest({
method: 'GET',
path: fromProviderState('/public/v2/posts/${id}/comments', '/public/v2/posts/101/comments'),
headers: {
"Content-Type": "application/json",
"authorization": `Bearer c71a5d82d1d52eb305b9302363ff68502737cca35426d880cc9a5c934f0c1730`
}
})
.willRespondWith({
status: 200,
body: []
});
return provider.executeTest(async (mockserver) => {
const response = await getRequest(mockserver.url, identity_data.successfulDataWithQR.interaction.withRequest);
expect(response.status).toEqual(identity_data.successfulDataWithQR.interaction.willRespondWith.status)
});
})
})
})
this is the generated pact
{
"consumer": {
"name": "getidentityConsumer"
},
"interactions": [
{
"description": "I want to get a new identity with QR",
"providerState": "A message with a 200 OK with QR associated",
"request": {
"generators": null,
"headers": {
"Content-Type": "application/json",
"authorization": "Bearer c71a5d82d1d52eb305b9302363ff68502737cca35426d880cc9a5c934f0c1730"
},
"matchingRules": {
"$.path": {
"match": "type"
}
},
"method": "GET",
"path": "/public/v2/posts/101/comments"
},
"response": {
"body": [],
"headers": {
"Content-Type": "application/json"
},
"status": 200
}
},
{
"description": "I want to get a new identity without QR",
"providerState": "A message with a 200 OK without QR associated",
"request": {
"headers": {
"Content-Type": "application/json",
"authorization": "Bearer c71a5d82d1d52eb305b9302363ff68502737cca35426d880cc9a5c934f0c1730"
},
"matchingRules": {
"$.path": {
"match": "type"
}
},
"method": "GET",
"path": "/public/v2/posts/100/comments"
},
"response": {
"body": [
{
"body": "Sed vel ad. Ea similique tempora. In a iusto.",
"email": "<mailto:nair_rakesh@schoen.io|nair_rakesh@schoen.io>",
"id": 107,
"name": "Rakesh Nair",
"post_id": 100
}
],
"headers": {
"Content-Type": "application/json"
},
"status": 200
}
}
],
"metadata": {
"pact-js": {
"version": "10.0.0-beta.59"
},
"pactRust": {
"ffi": "0.2.4",
"models": "0.3.1"
},
"pactSpecification": {
"version": "1.1.0"
}
},
"provider": {
"name": "getidentityProvider"
}
}
this is my code for the provider side
"use strict"
const { VerifierV3 } = require('@pact-foundation/pact/v3');
const identity_data = require("../../data/identity/get.identity.data")
const { createOptsProvider } = require('../../../helpers/createOpts');
describe("Validate pact of identity", () => {
it("validate the pact of an identity get", () => {
let opts = {
consumerVersionTags: ['QA'],
providerVersionTags: ['QA'],
providerVersion: '1.0.0',
providerBaseUrl: '<https://gorest.co.in>',
changeOrigin: true,
logLevel: 'TRACE',
provider: 'getidentityProvider',
pactUrls: [
'C:\\pact\\transfers-be-automation-test-pact\\__tests__\\contract\\pacts\\getidentityConsumer-getidentityProvider.json'
],
stateHandlers: {
'A message with a 200 OK without QR associated': {
setup: (params) => {
console.log("Entering to the state");
console.log(params);
Promise.resolve({ id: 102 });
}
}
},
}
return new VerifierV3(opts).verifyProvider()
.then((res) => {
console.log('Pact Verification Complete!: Get identity ', res);
}).catch((res) => {
throw new Error('Pact Verification FAIL!: Get identity ', res);
});
})
})
the problem is that i want to change (in this dummy example) the url https://gorest.co.in/public/v2/posts/100/comments to https://gorest.co.in/public/v2/posts/102/comments but it doesn't work, maybe you know what i'm doing wrong? π€Sebastian Suarez
04/12/2022, 3:51 PMYousaf Nabi (pactflow.io)
Yousaf Nabi (pactflow.io)
Yousaf Nabi (pactflow.io)
Sebastian Suarez
04/12/2022, 4:32 PMYousaf Nabi (pactflow.io)
Sebastian Suarez
04/12/2022, 5:12 PMYousaf Nabi (pactflow.io)
Sebastian Suarez
04/20/2022, 5:20 PMYousaf Nabi (pactflow.io)
spec:2
as it in not generating the correct contracts, this is after removing that the provider side is amending the URL correctly.
Btw there are some other things that will cause you issue in your test setup
1. Your consumer tests pass, even if you an an expectation that fails, such as expecting the body to some something or that the expected result. You can see the pact-verifier throwing an error,.
2. Your have fixed responses on your consumer side and you are testing against a live service, both of which are less than ideal.
{
"consumer": {
"name": "getidentityConsumer"
},
"interactions": [
{
"description": "I want to get a new identity with QR",
"providerStates": [
{
"name": "A message with a 200 OK with QR associated",
"params": {
"id": "50"
}
}
],
"request": {
"generators": {
"path": {
"expression": "/public/v2/posts/${id}/comments",
"type": "ProviderState"
}
},
"headers": {
"Content-Type": "application/json",
"authorization": "Bearer c71a5d82d1d52eb305b9302363ff68502737cca35426d880cc9a5c934f0c1730"
},
"matchingRules": {
"header": {},
"path": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
}
},
"method": "GET",
"path": "/public/v2/posts/101/comments"
},
"response": {
"body": [],
"headers": {
"Content-Type": "application/json"
},
"status": 200
}
},
{
"description": "I want to get a new identity without QR",
"providerStates": [
{
"name": "A message with a 200 OK without QR associated",
"params": {
"id": "45"
}
}
],
"request": {
"generators": {
"path": {
"expression": "/public/v2/posts/${id}/comments",
"type": "ProviderState"
}
},
"headers": {
"Content-Type": "application/json",
"authorization": "Bearer c71a5d82d1d52eb305b9302363ff68502737cca35426d880cc9a5c934f0c1730"
},
"matchingRules": {
"header": {},
"path": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
}
},
"method": "GET",
"path": "/public/v2/posts/100/comments"
},
"response": {
"body": [
{
"body": "Sed vel ad. Ea similique tempora. In a iusto.",
"email": "<mailto:nair_rakesh@schoen.io|nair_rakesh@schoen.io>",
"id": 107,
"name": "Rakesh Nair",
"post_id": 100
}
],
"headers": {
"Content-Type": "application/json"
},
"status": 200
}
}
],
"metadata": {
"pact-js": {
"version": "10.0.0-beta.59"
},
"pactRust": {
"ffi": "0.2.4",
"models": "0.3.1"
},
"pactSpecification": {
"version": "3.0.0"
}
},
"provider": {
"name": "getidentityProvider"
}
}
Yousaf Nabi (pactflow.io)
spec: 2
in the provider v2 options, we get a v1.1.0
spec generated. Looking at the types, neither of those are supported (allowing options are 3 and 4).
{
"consumer": {
"name": "getidentityConsumer"
},
"interactions": [
{
"description": "I want to get a new identity with QR",
"providerState": "A message with a 200 OK with QR associated",
"request": {
"generators": null,
"headers": {
"Content-Type": "application/json",
"authorization": "Bearer c71a5d82d1d52eb305b9302363ff68502737cca35426d880cc9a5c934f0c1730"
},
"matchingRules": {
"$.path": {
"match": "type"
}
},
"method": "GET",
"path": "/public/v2/posts/101/comments"
},
"response": {
"body": [],
"headers": {
"Content-Type": "application/json"
},
"status": 200
}
},
{
"description": "I want to get a new identity without QR",
"providerState": "A message with a 200 OK without QR associated",
"request": {
"headers": {
"Content-Type": "application/json",
"authorization": "Bearer c71a5d82d1d52eb305b9302363ff68502737cca35426d880cc9a5c934f0c1730"
},
"matchingRules": {
"$.path": {
"match": "type"
}
},
"method": "GET",
"path": "/public/v2/posts/100/comments"
},
"response": {
"body": [
{
"body": "Sed vel ad. Ea similique tempora. In a iusto.",
"email": "<mailto:nair_rakesh@schoen.io|nair_rakesh@schoen.io>",
"id": 107,
"name": "Rakesh Nair",
"post_id": 100
}
],
"headers": {
"Content-Type": "application/json"
},
"status": 200
}
}
],
"metadata": {
"pact-js": {
"version": "10.0.0-beta.59"
},
"pactRust": {
"ffi": "0.2.4",
"models": "0.3.1"
},
"pactSpecification": {
"version": "1.1.0"
}
},
"provider": {
"name": "getidentityProvider"
}
}
Matt (pactflow.io / pact-js / pact-go)
Matt (pactflow.io / pact-js / pact-go)
SpecificationVersion
enum, which correctly maps to the right spec. But because JS, you can shove any number in there. Because this maps to an underlying enum, it actually maps to 1.1 (hence the problem).
It might need a guard added to the method to ensure only valid specs can be specified. Iβll have a think about a nice way of doing itYousaf Nabi (pactflow.io)
v1
spec was used but no longer supported,
β’ if someone provides a spec version, but uses matchers/generators that aren't supported, when we throw an error.
I think the 2nd point leads into the discussion around the pact specs and generators, trying to find the threadYousaf Nabi (pactflow.io)
The feature support issue is still also a big challenge. The specification only governs the contract format and matching rules, but is silent on other behaviour (see also https://github.com/pact-foundation/pact-net/pull/380).
So, to avoid incompatibility issues you have to know:
1. What version of the client library you are on (what features it supports)
2. What specification it supports (contract file compatibility)
3. What are the versions of each of the providers you have (to determine feature support)
4. What specification it supports (to determine if the contract file is compatible)
That information isnβt accessible anywhere, and, it could be argued, is a lot to expect of a user
Sebastian Suarez
04/21/2022, 2:25 PMYousaf Nabi (pactflow.io)
Yousaf Nabi (pactflow.io)
Yousaf Nabi (pactflow.io)
Sebastian Suarez
04/21/2022, 3:58 PMSebastian Suarez
04/21/2022, 4:00 PMYousaf Nabi (pactflow.io)
[2022-04-21T16:25:29Z DEBUG pact_matching::json] JSON -> JSON: Comparing '100' to '999' using Equality -> Err(Expected '100' to be equal to '999')
[2022-04-21T16:25:29Z DEBUG pact_matching::json] compare_values: Comparing 'Number(100)' to 'Number(999)' at path '$[0].post_id' -> Err(["Expected '100' to be equal to '999'"])
post ID 107 has an empty array https://gorest.co.in/public/v2/posts/100/comments
2) Verifying a pact between getidentityConsumer and getidentityProvider Given A message with a 200 OK without QR associated - I want to get a new identity without QR
2.1) has a matching body
$ -> Expected {"body":"Sed vel ad. Ea similique tempora. In a iusto.","email":"<mailto:nair_rakesh@schoen.io|nair_rakesh@schoen.io>","id":107,"name":"Rakesh Nair","post_id":100} but was missing
$ -> Expected a List with 1 elements but received 0 elements
Yousaf Nabi (pactflow.io)
Yousaf Nabi (pactflow.io)
Sebastian Suarez
04/25/2022, 2:04 PMSebastian Suarez
04/25/2022, 2:11 PMhttps://media.giphy.com/media/DGWAx8d3IkICs/giphy.gifβΎ