<#1025 Asynchronous/Messages metadata validation f...
# pact-js
g
#1025 Asynchronous/Messages metadata validation fail Issue created by ColdFire87 Hi, I have generated a pact for a message based interaction. The gist of it is:
Copy code
const messagePact = new MessageConsumerPact({
    consumer: process.env.CONSUMER || 'AuditService',
    provider: 'CardService_Async',
    logLevel: 'warn',
    dir: path.resolve(process.cwd(), 'pacts'),
    spec: SpecificationVersion.SPECIFICATION_VERSION_V3,
    pactfileWriteMode: 'update',
});

describe('Kafka Pact test', () => {
    describe('receive an audit log message', () => {
        test('accepts a message', () => {
            messagePact
                .expectsToReceive('a message event update')
                .withMetadata({
                    'content-type': 'application/json',
                    'x-kafka-topic': KAFKA_TOPIC,
                })
                .withContent({
                    viewer: like('John Doe'),
                    card: {
                        id: like('08'),
                        type: regex(/^(CREDIT_CARD|PERSONAL_LOAN)$/, 'CREDIT_CARD'),
                        name: like('MyFlexiPay'),
                        version: like('v1'),
                    },
                })
                .verify(asynchronousBodyHandler(({content}) => streamHandler(content)));
        });
    });
});
Things I noticed when using different specification versions: • when using
SPECIFICATION_VERSION_V1
or
SPECIFICATION_VERSION_V2
,
asynchronousBodyHandler
passes the following data to the callback:
Copy code
{
  card: { id: '08', name: 'MyFlexiPay', type: 'CREDIT_CARD', version: 'v1' },
  viewer: 'John Doe'
}
• when using
SPECIFICATION_VERSION_V3
,
asynchronousBodyHandler
passes the following data to the callback:
Copy code
{
  content: {
    card: {
      id: '08',
      name: 'MyFlexiPay',
      type: 'CREDIT_CARD',
      version: 'v1'
    },
    viewer: 'John Doe'
  },
  contentType: 'application/json',
  encoded: false
}
SPECIFICATION_VERSION_V4
is not supported by
MessageConsumerPact
Regardless of using V1 or V2, the same pact contents is generated with this pact metadata:
Copy code
"metadata": {
  "pact-js": {
    "version": "10.1.4"
  },
  "pactRust": {
    "ffi": "0.3.12",
    "models": "0.4.5"
  },
  "pactSpecification": {
    "version": "3.0.0"
  }
}
Although I only specify
content-type
&
x-kafka-topic
for the message metadata,
contentType
is automatically added:
Copy code
"metadata": {
  "content-type": "application/json",
  "contentType": "application/json",
  "x-kafka-topic": "audit-log"
}
AuditService-CardService_Async_V1_V2.json.txt When using V3, I get this pact metadata:
Copy code
"metadata": {
  "pact-js": {
    "version": "10.1.4"
  },
  "pactRust": {
    "ffi": "0.3.12",
    "models": "0.4.5"
  },
  "pactSpecification": {
    "version": "4.0"
  }
}
The message metadata seems to be correct now (no additional
contentType
field added):
Copy code
"metadata": {
  "content-type": "application/json",
  "x-kafka-topic": "audit-log"
}
AuditService-CardService_Async_V3.json.txt * * * On the provider side, I have this verification code:
Copy code
const commonVerifierConfig = (commonEnv) => {
    return {
        logLevel: 'warn',
        providerVersion: commonEnv.GIT_COMMIT_SHA,
        providerVersionBranch: commonEnv.GIT_BRANCH,
        publishVerificationResult: commonEnv.PUBLISH_VERIFICATION_RESULTS,

        // Similar to state handlers?
        messageProviders: {
            'a message event update': () => JSON.parse(buildMessage(
                'John Doe',
                {id: '08', type: 'CREDIT_CARD', name: 'MyFlexiPay', version: 'v1'},
            ).value),
        },
    };
};

const verifySinglePact = (commonEnv) => () => {
    it('validates the expectations of CardService', async () => {
        // Initialize the Pact verifier
        const verifier = new MessageProviderPact({
            ...commonVerifierConfig(commonEnv),
            pactUrls: [process.env.PACT_URL],
        });

        // Verify pacts
        const output = await verifier.verify();
        console.log(output);
    });
};
where
buildMessage
is:
Copy code
const buildMessage = (viewer, card) => ({
    value: JSON.stringify({viewer, card}),
    headers: {
        'content-type': 'application/json',
        'x-kafka-topic': KAFKA_TOPIC,
    },
});
The validation for the message body passes, but the one for the message metadata fails:

image

Other things I noticed: • The documentation shows a
metaData
field (capital
D
), whereas all contracts I generated (V1/V2/V3) have
metadata

image

• Pactflow also shows `metaData`:

image

I believe, regardless of specification version, Pactflow expects
metaData
. The original thread of discussion on Slack -> https://pact-foundation.slack.com/archives/C9VBGLUM9/p1667408672806869 pact-foundation/pact-js
m
@Stefan Tertan apologies, I didn’t notice that when you raised the issue it was for another repo. Shuying has made me aware of it and I have moved it into the correct repo for fixing
s
thanks 👍
g
s
got this working... thanks for the help! 👍 🎉
🎉 1
m
Excellent! thanks for confirming, and the great bug report 🙌
👍 1