<#1071 headers with matchers are not working the s...
# pact-js-development
g
#1071 headers with matchers are not working the same way as in v9 Issue created by jhayes-dev Software versions • OS: macOS 12.4 • Consumer Pact library: v11.0.0 • Node Version: v16.19.1 Issue Checklist Please confirm the following: ☑︎ I have upgraded to the latest ☑︎ I have the read the FAQs in the Readme ☑︎ I have triple checked, that there are no unhandled promises in my code and have read the section on intermittent test failures ☑︎ I have set my log level to debug and attached a log file showing the complete request/response cycle ☐ For bonus points and virtual high fives, I have created a reproduceable git repository (see below) to illustrate the problem Expected behaviour I'm upgrading to pact@11 form pact@9. When defining the consumer tests the mock server return the correct body.
Copy code
{
  expected_response: {
    data: 'some string',
    event_id: '37227fda-94d3-4422-908d-fe2303914e98',
    posted_date: '2021-03-17T07:52:34.666Z'
  },
}
Actual behaviour But it is returning the 'raw' willRespondWith.body value
Copy code
{
  data: {
    data: { value: 'some string', 'pact:matcher:type': 'type' },
    event_id: {
      value: '37227fda-94d3-4422-908d-fe2303914e98',
      'pact:matcher:type': 'type'
    },
    posted_date: {
      value: '2021-03-17T07:52:34.666Z',
      regex: '^\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+([+-][0-2]\\d(:?[0-5]\\d)?|Z)$',
      'pact:matcher:type': 'regex'
    }
  }
}
Steps to reproduce Here is a script to reproduce the problem. See the comments in withRequest.headers and willRespondWith.headers for more details. test-pact.ts:
Copy code
import path from 'node:path';
import { Pact, Matchers } from '@pact-foundation/pact';
import axios, { AxiosResponse } from 'axios';

interface RequestPayload {
    data: string;
}

interface ResponsePayload extends RequestPayload {
    event_id: string;
    posted_date: string;
}

function toTemplate<T extends object>(obj: T): { [K in keyof T]: T[K] } {
    return obj;
}

async function main() {

    const provider: Pact = new Pact({
        consumer: 'consumer',
        provider: 'provider',
        dir: path.resolve('pacts'),
        spec: 2,
        logLevel: 'debug'
    });

    await provider.setup();

    const request: RequestPayload = {
        data: 'some string'
    };

    const expected_response: ResponsePayload = {
        ...request,
        event_id: '37227fda-94d3-4422-908d-fe2303914e98',
        posted_date: '2021-03-17T07:52:34.666Z'
    };

    await provider.addInteraction({
        state: undefined,
        uponReceiving: 'a post to the event bus',
        willRespondWith: {
            body: {
                data: Matchers.string(expected_response.data),
                event_id: Matchers.string(expected_response.event_id),
                posted_date: Matchers.iso8601DateTimeWithMillis(expected_response.posted_date),
            },
            headers: {
                // this worked in pact v9 but in v11 the returned body has all the 'value', 'regex' and 'pact:matcher:type' fields.
                // 'Content-Type': Matchers.term({
                //     generate: 'application/json;charset=utf-8',
                //     matcher: 'application/json.*'
                // }),
                // this also returns the body without the matchers replaced like above.
                'Content-Type': Matchers.term({
                    generate: 'application/json',
                    matcher: 'application/json.*'
                }),
                // this returns the correct body (with the matchers converted to example values)
                // 'Content-Type': 'application/json',
            },
            status: 201 
        },
        withRequest: {
            body: toTemplate(request),
            headers: {
                // this worked in pact v9 but in v11 return server error (500)
                // 'Content-Type': Matchers.term({
                //     generate: 'application/json;charset=utf-8',
                //     matcher: 'application/json.*'
                // }),
                // this works in pact v11 (I think it is just checking against the generate value not the regex)
                'Content-Type': Matchers.term({
                    generate: 'application/json',
                    matcher: 'application/json.*'
                }),
                // 'Content-Type': 'application/json',
            },
            method: 'POST',
            path: '/endpoint'
        }
    });

    const client = axios.create({ baseURL: provider.mockService.baseUrl });
    const { data } = await <http://client.post|client.post><RequestPayload, AxiosResponse<ResponsePayload>>('/endpoint', request);
    console.dir({ request, expected_response, data }, { depth: null });

    await provider.verify();
    await provider.finalize();
}

main().catch(err => {
    console.log('error: ', err)
    process.exitCode = 1;
})
Relevant log files ``` % npx ts-node test-pack.ts 2023-03-08T215723.371394Z WARN ThreadId(01) pact_models:content types Failed to parse '{"value":"application/json","regex":"application/json.*","pactmatchertype":"regex"}' as a content type: mime parse error: an invalid token was encountered, 7B at position 0 2023-03-08T215723.371436Z WARN ThreadId(01) pact_models:content types Failed to parse '{"value":"application/json","regex":"application/json.*","pactmatchertype":"regex"}' as a content type: mime parse error: an invalid token was encountered, 7B at position 0 2023-03-08T215723.371639Z DEBUG ThreadId(01) pact_ffi:mock serverhandles detected pactmatchertype, will configure a matcher 2023-03-08T215723.371730Z WARN ThreadId(01) pact_models:content types Failed to parse '{"value":"application/json","regex":"application/json.*","pactmatchertype":"regex"}' as a content type: mime parse error: an invalid token was encountered, 7B at position 0 2023-03-08T215723.371735Z WARN ThreadId(01) pact_models:content types Failed to parse '{"value":"application/json","regex":"application/json.*","pactmatchertype":"regex"}' as a content type: mime parse error: an invalid token was encountered, 7B at position 0 2023-03-08T215723.371783Z DEBUG ThreadId(01) pact_ffi:mock serverhandles detected pactmatchertype, will configure a matcher 2023-03-08T215723.371974Z DEBUG ThreadId(01) pact_plugin_driver:catalogue manager Updated catalogue entries: core/transport/http core/transport/https 2023-03-08T215723.371996Z DEBUG ThreadId(01) pact_plugin_driver:catalogue manager Updated catalogue entries: core/content-generator/binary core/content-generator/json core/content-matcher/json core/content-matcher/multipart-form-data core/content-matcher/text core/content-matcher/xml 2023-03-08T215723.372014Z DEBUG ThreadId(01) pact_plugin_driver:catalogue manager Updated catalogue entries: core/matcher/v1-equality core/matcher/v2-max-type core/matcher/v2-min-type core/matcher/v2-minmax-type core/matcher/v2-regex core/matcher/v2-type core/matcher/v3-content-type core/matcher/v3-date core/matcher/v3-datetime core/matcher/v3-decimal-type core/matcher/v3-includes core/matcher/v3-integer-type core/matcher/v3-null core/matcher/v3-number-type core/matcher/v3-time core/matcher/v4-array-contains core/matcher/v4-equals-ignore-order core/matcher/v4-max-equals-ignore-order core/matcher/v4-min-equals-ignore-order core/matcher/v4-minmax-equals-ignore-order core/matcher/v4-not-empty core/matcher/v4-semver 2023-03-08T215723.372170Z DEBUG ThreadId(01) pact_mock_server:mock server Started mock server on 127.0.0.1:61520 2023-03-08T215723.377848Z DEBUG tokio-runtime-worker hyper:protoh1io parsed 6 headers 2023-03-08T215723.377864Z DEBUG tokio-runtime-worker hyper:protoh1conn incoming body is content-length (22 bytes) 2023-03-08T215723.377872Z DEBUG tokio-runtime-worker hyper:protoh1conn incoming body completed 2023-03-08T215723.377876Z … pact-foundation/pact-js