pythonpactpact-python

Pact: how to set up provider states


I'm looking at the Python implementation of Pact and trying to set up provider states. It seems to say that the way to do it is for the provider to have an endpoint built into the service that is called to put the provider in the correct state. The issue is I can't find any documentation on what that endpoint is actually supposed to look like. What is the input, what does it return, etc.

I tried looking at the default ruby implementation, and it seems to imply a completely different mechanism for putting the provider into a certain state. This looks like it uses a ruby module that gets required by the verifier script, with no HTTP requests involved at all.

What is the correct way to set up a provider state? If it requires setting up additional endpoints, I need to know what that endpoint is supposed to look like. If it requires a class/module to be imported to the verifier script, I need to know how that is implemented in languages other than ruby.


Solution

  • As per the documentation in Pact-Python, it's a bit open ended how you actually accomplish this. Personally, how I would do it for say, a node provider as I normally don't work with Python, is within my provider tests, I would create a server on an unused port whose purpose is to receive states from pact and set them up properly. Once you run the tests, this small server would get hit from pact with a JSON file that includes, the consumer, provider and the state.

    For example, here's a node example:

    var http = require('http');
    
    beforeAll(function(){
        // PROVIDER STATE LISTENER 
        http.createServer(function (req, res) {
            var body = [];
            // Ignore this bit, this is just how node does server request/response
            req.on('data', (chunk) => {
                body.push(chunk);
            }).on('end', () => {
                // Get body, parse JSON.  JSON includes 'consumer' string and 'states' array of string
                var json = JSON.parse(Buffer.concat(body).toString());
    
    
                // THIS IS WHERE YOU NEED TO SETUP YOUR STATE
                res.status = 200; 
                switch(json.state) {
                    case "When User does something": // this is the actual name of the state that's specified by your consumer, which is found in the contract
                        // Setup any data that relates to your state here, like adding rows to a DB, setting environment variables, etc
                        break;
                    // Add another states that are used in your provider tests
                    default:
                        res.status = 500;
                        res.statusMessage = "Missing state '" + json.state + "'";
                }
                res.end(); // Send the response back
            });
        }).listen(9001);
    })
    
    // Run your tests
    it("Test Pact Interactions", function() {
        return pact.verifyPacts({
            // options here
            providerStatesSetupUrl: "http://localhost:9001"
        });
    });
    

    I hope that makes sense.