<#1037 Provider states are not being setup> Issue ...
# pact-js-development
g
#1037 Provider states are not being setup Issue created by iamchughmayank Software versionsOS: Mac OSX 13.0.1 • Consumer Pact library: Pact JS v10.4.0 • Provider Pact library: Pact JS v10.4.0 • Node Version: 14.18.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 Issue Description I am new to Pact and I am trying to create an MVP for contract testing between two of our services. I was able to setup a simple example test without any state, however, I am unable to setup multiple states using
stateHandlers
. I have tried following the example here for
V3
and also here which uses
setup
in the providerState but to no avail. When I run the tests, I am observing two issues with my tests: 1.
providerState
is not being set properly before the
requestFilter
2. Even though the contract has the
request.method
as
GET
, the API call to the provider service is going with
POST
. If I manually override it in the
requestFilter
, I am able to convert it to
GET
I have checked various forums/existing issues and Stackoverflow, however, I could not find anyone facing problems with
stateHandlers
basic implementation. Any help in Expected behaviour I am expecting the stateHandler to change a variable value as per the state name which will be then picked up by the
requestFilter
to bring provider in desirable state. Steps to reproduce _Demo repository_: https://github.com/iamchughmayank/pact-stateHandler-issue-demo Relevant log files Pact File
Copy code
{
  "consumer": {
    "name": "SupportService"
  },
  "interactions": [
    {
      "description": "a request to get client by id",
      "providerStates": [
        {
          "name": "valid id"
        }
      ],
      "request": {
        "method": "GET",
        "path": "/clients/26"
      },
      "response": {
        "body": {
          "data": [
            {
              "account_status": "test",
              "active": 1,
              "client_id": 24297,
              "client_name": "Rowe - Cummings",
              "created": "2017-07-14T16:32:29.000Z",
              "email_address": "<mailto:Grover.McCullough@yahoo.com|Grover.McCullough@yahoo.com>"
            }
          ],
          "result": 1,
          "status": "success"
        },
        "headers": {
          "Content-Type": "application/json"
        },
        "matchingRules": {
          "body": {
            "$": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            }
          }
        },
        "status": 200
      }
    }
  ],
  "metadata": {
    "pact-js": {
      "version": "10.4.0"
    },
    "pactRust": {
      "ffi": "0.3.19",
      "models": "1.0.3"
    },
    "pactSpecification": {
      "version": "3.0.0"
    }
  },
  "provider": {
    "name": "ClientService"
  }
}
Provier Spec
Copy code
/**
 * External dependencies
 */
import {Verifier}  from '@pact-foundation/pact';
import path, { dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));

describe( 'pact Verification', () => {
	let clientId;

	const baseOptions = {
		providerBaseUrl: '<http://localhost:3000>',
		provider: 'ClientService',
		providerVersion: '1.0.0',
		log: path.resolve( process.cwd(), 'logs', 'pact.log' ),
		logLevel: 'DEBUG',
		pactUrls: [ path.resolve( __dirname, './SupportService-ClientService.json' ) ],
		stateHandlers: {
			'valid id': {
				setup: () => {
					clientId = '26';
					return Promise.resolve( 'client id set to 26' );
				},

			},
			// I have also tried without setup as follows:
			// 'valid id': () => {
			// 	clientId = '26';
			// 	return Promise.resolve( 'client id set to 26' );
			// },
		},
		requestFilter: ( req, res, next ) => {
			req.url = `/clients/${ clientId }`;
			req.method = 'GET';
			next();
		},
	};

	it( 'should validate the expectations of SupportService for fetching one client by id', () => {
		const verifier = new Verifier( baseOptions );
		return verifier.verifyProvider();
	} );
} );
In the above case, when I run the test, I get a
GET
request with
clientId
as
undefined
even though the
stateHandler
has been setup to change the id
ClientService | 172.17.0.1 - - [29/Dec/2022:15:46:56 +0000] "GET /clients/undefined HTTP/1.1" 404 67 "-" "-"
The pact tests fail with error:
Copy code
Verifying a pact between SupportService and ClientService

  a request to get client by id
     Given valid id
      Request Failed - One or more of the setup state change handlers has failed


Failures:

1) Verifying a pact between SupportService and ClientService Given valid id - a request to get client by id - One or more of the setup state change handlers has failed
Debug logs ``` 2022-12-29T192258.585776Z ERROR ThreadId(02) verify_pact_internal{provider_info=ProviderInfo { name: "ClientService", protocol: "http", host: "127.0.0.1", port: Some(52068), path: "/", transports: [ProviderTransport { transport: "http", port: Some(52068), path: Some("/"), scheme: None }] } filter=None pact=RequestResponsePact { consumer: Consumer { name: "SupportService" }, provider: Provider { name: "ClientService" }, interactions: [RequestResponseInteraction { id: None, description: "a request to get client by id", provider_states: [ProviderState { name: "valid id", params: {} }], request: Request { method: "GET", path: "/clients/26", query: None, headers: None, body: Missing, matching_rules: MatchingRules { rules: {} }, generators: Generators { categories: {} } }, response: Response { status: 200, headers: Some({"Content-Type": ["application/json"]}), body: Present(b"{\"data\":[{\"account_status\":\"test\",\"active\":1,\"client_id\":24297,\"client_name\":\"Rowe - Cummings\",\"created\":\"2017-07-14T163229.000Z\",\"email_address\":\"Grover.McCullough@yahoo.com\"}],\"result\":1,\"status\":\"success\"}", None, None), matching_rules: MatchingRules { rules: {BODY: MatchingRuleCategory { name: BODY, rules: {DocPath { path_tokens: [Root], expr: "$" }: RuleList { rules: [Type], rule_logic: And, cascaded: false }} }} }, generators: Generators { categories: {} } } }], metadata: {"pact-js": {"version": "10.4.0"}, "pactRust": {"ffi": "0.3.19", "models": "1.0.3"}, "pactSpecification": {"version": "3.0.0"}}, specification_version: V3 } options=VerificationOptions { request_filter: None, disable_ssl_verification: false, request_timeout: 30000, custom_headers: {}, coloured_output: true, no_pacts_is_error: true } provider_state_executor=HttpRequestProviderStateExecutor { state_change_url: Some("http://127.0.0.1:52068/_pactSetup"), state_change_teardown: true, state_change_body: true, reties: 3 } pending=false}:verify_interaction{interaction="a request to get client by id"}:verify_interaction{provider=ProviderInfo { name: "ClientService", protocol: "http", host: "127.0.0.1", port: Some(52068), path: "/", transports: [ProviderTransport { transport: "http", port: Some(52068), path: Some("/"), scheme: None }] } interactio… pact-foundation/pact-js