Hey folks I tried to generate pact with header - `...
# pact-js
a
Hey folks I tried to generate pact with header -
Content-Type": "application/x-protobuf-json-format
but generates some weird represation of expected response string(not a map as
application/json
) like `"{"requestId":{"pactmatchertype":"type","value":"2b0124bf-4b7a-4ac7-938c-6021be9cb661"}}"`and fail the provider's verification, is it because of pact-js doesn't support this type of type(
application/x-protobuf-json-format
) of content well right now?
m
mind sharing a bit more about your setup - e.g. consumer test, logs etc.?
a
sure, I had setup consumer test with
Content-Type": "application/x-protobuf-json-format
(I haven't tried this type of content before), define a response like this
Copy code
const responsePostOffers = {
    requestId: string(UUID)
}
and pact generate the expected response in a string like this:
Copy code
"body": "{\"requestId\":{\"pact:matcher:type\":\"type\",\"value\":\"2b0124bf-4b7a-4ac7-938c-6021be9cb661\"}\"}"
when I tried to verify it in the provider side, it fails, because the request id only contain a single UUID instead of the matcher that pact generated : (
I can show you the pact I generated, like this
Copy code
{
  "consumer": {
    "name": "test1"
  },
  "interactions": [
    {
      "description": "Get test as an offer from TopK",
      "providerStates": [
        {
          "name": "the service is operating normally"
        }
      ],
      "request": {
        "body": "{\"productsPerVertical\":{\"INSURANCE\":1}}",
        "headers": {
          "Content-Type": "application/x-protobuf-json-format"
        },
        "method": "POST",
        "path": "/v3/cross-sell/products"
      },
      "response": {
        "body": "{\"requestId\":{\"pact:matcher:type\":\"type\",\"value\":\"2b0124bf-4b7a-4ac7-938c-6021be9cb661\"}}",
        "headers": {
          "Content-Type": "application/x-protobuf-json-format"
        },
        "status": 200
      }
    }
  ],
  "metadata": {
    "pact-js": {
      "version": "10.4.1"
    },
    "pactRust": {
      "ffi": "0.4.0",
      "models": "1.0.4"
    },
    "pactSpecification": {
      "version": "3.0.0"
    }
  },
  "provider": {
    "name": "test2"
  }
}
m
I want to see how you write the test. The generated pact looks incorrect
a
yeah, I think so, here is the consumer test I have
Copy code
/* eslint-disable @typescript-eslint/no-explicit-any */
import {MatchersV3} from '@pact-foundation/pact';
import {OffersClient} from '../offersClient';
import path from 'path';
import {PactV3} from '@pact-foundation/pact';
import {CONSUMER, PROVIDER_TOPK} from '../constants';
import {AxiosResponse} from '@sample/topk-api-client';
import {TopKResponse} from '../../../src/server/services/top-k/types';

const {string, integer, decimal} = MatchersV3;
const UUID = '2b0124bf-4b7a-4ac7-938c-6021be9cb661'; //This ID is static to avoid updates to the published contracts every time the CI job runs.

describe('The Offers API', () => {
  const pactPath = `${process.env.CI_BUILDS_DIR || process.cwd()}/pacts`;
  const mockProvider = new PactV3({
    port: 8081,
    dir: path.resolve(pactPath), // folder with created contracts
    consumer: CONSUMER,
    provider: PROVIDER_TOPK,
    logLevel: 'debug',
  });
  const requestHeaders = {'Content-Type': 'application/x-protobuf-json-format'};
  const responseHeaders = {'Content-Type': 'application/x-protobuf-json-format'};

  const requestPostOffers = {
    productsPerVertical: {
      INSURANCE: 1,
    },
  };

  const responsePostOffers = {
    requestId: string(UUID),
  };

  it('returns 200 when test addons are posted', () => {
    // Arrange: Setup our expected interactions
    mockProvider
      .given('the service is operating normally')
      .uponReceiving('Get test as an offer from test')
      .withRequest({
        method: 'POST',
        path: '/v3/test/products',
        headers: requestHeaders,
        body: requestPostOffers,
      })
      .willRespondWith({
        status: 200,
        headers: responseHeaders,
        body: responsePostOffers,
      });
    // Act: make request to Pact mock server
    return mockProvider.executeTest(async () => {
      const offersClient = new OffersClient();
      const offersResponse = (await offersClient.products(
        requestPostOffers as any
      )) as AxiosResponse<TopKResponse>;
      // assert that we got the expected response
      expect(offersResponse.status).toEqual(200);
      return;
    });
  });
});
I think the key point may be related to
{'Content-Type': 'application/x-protobuf-json-format'}
if I change it to
application/json
,everything looks fine(I can generate right matcher rules and request&response as a map)