pact-foundation / pact-jvm

JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://docs.pact.io
Apache License 2.0
1.08k stars 479 forks source link

Defining (HTTP-Request) content type for url based pactFile in PactVerificationTask #83

Closed hendrikstill closed 9 years ago

hendrikstill commented 9 years ago

If I want to use a external pactFile from an HTTP-Server to verify my Provider with the PactVerificationTask my gradle file looks like this

pact {
    serviceProviders {
        productPriceServiceProvider {
            protocol = 'http'
            host = 'localhost'
            port = 10101
            path = '/'
            hasPactWith('productServiceConsumer') {
                pactFile = url("http://localhost:9292/pacts/provider/Product_Price_Service/consumer/Product_Service/latest")
            }
        }
    }
}

This works fine, but if you try to access url's which expect a specific Header (e.g. Accept: 'application/json'), the Task will not fetch the correct content. This is the case if you use the Pact Broker. The request of a pact e.g. "http://localhost:9292/pacts/provider/Product_Price_Service/consumer/Product_Service/latest" without the (Accept: 'application/json') will return a HTML-Page.

The request parameters should be passed into this line [1] as parameter of newInputStream method (see [2]).

[1]https://github.com/DiUS/pact-jvm/blob/master/pact-jvm-provider-gradle/src/main/groovy/au/com/dius/pact/provider/gradle/PactVerificationTask.groovy#L34 [2]http://groovy.codehaus.org/groovy-jdk/java/net/URL.html#newInputStream%28java.util.Map%29

uglyog commented 9 years ago

I've added an accept header to the URL fetch. Hope this fixes your issue.

bethesque commented 9 years ago

This does not sound right. The default content type returned by the pact broker for a pact resource is application/json. It will only return a HTML page if the Accept header includes HTML. I'd suggest that the client that is making the request might be adding an HTML Accept header by default if one is not specified.

If you execute curl http://localhost:9292/pacts/provider/Product_Price_Service/consumer/Product_Service/latest do you get HTML or JSON?

hendrikstill commented 9 years ago

@bethesque you are right, with curl I get the correct response. So as correction: the Pact Broker returns a JSON, if no Accept Header is given. But I will validate if 4ddb281 fixes my problem

gthicks commented 9 years ago

This change doesn't appear to have solved the problem. I looks like the accept header is not being set correctly. Using a packet sniffer, I found that requests are being made with "Accept: text/html, image/gif, image/jpeg"

I think that the proper syntax for setting the request headers is:

pact = Pact$.MODULE$.from(new StreamInput(consumer.pactFile.newInputStream(requestProperties: ['Accept': 'application/json'])))

based on http://mrhaki.blogspot.com/2011/09/groovy-goodness-use-connection.html

I can provide a pull request if you would like.

gthicks commented 9 years ago

This is now working correctly for my purposes. Anyone have any objection to closing this issue?

uglyog commented 9 years ago

Closed. Thanks again for the pull request.