package au.com.dius.pact.consumer.pactproviderrule;
import au.com.dius.pact.consumer.Pact;
import au.com.dius.pact.consumer.PactVerification;
import au.com.dius.pact.consumer.PactVerificationResult;
import au.com.dius.pact.consumer.dsl.PactDslWithProvider;
import au.com.dius.pact.consumer.exampleclients.ConsumerClient;
import au.com.dius.pact.model.BodyMismatch;
import au.com.dius.pact.model.RequestPartMismatch;
import au.com.dius.pact.model.RequestResponsePact;
import org.junit.Rule;
import org.junit.Test;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
public class PactMultiProviderTest {
private static final String NAME_LARRY_JSON = "{\"name\": \"larry\"}";
@Rule
public TestFailureProviderRule mockTestProvider = new TestFailureProviderRule("test_provider", this);
@Rule
public TestFailureProviderRule mockTestProvider2 = new TestFailureProviderRule("test_provider2", this);
@Pact(provider="test_provider", consumer="test_consumer")
public RequestResponsePact createFragment(PactDslWithProvider builder) {
Map<String, String> headers = new HashMap<String, String>();
headers.put("testreqheader", "testreqheadervalue");
return builder
.given("good state")
.uponReceiving("PactProviderTest test interaction")
.path("/")
.method("GET")
.headers(headers)
.willRespondWith()
.status(200)
.headers(headers)
.body("{\"responsetest\": true, \"name\": \"harry\"}")
.uponReceiving("PactProviderTest second test interaction")
.method("OPTIONS")
.headers(headers)
.path("/second")
.body("")
.willRespondWith()
.status(200)
.headers(headers)
.body("")
.toPact();
}
@Pact(provider="test_provider2", consumer="test_consumer")
public RequestResponsePact createFragment2(PactDslWithProvider builder) {
return builder
.given("good state")
.uponReceiving("PactProviderTest test interaction")
.path("/")
.method("PUT")
.body(NAME_LARRY_JSON)
.willRespondWith()
.status(200)
.body("{\"responsetest\": true, \"name\": \"larry\"}")
.toPact();
}
@Test
@PactVerification({"test_provider", "test_provider2"})
public void allPass() throws IOException {
mockTestProvider.validateResultWith((result, t) -> {
assertThat(t, is(nullValue()));
assertThat(result, is(PactVerificationResult.Ok.INSTANCE));
});
doTest("/", NAME_LARRY_JSON);
}
@Test
@PactVerification({"test_provider", "test_provider2"})
public void consumerTestFails() throws IOException, InterruptedException {
mockTestProvider.validateResultWith((result, t) -> {
assertThat(t, is(instanceOf(AssertionError.class)));
assertThat(t.getMessage(), is("Pact Test function failed with an exception: Oops"));
assertThat(result, is(instanceOf(PactVerificationResult.Error.class)));
PactVerificationResult.Error error = (PactVerificationResult.Error) result;
assertThat(error.getError(), is(instanceOf(RuntimeException.class)));
assertThat(error.getError().getMessage(), is("Oops"));
assertThat(error.getMockServerState(), is(PactVerificationResult.Ok.INSTANCE));
});
doTest("/", NAME_LARRY_JSON);
throw new RuntimeException("Oops");
}
@Test
@PactVerification(value = {"test_provider", "test_provider2"})
public void provider1Fails() throws IOException, InterruptedException {
mockTestProvider.validateResultWith((result, t) -> {
assertThat(t, is(instanceOf(AssertionError.class)));
assertThat(t.getMessage(), startsWith("The following mismatched requests occurred:\nUnexpected Request:\n\tmethod: GET\n\tpath: /abc"));
assertThat(result, is(instanceOf(PactVerificationResult.Mismatches.class)));
PactVerificationResult.Mismatches error = (PactVerificationResult.Mismatches) result;
assertThat(error.getMismatches(), hasSize(1));
PactVerificationResult result1 = error.getMismatches().get(0);
assertThat(result1, is(instanceOf(PactVerificationResult.UnexpectedRequest.class)));
PactVerificationResult.UnexpectedRequest unexpectedRequest = (PactVerificationResult.UnexpectedRequest) result1;
assertThat(unexpectedRequest.getRequest().getPath(), is("/abc"));
});
doTest("/abc", NAME_LARRY_JSON);
}
@Test
@PactVerification(value = {"test_provider", "test_provider2"})
public void provider2Fails() throws IOException, InterruptedException {
mockTestProvider2.validateResultWith((result, t) -> {
assertThat(t, is(instanceOf(AssertionError.class)));
assertThat(t.getMessage(), is("The following mismatched requests occurred:\n" +
"PartialMismatch(mismatches=[BodyMismatch(larry,farry,Some(Expected 'larry' but received 'farry'),$.body.name,None)])"));
assertThat(result, is(instanceOf(PactVerificationResult.Mismatches.class)));
PactVerificationResult.Mismatches error = (PactVerificationResult.Mismatches) result;
assertThat(error.getMismatches(), hasSize(1));
PactVerificationResult result1 = error.getMismatches().get(0);
assertThat(result1, is(instanceOf(PactVerificationResult.PartialMismatch.class)));
PactVerificationResult.PartialMismatch error1 = (PactVerificationResult.PartialMismatch) result1;
assertThat(error1.getMismatches(), hasSize(1));
RequestPartMismatch mismatch = error1.getMismatches().get(0);
assertThat(mismatch, is(instanceOf(BodyMismatch.class)));
});
doTest("/", "{\"name\": \"farry\"}");
}
@Test
@PactVerification(value = {"test_provider", "test_provider2"})
public void bothprovidersFail() throws IOException, InterruptedException {
mockTestProvider.validateResultWith((result, t) -> {
assertThat(t, is(instanceOf(AssertionError.class)));
assertThat(t.getMessage(), startsWith("The following mismatched requests occurred:\nUnexpected Request:\n\tmethod: GET\n\tpath: /abc"));
assertThat(result, is(instanceOf(PactVerificationResult.Mismatches.class)));
PactVerificationResult.Mismatches error = (PactVerificationResult.Mismatches) result;
assertThat(error.getMismatches(), hasSize(1));
PactVerificationResult result1 = error.getMismatches().get(0);
assertThat(result1, is(instanceOf(PactVerificationResult.UnexpectedRequest.class)));
PactVerificationResult.UnexpectedRequest unexpectedRequest = (PactVerificationResult.UnexpectedRequest) result1;
assertThat(unexpectedRequest.getRequest().getPath(), is("/abc"));
});
mockTestProvider2.validateResultWith((result, t) -> {
assertThat(t, is(instanceOf(AssertionError.class)));
assertThat(t.getMessage(), is("The following mismatched requests occurred:\n" +
"PartialMismatch(mismatches=[BodyMismatch(larry,farry,Some(Expected 'larry' but received 'farry'),$.body.name,None)])"));
assertThat(result, is(instanceOf(PactVerificationResult.Mismatches.class)));
PactVerificationResult.Mismatches error = (PactVerificationResult.Mismatches) result;
assertThat(error.getMismatches(), hasSize(1));
PactVerificationResult result1 = error.getMismatches().get(0);
assertThat(result1, is(instanceOf(PactVerificationResult.PartialMismatch.class)));
PactVerificationResult.PartialMismatch error1 = (PactVerificationResult.PartialMismatch) result1;
assertThat(error1.getMismatches(), hasSize(1));
RequestPartMismatch mismatch = error1.getMismatches().get(0);
assertThat(mismatch, is(instanceOf(BodyMismatch.class)));
});
doTest("/abc", "{\"name\": \"farry\"}");
}
private void doTest(String path, String json) throws IOException {
ConsumerClient consumerClient = new ConsumerClient(mockTestProvider.getUrl());
consumerClient.options("/second");
try {
consumerClient.getAsMap(path, "");
} catch (IOException e) {
}
try {
new ConsumerClient(mockTestProvider2.getUrl()).putAsMap("/", json);
} catch (IOException e) {
}
}
}