Hi, My application calls a.o. a few file download...
# pact-jvm
m
Hi, My application calls a.o. a few file download endpoints that should be covered by consumer driven contract tests. I don't care about the downloaded content but want to verify that the body is not empty by checking that the Content-Length header is set to a value > 0. Used version: au.com.dius.pact.consumerjunit4.3.10 Consumer code:
Copy code
@Override
protected RequestResponsePact createPact(final PactDslWithProvider aBuilder)
{
  final Map<String, String> requestHeaders = ChatTestUtil.createRequestHeaderMap();

  return aBuilder//
    .given("A text prod finished successfully")//
    .uponReceiving("A request to download text")//
    .pathFromProviderState("/textresult/${jobId}", "/textresult/" + ChatTestUtil.DUMMY_JOB_ID)//
    .method("GET")//
    .headers(requestHeaders)
    .willRespondWith()//
    .status(200)//
    .headers(Map.of("Content-Type", "text/plain"))//
    .matchHeader("Content-Length", "[1-9][0-9]+")//
    .body(PactDslRootValue.stringType())
  //.body(PactDslRootValue.stringMatcher(".*", "whatever"))
  //.withBinaryData("FooBar".getBytes(), "text/plain")
    .toPact();
  }
The variant with "*.body(PactDslRootValue.stringType())*" fails with following exception on provider side:
Copy code
java.lang.AssertionError: 
	Failures:

	1) Verifying a pact between Core_Chat_Client and Chat_Service - A request to download text

		1.1) BodyMismatch: / BodyMismatch: Expected body 'string' to match 'Participants:
	TestUser

	TestUser sent message
	16 Oct 2001 10:14 PM +02:00 Hello World

	TestUser sent message
	16 Oct 2001 10:14 PM +02:00 Lorem Ipsumupczl
	' using equality but did not match
The variant with "*.body(PactDslRootValue.stringMatcher(".*", "whatever")*" fails with also on provider side:
Copy code
java.lang.AssertionError:
	Failures:
	1) Verifying a pact between Core_Chat_Client and Chat_Service - A request to download text
	    1.1) BodyMismatch: / BodyMismatch: Expected body 'whatever' to match 'Participants:
	TestUser
	TestUser sent message
	16 Oct 2001 10:14 PM +02:00 Hello World
	TestUser sent message
	16 Oct 2001 10:14 PM +02:00 Lorem Ipsumphaai
	' using regex '.*' but did not match
And the last variant "*.withBinaryData("FooBar".getBytes(), "text/plain")*" fails also:
Copy code
java.lang.AssertionError:
	Failures:

	1) Verifying a pact between Core_Chat_Client and Chat_Service - A request to download text

		1.1) BodyMismatch: / BodyMismatch: Expected body 'FooBar' to match 'Participants:
	TestUser

	TestUser sent message
	16 Oct 2001 10:14 PM +02:00 Hello World

	TestUser sent message
	16 Oct 2001 10:14 PM +02:00 Lorem Ipsumxetoj
	' using equality but did not match
How can I verify that the body of a response is not empty?
u
I think
PactDslRootValue.stringMatcher
is the only one that works on plain text bodies. You should use
.+
as the regex as
.*
can match an empty string (* means zero or more), and you may need to add the start and end markers.
Try
^.+$
m
Thanks for your suggestion @uglyog. We found the problem meanwhile. Pact verification fails in case that the body contains line breaks, e.g. "Hello \r\n World".
Copy code
Failures:
1) Verifying a pact between Core_Chat_Client and Chat_Service - A request to download text
    1.1) BodyMismatch: / BodyMismatch: Expected body 'whatever' to match 'Hello 
 World' using regex '^.+$' but did not match
    at au.com.dius.pact.provider.junit5.PactVerificationContext.verifyInteraction(PactJUnit5VerificationProvider.kt:94)
    at foo.ContractVerificationTest.pactVerificationTestTemplate(ContractVerificationTest.java:147)
I attached also the JSON contract. Should I open a bug for this issue?
u
Yes, please do
m
Thanks @uglyog, I confirm that your fix for #1579 is working. I have another question regarding the verification of file downloads. Now I want to verify that the body is not empty for files with mimetype "application/pdf" or "application/octet-stream". I tried to use the same matcher PactDslRootValue.stringMatcher("^.+$", "whatever") that I used for text downloads, but this does not work. Consumer code:
Copy code
protected RequestResponsePact createPact(final PactDslWithProvider aBuilder) {
    return aBuilder//
        .given("A image prod finished successfully")//
        .uponReceiving("A request to download an image")//
        .pathFromProviderState("/result/${jobId}", "/result/" + ChatTestUtil.DUMMY_JOB_ID)//
        .method("GET")//
        .headers(myRequestHeaders)
        //
        .willRespondWith()//
        .status(200)//
        .headers(Map.of("Content-Type", "application/pdf"))//
        .matchHeader(ChatProductionApi.HEADER_PARAM_PAGE_COUNT, "[0-9]+")//
        .body(PactDslRootValue.stringMatcher("^.+$", "whatever"))
The generated pact file looks like this:
Copy code
{
  "consumer": {
    "name": "Core_Chat_Client"
  },
  "interactions": [
    {
      "description": "A request to download an image",
      "providerStates": [
        {
          "name": "A image prod finished successfully"
        }
      ],
      "request": {
        "generators": {
          "path": {
            "dataType": "STRING",
            "expression": "/result/${jobId}",
            "type": "ProviderState"
          }
        },
        "headers": {
          "RM-MDC-TOKEN": "dummyTraceId"
        },
        "method": "GET",
        "path": "/result/dummyJobId"
      },
      "response": {
        "headers": {
          "Content-Type": "application/pdf",
          "PDF-PAGE-COUNT": "32"
        },
        "matchingRules": {
          "header": {
            "PDF-PAGE-COUNT": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "regex",
                  "regex": "[0-9]+"
                }
              ]
            }
          }
        },
        "status": 200
      }
    }
  ],
  "metadata": {
    "pact-jvm": {
      "version": "4.3.13"
    },
    "pactSpecification": {
      "version": "3.0.0"
    }
  },
  "provider": {
    "name": "Chat_Service"
  }
}
Failure on provider side:
Copy code
Failures:
1) Verifying a pact between Core_Chat_Client and Chat_Service - A request to download an image has a matching body
    1.1) body: / Actual body 'Hello 
 World' is not equal to the expected body 'whatever'

java.lang.AssertionError: Core_Chat_Client - Upon A request to download an image 
Failures:
1) Verifying a pact between Core_Chat_Client and Chat_Service - A request to download an image has a matching body
    1.1) body: / Actual body 'Hello 
 World' is not equal to the expected body 'whatever'

    at au.com.dius.pact.provider.junit5.PactVerificationContext.verifyInteraction(PactVerificationContext.kt:66)
    at com.recommind.autotest.ContractVerificationTest.pactVerificationTestTemplate(ContractVerificationTest.java:147)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at ...
The provider simply sent "Hello World" as response body in this test. How can I validate that the provider sends any data in the response body for mimetypes other than plain text ?
u
Use
withBinaryData
, it does exactly what you need
m
Thanks, it works!