Fixing missing context-path usage
without this change when the user adds context-path it gets ignored and WireMock fails to register stubs with this change we update the WireMock instance to include the context path fixes #99
This commit is contained in:
@@ -632,7 +632,7 @@ The aforementioned contract is an agreement between two sides that:
|
||||
|
||||
- if an HTTP request is sent with
|
||||
** a method `PUT` on an endpoint `/fraudcheck`
|
||||
** JSON body with `clientId` matching the regular expression `[0-9]{10}` and `loanAmount` equal to `99999`
|
||||
** JSON body with `clientPesel` matching the regular expression `[0-9]{10}` and `loanAmount` equal to `99999`
|
||||
** and with a header `Content-Type` equal to `application/vnd.fraud.v1+json`
|
||||
- then an HTTP response would be sent to the consumer that
|
||||
** has status `200`
|
||||
@@ -875,7 +875,7 @@ public void validate_shouldMarkClientAsFraud() throws Exception {
|
||||
// given:
|
||||
MockMvcRequestSpecification request = given()
|
||||
.header("Content-Type", "application/vnd.fraud.v1+json")
|
||||
.body("{\"clientId\":\"1234567890\",\"loanAmount\":99999}");
|
||||
.body("{\"clientPesel\":\"1234567890\",\"loanAmount\":99999}");
|
||||
|
||||
// when:
|
||||
ResponseOptions response = given().spec(request)
|
||||
|
||||
@@ -201,7 +201,7 @@ The aforementioned contract is an agreement between two sides that:
|
||||
|
||||
- if an HTTP request is sent with
|
||||
** a method `PUT` on an endpoint `/fraudcheck`
|
||||
** JSON body with `clientId` matching the regular expression `[0-9]{10}` and `loanAmount` equal to `99999`
|
||||
** JSON body with `clientPesel` matching the regular expression `[0-9]{10}` and `loanAmount` equal to `99999`
|
||||
** and with a header `Content-Type` equal to `application/vnd.fraud.v1+json`
|
||||
- then an HTTP response would be sent to the consumer that
|
||||
** has status `200`
|
||||
@@ -375,7 +375,7 @@ public void validate_shouldMarkClientAsFraud() throws Exception {
|
||||
// given:
|
||||
MockMvcRequestSpecification request = given()
|
||||
.header("Content-Type", "application/vnd.fraud.v1+json")
|
||||
.body("{\"clientId\":\"1234567890\",\"loanAmount\":99999}");
|
||||
.body("{\"clientPesel\":\"1234567890\",\"loanAmount\":99999}");
|
||||
|
||||
// when:
|
||||
ResponseOptions response = given().spec(request)
|
||||
|
||||
@@ -285,7 +285,7 @@ class LoanApplicationServiceSpec extends Specification {
|
||||
def 'should successfully apply for loan'() {
|
||||
given:
|
||||
LoanApplication application =
|
||||
new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123)
|
||||
new LoanApplication(client: new Client(clientPesel: '12345678901'), amount: 123.123)
|
||||
when:
|
||||
LoanApplicationResult loanApplication == sut.loanApplication(application)
|
||||
then:
|
||||
|
||||
@@ -196,7 +196,7 @@ class StubRunnerExecutor implements StubFinder {
|
||||
return condition ? this.stubServer.getStubUrl() : null;
|
||||
}
|
||||
|
||||
private void startStubServers(StubRunnerOptions stubRunnerOptions,
|
||||
private void startStubServers(final StubRunnerOptions stubRunnerOptions,
|
||||
final StubConfiguration stubConfiguration, StubRepository repository) {
|
||||
final List<WiremockMappingDescriptor> mappings = repository
|
||||
.getProjectDescriptors();
|
||||
@@ -206,7 +206,7 @@ class StubRunnerExecutor implements StubFinder {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("There are no HTTP related contracts. Won't start any servers");
|
||||
}
|
||||
this.stubServer = new StubServer(stubConfiguration, mappings, contracts, new NoOpHttpServerStub());
|
||||
this.stubServer = new StubServer(stubRunnerOptions, stubConfiguration, mappings, contracts, new NoOpHttpServerStub());
|
||||
return;
|
||||
}
|
||||
if (contracts.isEmpty()) {
|
||||
@@ -215,14 +215,14 @@ class StubRunnerExecutor implements StubFinder {
|
||||
+ "that's why will start the server - maybe you know what you're doing...");
|
||||
}
|
||||
if (port != null && port >= 0) {
|
||||
this.stubServer = new StubServer(stubConfiguration, mappings, contracts,
|
||||
this.stubServer = new StubServer(stubRunnerOptions, stubConfiguration, mappings, contracts,
|
||||
new WireMockHttpServerStub(port));
|
||||
} else {
|
||||
this.stubServer = this.portScanner
|
||||
.tryToExecuteWithFreePort(new PortCallback<StubServer>() {
|
||||
@Override
|
||||
public StubServer call(int availablePort) {
|
||||
return new StubServer(stubConfiguration,
|
||||
return new StubServer(stubRunnerOptions, stubConfiguration,
|
||||
mappings, contracts,
|
||||
new WireMockHttpServerStub(availablePort));
|
||||
}
|
||||
|
||||
@@ -61,6 +61,11 @@ public class StubRunnerOptions {
|
||||
*/
|
||||
final Map<StubConfiguration, Integer> stubIdsToPortMapping;
|
||||
|
||||
/**
|
||||
* Context Path of the server
|
||||
*/
|
||||
final String contextPath;
|
||||
|
||||
public StubRunnerOptions(Integer minPortValue, Integer maxPortValue,
|
||||
String stubRepositoryRoot, boolean workOffline, String stubsClassifier,
|
||||
Collection<StubConfiguration> dependencies,
|
||||
@@ -72,6 +77,21 @@ public class StubRunnerOptions {
|
||||
this.stubsClassifier = stubsClassifier;
|
||||
this.dependencies = dependencies;
|
||||
this.stubIdsToPortMapping = stubIdsToPortMapping;
|
||||
this.contextPath = "";
|
||||
}
|
||||
|
||||
public StubRunnerOptions(Integer minPortValue, Integer maxPortValue,
|
||||
String stubRepositoryRoot, boolean workOffline, String stubsClassifier,
|
||||
Collection<StubConfiguration> dependencies,
|
||||
Map<StubConfiguration, Integer> stubIdsToPortMapping, String contextPath) {
|
||||
this.minPortValue = minPortValue;
|
||||
this.maxPortValue = maxPortValue;
|
||||
this.stubRepositoryRoot = stubRepositoryRoot;
|
||||
this.workOffline = workOffline;
|
||||
this.stubsClassifier = stubsClassifier;
|
||||
this.dependencies = dependencies;
|
||||
this.stubIdsToPortMapping = stubIdsToPortMapping;
|
||||
this.contextPath = contextPath;
|
||||
}
|
||||
|
||||
public Integer port(StubConfiguration stubConfiguration) {
|
||||
@@ -90,18 +110,6 @@ public class StubRunnerOptions {
|
||||
return this.maxPortValue;
|
||||
}
|
||||
|
||||
public String getStubRepositoryRoot() {
|
||||
return this.stubRepositoryRoot;
|
||||
}
|
||||
|
||||
public boolean isWorkOffline() {
|
||||
return this.workOffline;
|
||||
}
|
||||
|
||||
public String getStubsClassifier() {
|
||||
return this.stubsClassifier;
|
||||
}
|
||||
|
||||
public Collection<StubConfiguration> getDependencies() {
|
||||
return this.dependencies;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ public class StubRunnerOptionsBuilder {
|
||||
private String stubRepositoryRoot;
|
||||
private boolean workOffline = false;
|
||||
private String stubsClassifier = "stubs";
|
||||
private String contextPath = "";
|
||||
|
||||
public StubRunnerOptionsBuilder() {
|
||||
}
|
||||
@@ -95,18 +96,25 @@ public class StubRunnerOptionsBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public StubRunnerOptionsBuilder withContextPath(String contextPath) {
|
||||
this.contextPath = contextPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StubRunnerOptionsBuilder withOptions(StubRunnerOptions options) {
|
||||
this.minPortValue = options.minPortValue;
|
||||
this.maxPortValue = options.maxPortValue;
|
||||
this.stubRepositoryRoot = options.stubRepositoryRoot;
|
||||
this.workOffline = options.workOffline;
|
||||
this.stubsClassifier = options.stubsClassifier;
|
||||
this.contextPath = options.contextPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StubRunnerOptions build() {
|
||||
return new StubRunnerOptions(this.minPortValue, this.maxPortValue, this.stubRepositoryRoot,
|
||||
this.workOffline, this.stubsClassifier, buildDependencies(), this.stubIdsToPortMapping);
|
||||
this.workOffline, this.stubsClassifier, buildDependencies(), this.stubIdsToPortMapping,
|
||||
this.contextPath);
|
||||
}
|
||||
|
||||
private Collection<StubConfiguration> buildDependencies() {
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Collection;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.contract.spec.Contract;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
|
||||
@@ -34,9 +35,11 @@ class StubServer {
|
||||
final StubConfiguration stubConfiguration;
|
||||
final Collection<WiremockMappingDescriptor> mappings;
|
||||
final Collection<Contract> contracts;
|
||||
private final StubRunnerOptions stubRunnerOptions;
|
||||
|
||||
StubServer(StubConfiguration stubConfiguration, Collection<WiremockMappingDescriptor> mappings,
|
||||
Collection<Contract> contracts, HttpServerStub httpServerStub) {
|
||||
StubServer(StubRunnerOptions stubRunnerOptions, StubConfiguration stubConfiguration,
|
||||
Collection<WiremockMappingDescriptor> mappings, Collection<Contract> contracts, HttpServerStub httpServerStub) {
|
||||
this.stubRunnerOptions = stubRunnerOptions;
|
||||
this.stubConfiguration = stubConfiguration;
|
||||
this.mappings = mappings;
|
||||
this.httpServerStub = httpServerStub;
|
||||
@@ -68,13 +71,23 @@ class StubServer {
|
||||
|
||||
public URL getStubUrl() {
|
||||
try {
|
||||
return new URL("http://localhost:" + getPort());
|
||||
return new URL("http://localhost:" + getPort() + prependSlashIfNecessary(this.stubRunnerOptions.contextPath));
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
throw new IllegalStateException("Cannot parse URL", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String prependSlashIfNecessary(String contextPath) {
|
||||
if (!StringUtils.hasText(contextPath)) {
|
||||
return "";
|
||||
}
|
||||
if (contextPath.startsWith("/")) {
|
||||
return contextPath;
|
||||
}
|
||||
return "/" + contextPath;
|
||||
}
|
||||
|
||||
public StubConfiguration getStubConfiguration() {
|
||||
return this.stubConfiguration;
|
||||
}
|
||||
@@ -84,7 +97,7 @@ class StubServer {
|
||||
}
|
||||
|
||||
private void registerStubMappings() {
|
||||
WireMock wireMock = new WireMock("localhost", this.httpServerStub.port());
|
||||
WireMock wireMock = new WireMock("localhost", this.httpServerStub.port(), prependSlashIfNecessary(this.stubRunnerOptions.contextPath));
|
||||
registerDefaultHealthChecks(wireMock);
|
||||
registerStubs(this.mappings, wireMock);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.io.IOException;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.contract.stubrunner.AetherStubDownloader;
|
||||
import org.springframework.cloud.contract.stubrunner.BatchStubRunner;
|
||||
@@ -48,6 +49,8 @@ public class StubRunnerConfiguration {
|
||||
private StubDownloader stubDownloader;
|
||||
@Autowired
|
||||
private StubRunnerProperties props;
|
||||
@Autowired(required = false)
|
||||
private ServerProperties serverProperties;
|
||||
|
||||
/**
|
||||
* Bean that initializes stub runners, runs them and on shutdown closes them. Upon its
|
||||
@@ -63,7 +66,9 @@ public class StubRunnerConfiguration {
|
||||
.withWorkOffline(this.props.getRepositoryRoot() == null
|
||||
|| this.props.isWorkOffline())
|
||||
.withStubsClassifier(this.props.getClassifier())
|
||||
.withStubs(this.props.getIds()).build();
|
||||
.withStubs(this.props.getIds())
|
||||
.withContextPath(contextPath())
|
||||
.build();
|
||||
BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions,
|
||||
this.stubDownloader != null ? this.stubDownloader
|
||||
: new AetherStubDownloader(stubRunnerOptions),
|
||||
@@ -78,4 +83,11 @@ public class StubRunnerConfiguration {
|
||||
return stubRepositoryRoot != null ? stubRepositoryRoot.getURI().toString() : "";
|
||||
}
|
||||
|
||||
private String contextPath() {
|
||||
if (this.serverProperties == null) {
|
||||
return "";
|
||||
}
|
||||
return this.serverProperties.getContextPath();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class StubServerSpec extends Specification {
|
||||
def 'should register stub mappings upon server start'() {
|
||||
given:
|
||||
List<WiremockMappingDescriptor> mappingDescriptors = new StubRepository(repository).getProjectDescriptors()
|
||||
StubServer pingStubServer = new StubServer(stubConfiguration, mappingDescriptors, [],
|
||||
StubServer pingStubServer = new StubServer(new TestStubRunnerOptions(), stubConfiguration, mappingDescriptors, [],
|
||||
new WireMockHttpServerStub(STUB_SERVER_PORT))
|
||||
when:
|
||||
pingStubServer.start()
|
||||
@@ -40,7 +40,7 @@ class StubServerSpec extends Specification {
|
||||
def 'should provide stub server URL'() {
|
||||
given:
|
||||
List<WiremockMappingDescriptor> mappingDescriptors = new StubRepository(repository).getProjectDescriptors()
|
||||
StubServer pingStubServer = new StubServer(stubConfiguration, mappingDescriptors, [],
|
||||
StubServer pingStubServer = new StubServer(new TestStubRunnerOptions(), stubConfiguration, mappingDescriptors, [],
|
||||
new WireMockHttpServerStub(STUB_SERVER_PORT))
|
||||
when:
|
||||
pingStubServer.start()
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.springframework.cloud.contract.stubrunner
|
||||
|
||||
import groovy.transform.PackageScope
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@PackageScope class TestStubRunnerOptions extends StubRunnerOptions {
|
||||
public TestStubRunnerOptions() {
|
||||
super(1, 2, "", false, "", new ArrayList<StubConfiguration>(),
|
||||
new HashMap<StubConfiguration, Integer>());
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@
|
||||
<module>spring-cloud-contract-stub-runner-boot-eureka</module>
|
||||
<module>spring-cloud-contract-stub-runner-boot-zookeeper</module>
|
||||
<module>spring-cloud-contract-stub-runner-camel</module>
|
||||
<module>spring-cloud-contract-stub-runner-context-path</module>
|
||||
<module>spring-cloud-contract-stub-runner-integration</module>
|
||||
<module>spring-cloud-contract-stub-runner-stream</module>
|
||||
</modules>
|
||||
|
||||
45
tests/spring-cloud-contract-stub-runner-context-path/pom.xml
Normal file
45
tests/spring-cloud-contract-stub-runner-context-path/pom.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-tests</artifactId>
|
||||
<version>1.0.1.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-contract-stub-runner-context-path</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Contract Stub Runner With Context Path</name>
|
||||
<description>Spring Cloud Contract Stub Runner With Context Path</description>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.example.loan;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.example.loan;
|
||||
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.example.loan.model.FraudCheckStatus;
|
||||
import com.example.loan.model.FraudServiceRequest;
|
||||
import com.example.loan.model.FraudServiceResponse;
|
||||
import com.example.loan.model.LoanApplication;
|
||||
import com.example.loan.model.LoanApplicationResult;
|
||||
import com.example.loan.model.LoanApplicationStatus;
|
||||
|
||||
@Service
|
||||
public class LoanApplicationService {
|
||||
|
||||
private static final String FRAUD_SERVICE_JSON_VERSION_1 =
|
||||
"application/vnd.fraud.v1+json";
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
private String fraudUrl = "http://localhost:8080";
|
||||
|
||||
public LoanApplicationService() {
|
||||
this.restTemplate = new RestTemplate();
|
||||
}
|
||||
|
||||
public LoanApplicationResult loanApplication(LoanApplication loanApplication) {
|
||||
FraudServiceRequest request =
|
||||
new FraudServiceRequest(loanApplication);
|
||||
|
||||
FraudServiceResponse response =
|
||||
sendRequestToFraudDetectionService(request);
|
||||
|
||||
return buildResponseFromFraudResult(response);
|
||||
}
|
||||
|
||||
private FraudServiceResponse sendRequestToFraudDetectionService(
|
||||
FraudServiceRequest request) {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
httpHeaders.add(HttpHeaders.CONTENT_TYPE, FRAUD_SERVICE_JSON_VERSION_1);
|
||||
|
||||
// tag::client_call_server[]
|
||||
ResponseEntity<FraudServiceResponse> response =
|
||||
this.restTemplate.exchange(this.fraudUrl + "/fraudcheck", HttpMethod.PUT,
|
||||
new HttpEntity<>(request, httpHeaders),
|
||||
FraudServiceResponse.class);
|
||||
// end::client_call_server[]
|
||||
|
||||
return response.getBody();
|
||||
}
|
||||
|
||||
private LoanApplicationResult buildResponseFromFraudResult(FraudServiceResponse response) {
|
||||
LoanApplicationStatus applicationStatus = null;
|
||||
if (FraudCheckStatus.OK == response.getFraudCheckStatus()) {
|
||||
applicationStatus = LoanApplicationStatus.LOAN_APPLIED;
|
||||
} else if (FraudCheckStatus.FRAUD == response.getFraudCheckStatus()) {
|
||||
applicationStatus = LoanApplicationStatus.LOAN_APPLICATION_REJECTED;
|
||||
}
|
||||
|
||||
return new LoanApplicationResult(applicationStatus, response.getRejectionReason());
|
||||
}
|
||||
|
||||
public void setFraudUrl(String fraudUrl) {
|
||||
this.fraudUrl = fraudUrl;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public class Client {
|
||||
|
||||
private String clientId;
|
||||
|
||||
public Client() {
|
||||
}
|
||||
|
||||
public Client(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return this.clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public enum FraudCheckStatus {
|
||||
OK, FRAUD
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class FraudServiceRequest {
|
||||
|
||||
private String clientPesel;
|
||||
|
||||
private BigDecimal loanAmount;
|
||||
|
||||
public FraudServiceRequest() {
|
||||
}
|
||||
|
||||
public FraudServiceRequest(LoanApplication loanApplication) {
|
||||
this.clientPesel = loanApplication.getClient().getClientId();
|
||||
this.loanAmount = loanApplication.getAmount();
|
||||
}
|
||||
|
||||
public String getClientPesel() {
|
||||
return this.clientPesel;
|
||||
}
|
||||
|
||||
public void setClientPesel(String clientPesel) {
|
||||
this.clientPesel = clientPesel;
|
||||
}
|
||||
|
||||
public BigDecimal getLoanAmount() {
|
||||
return this.loanAmount;
|
||||
}
|
||||
|
||||
public void setLoanAmount(BigDecimal loanAmount) {
|
||||
this.loanAmount = loanAmount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public class FraudServiceResponse {
|
||||
|
||||
private FraudCheckStatus fraudCheckStatus;
|
||||
|
||||
private String rejectionReason;
|
||||
|
||||
public FraudServiceResponse() {
|
||||
}
|
||||
|
||||
public FraudCheckStatus getFraudCheckStatus() {
|
||||
return this.fraudCheckStatus;
|
||||
}
|
||||
|
||||
public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) {
|
||||
this.fraudCheckStatus = fraudCheckStatus;
|
||||
}
|
||||
|
||||
public String getRejectionReason() {
|
||||
return this.rejectionReason;
|
||||
}
|
||||
|
||||
public void setRejectionReason(String rejectionReason) {
|
||||
this.rejectionReason = rejectionReason;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class LoanApplication {
|
||||
|
||||
private Client client;
|
||||
|
||||
private BigDecimal amount;
|
||||
|
||||
private String loanApplicationId;
|
||||
|
||||
public LoanApplication() {
|
||||
}
|
||||
|
||||
public LoanApplication(Client client, double amount) {
|
||||
this.client = client;
|
||||
this.amount = BigDecimal.valueOf(amount);
|
||||
}
|
||||
|
||||
public Client getClient() {
|
||||
return this.client;
|
||||
}
|
||||
|
||||
public void setClient(Client client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public BigDecimal getAmount() {
|
||||
return this.amount;
|
||||
}
|
||||
|
||||
public void setAmount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getLoanApplicationId() {
|
||||
return this.loanApplicationId;
|
||||
}
|
||||
|
||||
public void setLoanApplicationId(String loanApplicationId) {
|
||||
this.loanApplicationId = loanApplicationId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public class LoanApplicationResult {
|
||||
|
||||
private LoanApplicationStatus loanApplicationStatus;
|
||||
|
||||
private String rejectionReason;
|
||||
|
||||
public LoanApplicationResult() {
|
||||
}
|
||||
|
||||
public LoanApplicationResult(LoanApplicationStatus loanApplicationStatus, String rejectionReason) {
|
||||
this.loanApplicationStatus = loanApplicationStatus;
|
||||
this.rejectionReason = rejectionReason;
|
||||
}
|
||||
|
||||
public LoanApplicationStatus getLoanApplicationStatus() {
|
||||
return this.loanApplicationStatus;
|
||||
}
|
||||
|
||||
public void setLoanApplicationStatus(LoanApplicationStatus loanApplicationStatus) {
|
||||
this.loanApplicationStatus = loanApplicationStatus;
|
||||
}
|
||||
|
||||
public String getRejectionReason() {
|
||||
return this.rejectionReason;
|
||||
}
|
||||
|
||||
public void setRejectionReason(String rejectionReason) {
|
||||
this.rejectionReason = rejectionReason;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.example.loan.model;
|
||||
|
||||
public enum LoanApplicationStatus {
|
||||
LOAN_APPLIED, LOAN_APPLICATION_REJECTED
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
server.port: 0
|
||||
server.context-path: /my-path
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.example.loan;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.contract.stubrunner.StubFinder;
|
||||
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.example.loan.model.Client;
|
||||
import com.example.loan.model.LoanApplication;
|
||||
import com.example.loan.model.LoanApplicationResult;
|
||||
import com.example.loan.model.LoanApplicationStatus;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
// tag::autoconfigure_stubrunner[]
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@AutoConfigureStubRunner(repositoryRoot = "classpath:m2repo/repository/",
|
||||
ids = { "org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer" })
|
||||
public class LoanApplicationServiceTests {
|
||||
// end::autoconfigure_stubrunner[]
|
||||
|
||||
@Autowired private LoanApplicationService service;
|
||||
@Autowired private StubFinder stubFinder;
|
||||
|
||||
@Before
|
||||
public void setPort() {
|
||||
this.service.setFraudUrl(this.stubFinder.findStubUrl("fraudDetectionServer").toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSuccessfullyApplyForLoan() {
|
||||
// given:
|
||||
LoanApplication application = new LoanApplication(new Client("1234567890"),
|
||||
123.123);
|
||||
// when:
|
||||
LoanApplicationResult loanApplication = service.loanApplication(application);
|
||||
// then:
|
||||
assertThat(loanApplication.getLoanApplicationStatus())
|
||||
.isEqualTo(LoanApplicationStatus.LOAN_APPLIED);
|
||||
assertThat(loanApplication.getRejectionReason()).isNull();
|
||||
}
|
||||
|
||||
// tag::client_tdd[]
|
||||
@Test
|
||||
public void shouldBeRejectedDueToAbnormalLoanAmount() {
|
||||
// given:
|
||||
LoanApplication application = new LoanApplication(new Client("1234567890"),
|
||||
99999);
|
||||
// when:
|
||||
LoanApplicationResult loanApplication = service.loanApplication(application);
|
||||
// then:
|
||||
assertThat(loanApplication.getLoanApplicationStatus())
|
||||
.isEqualTo(LoanApplicationStatus.LOAN_APPLICATION_REJECTED);
|
||||
assertThat(loanApplication.getRejectionReason()).isEqualTo("Amount too high");
|
||||
}
|
||||
// end::client_tdd[]
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2016 the original author or authors.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.cloud.contract.verifier.stubs</groupId>
|
||||
<artifactId>fraudDetectionServer</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
</project>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2013-2016 the original author or authors.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<metadata>
|
||||
<groupId>org.springframework.cloud.contract.verifier.stubs</groupId>
|
||||
<artifactId>fraudDetectionServer</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<versioning>
|
||||
<versions>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</versions>
|
||||
<lastUpdated>20160409062112</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
||||
Reference in New Issue
Block a user