pactum
pactum copied to clipboard
Pactum Mock Server is format sensitive to Graphql Requests
Describe the bug When making a graphql request to the mock server, a request made with a slightly different formatted gql body will cause the mock to believe it is a different defined interaction and return "Interaction Not Found"
To Reproduce Steps to reproduce the behavior:
- Start Mock Server
- Define a GQL request interaction with a defined body
- Make GQL request with body defined from step 2 (returns expected mocked response)
- Slightly alter the formatting of the gql request
- Response is an "Interaction Not Found"
Expected behavior The formatting of the request should not change the body of a gql request, and should return a mocked response if the request exists as a defined interaction
Screenshots
Software (please complete the following information):
- OS: ubuntu 20.04
- NodeJS Version 18.1
Hello @nate1228, thanks for reporting the issue. To further investigate, can you give us a sample data in json format to replicate the issue.
As a work around, disable the strict request matching and don't include request body in the mock interaction.
mock.addInteraction({
strict: false,
request: {
method: 'POST',
path: '/vessel/data'
},
response: {
status: 200
}
})
I believe any gql request that is in a different format can be used to replicate the issue
{ positions { getLatestPositionsPerVessel( request: { timestampRange: { minValueInclusive: "2022-05-10T00:00:00Z" maxValueInclusive: "2022-05-18T00:00:00Z" } positionsSnapshot: "" yearBuiltRange: { minValueInclusive: 2000, maxValueInclusive: 2020 } deadweightRange: { minValueInclusive: 170000, maxValueInclusive: 200000 } moveStatuses: { values: ["At anchor", "Under way using engine", "Moored"] } headingRanges: { ranges: [ { start: 23, end: 67 } { start: 68, end: 112 } { start: 113, end: 157 } { start: 338, end: 360 } { start: 0, end: 22 } ] } mustMatchAllGeoFilters: false count: 5 } ) { isPreview latestVesselPositions { vesselPositions { name draught maxDraught moveStatus imo destination destinationTidied coordinates { lat lon } beam length mmsi timestamp heading dwt eta speed yob } } } } }
{positions { getLatestPositionsPerVessel( request: {timestampRange: {minValueInclusive: "2022-05-10T00:00:00Z", maxValueInclusive: "2022-05-18T00:00:00Z"}, positionsSnapshot: "", yearBuiltRange: {minValueInclusive: 2000, maxValueInclusive: 2020}, deadweightRange: {minValueInclusive: 170000, maxValueInclusive: 200000}, moveStatuses: {values: ["At anchor", "Under way using engine", "Moored"]}, headingRanges: {ranges: [{start: 23, end: 67}, {start: 68, end: 112}, {start: 113, end: 157}, {start: 338, end: 360}, {start: 0, end: 22}]}, mustMatchAllGeoFilters: false, count: 5} ) { isPreview latestVesselPositions { vesselPositions { name draught maxDraught moveStatus imo destination destinationTidied coordinates { lat lon } beam length mmsi timestamp heading dwt eta speed yob } } } } }
Part of the issue is that the mock server "reads" the gql body as a large string and not a gql object
The work around would not necessarily solve the issue because I need a 2nd gql mock with the same base url :/ Let me know if that works!
I'm not able to replicate the issue with different formats of GQL query at mock server and postman payload. I might be missing something.
mock.addInteraction({
request: {
method: 'POST',
path: '/vessel/data',
graphQL: {
query: `
{ positions { getLatestPositionsPerVessel( request: { timestampRange: { minValueInclusive: "2022-05-10T00:00:00Z" maxValueInclusive: "2022-05-18T00:00:00Z" } positionsSnapshot: "" yearBuiltRange: { minValueInclusive: 2000, maxValueInclusive: 2020 } deadweightRange: { minValueInclusive: 170000, maxValueInclusive: 200000 } moveStatuses: { values: ["At anchor", "Under way using engine", "Moored"] } headingRanges: { ranges: [ { start: 23, end: 67 } { start: 68, end: 112 } { start: 113, end: 157 } { start: 338, end: 360 } { start: 0, end: 22 } ] } mustMatchAllGeoFilters: false count: 5 } ) { isPreview latestVesselPositions { vesselPositions { name draught maxDraught moveStatus imo destination destinationTidied coordinates { lat lon } beam length mmsi timestamp heading dwt eta speed yob } } } } }
{positions { getLatestPositionsPerVessel( request: {timestampRange: {minValueInclusive: "2022-05-10T00:00:00Z", maxValueInclusive: "2022-05-18T00:00:00Z"}, positionsSnapshot: "", yearBuiltRange: {minValueInclusive: 2000, maxValueInclusive: 2020}, deadweightRange: {minValueInclusive: 170000, maxValueInclusive: 200000}, moveStatuses: {values: ["At anchor", "Under way using engine", "Moored"]}, headingRanges: {ranges: [{start: 23, end: 67}, {start: 68, end: 112}, {start: 113, end: 157}, {start: 338, end: 360}, {start: 0, end: 22}]}, mustMatchAllGeoFilters: false, count: 5} ) { isPreview latestVesselPositions { vesselPositions { name draught maxDraught moveStatus imo destination destinationTidied coordinates { lat lon } beam length mmsi timestamp heading dwt eta speed yob } } } } }
`
}
},
response: {
status: 200
}
})
mock.addInteraction({
request: {
method: 'POST',
path: '/vessel/data',
graphQL: {
query: `
{
positions {
getLatestPositionsPerVessel(
request: {
timestampRange: {
minValueInclusive: "2022-05-10T00:00:00Z"
maxValueInclusive: "2022-05-18T00:00:00Z"
}
positionsSnapshot: ""
yearBuiltRange: { minValueInclusive: 2000, maxValueInclusive: 2020 }
deadweightRange: {
minValueInclusive: 170000
maxValueInclusive: 200000
}
moveStatuses: {
values: ["At anchor", "Under way using engine", "Moored"]
}
headingRanges: {
ranges: [
{ start: 23, end: 67 }
{ start: 68, end: 112 }
{ start: 113, end: 157 }
{ start: 338, end: 360 }
{ start: 0, end: 22 }
]
}
mustMatchAllGeoFilters: false
count: 5
}
) {
isPreview
latestVesselPositions {
vesselPositions {
name
draught
maxDraught
moveStatus
imo
destination
destinationTidied
coordinates {
lat
lon
}
beam
length
mmsi
timestamp
heading
dwt
eta
speed
yob
}
}
}
}
}
{
positions {
getLatestPositionsPerVessel(
request: {
timestampRange: {
minValueInclusive: "2022-05-10T00:00:00Z"
maxValueInclusive: "2022-05-18T00:00:00Z"
}
positionsSnapshot: ""
yearBuiltRange: { minValueInclusive: 2000, maxValueInclusive: 2020 }
deadweightRange: {
minValueInclusive: 170000
maxValueInclusive: 200000
}
moveStatuses: {
values: ["At anchor", "Under way using engine", "Moored"]
}
headingRanges: {
ranges: [
{ start: 23, end: 67 }
{ start: 68, end: 112 }
{ start: 113, end: 157 }
{ start: 338, end: 360 }
{ start: 0, end: 22 }
]
}
mustMatchAllGeoFilters: false
count: 5
}
) {
isPreview
latestVesselPositions {
vesselPositions {
name
draught
maxDraught
moveStatus
imo
destination
destinationTidied
coordinates {
lat
lon
}
beam
length
mmsi
timestamp
heading
dwt
eta
speed
yob
}
}
}
}
}
`
}
},
response: {
status: 200
}
})