-
-
Notifications
You must be signed in to change notification settings - Fork 354
Description
Software versions
Please provide at least OS and version of pact-js
OS: macOS (arm64)
Consumer Pact library: Pact-JS v13.2.0
Provider Pact library: Pact-JS v13.2.0 (with pact-core@15.2.1)
Node Version: v18.20.2
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
When configuring the Verifier with a stateHandlers object that defines a no-op function for a provider state (e.g., "quote can be created"), the verifier should:
Execute the stateHandlers function locally.
Not send any HTTP requests for state setup (e.g., no POST to http://127.0.0.1:/_pactSetup).
Proceed directly to verifying the interaction against the providerBaseUrl (<>).
The stateHandlers should override the default state setup behavior, especially when the provider doesn’t require external setup.
Actual behaviour
Despite defining a stateHandlers function for "quote can be created", the verifier:
Registers the handler (logs show it’s configured) but does not execute it (no handler logs appear).
Sends a POST request to http://127.0.0.1:/_pactSetup (e.g., 127.0.0.1:52667), which times out after 30 seconds because no local server is running.
Fails with: MismatchResult::Error("Invalid response: error sending request for url (http://127.0.0.1:/_pactSetup)", None).
This happens even with a no-op stateHandlers function and persists whether requestFilter is present or not (though the presence of requestFilter might exacerbate or alter the behavior).
Steps to reproduce
Install Pact-JS: npm install @pact-foundation/pact@13.2.0.
Create a Pact file at pacts/consumer-pact.json with the contents below.
Relevant log files
consumer-pact.json
`const path = require('path');
const { Verifier } = require('@pact-foundation/pact');
const PROVIDER_NAME = 'provider';
const CONSUMER_NAME = 'consumer';
const baseUrl = 'my-servivce-url';
const pactDir = path.resolve(process.cwd(), 'pacts');
// Mock request filter
const requestFilter = (req, res, next) => {
console.log('Request filter called for:', req.method, req.path);
req.headers['content-type'] = 'application/json';
req.headers['accept'] = 'application/json';
next();
};
describe('Pact Verification for ForexV3-Funding', () => {
it('validates forex quote endpoint expectations against local pact', async function () {
this.timeout(60000);
const localPactFile = path.join(pactDir, `${CONSUMER_NAME.toLowerCase()}-${PROVIDER_NAME.toLowerCase()}.json`);
const verifier = new Verifier({
provider: PROVIDER_NAME,
providerBaseUrl: baseUrl,
pactUrls: [localPactFile],
stateHandlers: {
'quote can be created': () => {
console.log('State handler for "quote can be created" executed');
return Promise.resolve();
}
},
requestFilter, // Comment this out to test without it
customProviderHeaders: [
'Content-Type: application/json',
'Accept: application/json'
],
logLevel: 'DEBUG'
});
try {
await verifier.verifyProvider();
console.log('Pact verification successful for local file');
} catch (err) {
console.error('Pact verification failed:', err);
throw err;
}
});
});_Please ensure you set logging to
DEBUG` and attach any relevant log files here (or link to a gist)._
Comment out requestFilter in the Verifier options and rerun to see if the behavior changes (testing your hypothesis).