Victor Zviaruha
10/27/2022, 12:02 PM[09:38:07] : [Step 1/1] 2022-10-27T09:38:07.687602Z DEBUG ThreadId(01) pactffi_create_mock_server_for_pact{pact=PactHandle { pact_ref: 2 } addr_str=0x7ffceb12faf0 tls=false}: pact_mock_server::mock_server: Started mock server on 127.0.0.1:34851
[09:38:07] : [Step 1/1] 2022-10-27T09:38:07.692042Z DEBUG ThreadId(01) pact_matching::metrics: Could not get the tokio runtime, will not send metrics - there is no reactor running, must be called from the context of a Tokio 1.x runtime
[09:38:07] : [Step 1/1] 2022-10-27T09:38:07.692066Z DEBUG ThreadId(01) pact_mock_server::server_manager: Shutting down mock server with ID 669f159b-22ac-4e8d-b0c6-378f489ba070 - MockServerMetrics { requests: 0 }
[09:38:07] : [Step 1/1] 2022-10-27T09:38:07.692087Z DEBUG ThreadId(01) pact_mock_server::mock_server: Mock server 669f159b-22ac-4e8d-b0c6-378f489ba070 shutdown - MockServerMetrics { requests: 0 }
[09:38:07] : [Step 1/1] 2022-10-27T09:38:07.692105Z DEBUG tokio-runtime-worker hyper::server::shutdown: signal received, starting graceful shutdown
Attached is test code (I've removed some tests for readability as they have same logic) and build logs. Could you please help with this?Victor Zviaruha
10/27/2022, 1:54 PMYousaf Nabi (pactflow.io)
const path = require("path");
const request = require("superagent");
const { PactV3 } = require("@pact-foundation/pact");
const chai = require("chai");
const expect = chai.expect;
const { integer, timestamp, boolean, string, eachLike, like, reify } =
require("@pact-foundation/pact").MatchersV3;
const tenantId = "acme";
const projectId = "agcstest";
const authHeader = {
Authorization: "Bearer token"
};
const getBackupsListUrl = `/api/v3/databases/backups/${tenantId}/${projectId}`;
const backupsListExpectedBody = eachLike({
id: like(1),
name: like("string"),
type: like("string"),
startedAt: like("timestamp"),
completedAt: like("timestamp"),
sourceProjectId: like("string"),
sourceEnvironmentId: like("string"),
tenantId: like("string"),
projectId: like("string")
});
describe("Pact", () => {
const provider = new PactV3({
dir: path.resolve(process.cwd(), "pacts"),
consumer: "DatabaseServiceUI",
provider: "DatabaseService",
logLevel: "debug"
});
describe("GET to database backups list", () => {
it("returns list of DB backups", () => {
provider
.given(`GET to ${getBackupsListUrl}`)
.uponReceiving("request to list all DB backups")
.withRequest({
method: "GET",
path: getBackupsListUrl
})
.willRespondWith({
status: 200,
body: backupsListExpectedBody
});
return provider.executeTest((mockserver) => {
return request
.get(mockserver.url + getBackupsListUrl)
.set(authHeader)
.then((res) => {
expect(res.body).to.have.deep.members(
reify(backupsListExpectedBody)
);
});
});
});
});
});
had a quick look.
this is using mocha/chai.
1. you have matchers in your expected payload, in your expect(res.body).toMatchObject(backupsListExpectedBody); - you can use the reify method to strip the matchers off the body, otherwise you are expected your api client to return you an object with pact matchers
2. Your like matcher needs to have a valid value, string is not defined like("example string to add into the example") will match any string. so not like(string) unless you have string declared as a string value const string = "some example value"
3. You can wrap the backupsListExpectedBody object, in an eachLike matcher, which will say match me an array with at least 1 of these shape objects in.Yousaf Nabi (pactflow.io)
{
"consumer": {
"name": "DatabaseServiceUI"
},
"interactions": [
{
"description": "request to list all DB backups",
"providerStates": [
{
"name": "GET to /api/v3/databases/backups/acme/agcstest"
}
],
"request": {
"method": "GET",
"path": "/api/v3/databases/backups/acme/agcstest"
},
"response": {
"body": [
{
"completedAt": "timestamp",
"id": 1,
"name": "string",
"projectId": "string",
"sourceEnvironmentId": "string",
"sourceProjectId": "string",
"startedAt": "timestamp",
"tenantId": "string",
"type": "string"
}
],
"headers": {
"Content-Type": "application/json"
},
"matchingRules": {
"body": {
"$": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$[*].completedAt": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$[*].id": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$[*].name": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$[*].projectId": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$[*].sourceEnvironmentId": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$[*].sourceProjectId": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$[*].startedAt": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$[*].tenantId": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$[*].type": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
}
}
},
"status": 200
}
}
],
"metadata": {
"pact-js": {
"version": "10.1.4"
},
"pactRust": {
"ffi": "0.3.12",
"models": "0.4.5"
},
"pactSpecification": {
"version": "3.0.0"
}
},
"provider": {
"name": "DatabaseService"
}
}Yousaf Nabi (pactflow.io)
Victor Zviaruha
10/27/2022, 2:08 PMYousaf Nabi (pactflow.io)
Victor Zviaruha
10/27/2022, 2:11 PM