pactum icon indicating copy to clipboard operation
pactum copied to clipboard

Pactum Mock Server is format sensitive to Graphql Requests

Open nate1228 opened this issue 2 years ago • 3 comments

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:

  1. Start Mock Server
  2. Define a GQL request interaction with a defined body
  3. Make GQL request with body defined from step 2 (returns expected mocked response)
  4. Slightly alter the formatting of the gql request
  5. 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 image image image

Software (please complete the following information):

  • OS: ubuntu 20.04
  • NodeJS Version 18.1

nate1228 avatar May 17 '22 20:05 nate1228

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
  }
})

ASaiAnudeep avatar May 18 '22 09:05 ASaiAnudeep

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!

nate1228 avatar May 18 '22 18:05 nate1228

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
  }
})

ASaiAnudeep avatar May 20 '22 15:05 ASaiAnudeep