added json upload and response headers

This commit is contained in:
Sander Hautvast 2015-06-11 16:33:34 +02:00
parent 506bea5d0e
commit 1407b21b4d
20 changed files with 346 additions and 94 deletions

View file

@ -3,13 +3,12 @@
Simple universal mocking tool for http requests Simple universal mocking tool for http requests
- requires java 8 - requires java 8
- set up expectations using json files in $PROJECT/everest_data directory - set up expectations using json files in $PROJECT/everest_data directory
-- or start java with -Deverest.data=[..] for a different data directory - or start java with -Deverest.data=[..] for a different data directory
- start using gradlew run - start using gradlew run
- replay - replay
<h3>Sample json</h3> <h3>Sample json</h3>
{<br/> {<br/>
"id": "91f83cd9-a0a5-49f5-b740-78ba8f504797",<br/>
"name": "wehkamp.nl",<br/> "name": "wehkamp.nl",<br/>
"url": "http://www.wehkamp.nl",<br/> "url": "http://www.wehkamp.nl",<br/>
"method": "GET",<br/> "method": "GET",<br/>
@ -18,10 +17,17 @@ Simple universal mocking tool for http requests
&nbsp;&nbsp;},<br/> &nbsp;&nbsp;},<br/>
"response": "<html>",<br/> "response": "<html>",<br/>
"responseStatus": 200<br/> "responseStatus": 200<br/>
"responseHeaders": <br/>
&nbsp;&nbsp;"Accept": ["application/json"]<br/>
&nbsp;&nbsp;},<br/>
}<br/> }<br/>
- url can be java regex expression - url can be java regex expression
- json files are reloaded on the fly
<h4>api for json upload</h4>
- the JSON above can be uploaded to a running server using a POST to http://[server]:[port]/__api/upload
- use Content-Type=application/json
<h3>TODO's</h3> <h3>TODO's</h3>
- implement response headers - build a proxy that generates the json from actual requests/responses
- build a proxy that generates json

View file

@ -35,6 +35,7 @@ dependencies{
compile 'org.springframework.boot:spring-boot-starter-web' compile 'org.springframework.boot:spring-boot-starter-web'
compile 'commons-io:commons-io:2.0.1' compile 'commons-io:commons-io:2.0.1'
compile 'com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.2.1' compile 'com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.2.1'
// compile 'org.littleshoot:littleproxy:1.0.0-beta7'
testCompile 'org.testng:testng:6.8' testCompile 'org.testng:testng:6.8'
testCompile "org.springframework:spring-test:4.0.6.RELEASE" testCompile "org.springframework:spring-test:4.0.6.RELEASE"

View file

@ -2,7 +2,7 @@ package nl.wehkamp.everest;
import javax.servlet.Servlet; import javax.servlet.Servlet;
import nl.wehkamp.everest.web.MockingServlet; import nl.wehkamp.everest.web.PredictableResponseServlet;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
@ -30,12 +30,12 @@ public class WebServer implements ApplicationContextAware {
@Bean @Bean
public ServletRegistrationBean servletRegistrationBean() { public ServletRegistrationBean servletRegistrationBean() {
return new ServletRegistrationBean(mockingServlet(), "/*"); return new ServletRegistrationBean(predictableResponseServlet(), "/*");
} }
@Bean @Bean
public Servlet mockingServlet() { public Servlet predictableResponseServlet() {
return new MockingServlet(); return new PredictableResponseServlet();
} }
public static void main(String[] args) { public static void main(String[] args) {

View file

@ -32,15 +32,15 @@ import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@Component("requestResponseRepository") @Component
public class RequestResponseJsonFileRepository extends RequestResponseMemoryRepository { public class PredictionJsonFileRepository extends PredictionMemoryRepository {
private static final Logger log = LoggerFactory.getLogger(RequestResponseJsonFileRepository.class); private static final Logger log = LoggerFactory.getLogger(PredictionJsonFileRepository.class);
private String dataDirectoryName = System.getProperty("everest.data", "everest_data"); private String dataDirectoryName = System.getProperty("everest.data", "everest_data");
private ObjectMapper jackson = new ObjectMapper(); private ObjectMapper jackson = new ObjectMapper();
public RequestResponseJsonFileRepository() { public PredictionJsonFileRepository() {
createDataDirectoryIfAbsent(); createDataDirectoryIfAbsent();
fillCacheIfEmpty(); fillCacheIfEmpty();
} }
@ -55,7 +55,9 @@ public class RequestResponseJsonFileRepository extends RequestResponseMemoryRepo
throw new RuntimeException(e); throw new RuntimeException(e);
} finally { } finally {
try { try {
if (os != null) {
os.close(); os.close();
}
} catch (IOException e) { } catch (IOException e) {
} }
} }

View file

@ -1,14 +1,15 @@
package nl.wehkamp.everest.dao; package nl.wehkamp.everest.dao;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import nl.wehkamp.everest.model.Prediction; import nl.wehkamp.everest.model.Prediction;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@Repository("requestResponseMemoryRepository") @Repository
public class RequestResponseMemoryRepository implements RequestResponseRepository { public class PredictionMemoryRepository implements PredictionRepository {
protected Set<Prediction> cache = new HashSet<>(); protected Set<Prediction> cache = new HashSet<>();
@Override @Override
@ -24,4 +25,13 @@ public class RequestResponseMemoryRepository implements RequestResponseRepositor
public void clear() { public void clear() {
cache.clear(); cache.clear();
} }
public Optional<Prediction> findByName(String name) {
for (Prediction p : cache) {
if (p.getName().equals(name)) {
return Optional.of(p);
}
}
return Optional.empty();
}
} }

View file

@ -4,9 +4,9 @@ import java.util.Set;
import nl.wehkamp.everest.model.Prediction; import nl.wehkamp.everest.model.Prediction;
public interface RequestResponseRepository { public interface PredictionRepository {
void save(Prediction record); void save(Prediction prediction);
Set<Prediction> findAll(); Set<Prediction> findAll();

View file

@ -5,6 +5,7 @@ import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -34,6 +35,10 @@ public class Headers {
} }
} }
public Set<String> getHeaderNames() {
return headers.keySet();
}
/** /**
* returns all header values for a given name. Or null if none set * returns all header values for a given name. Or null if none set
*/ */

View file

@ -1,7 +1,10 @@
package nl.wehkamp.everest.model; package nl.wehkamp.everest.model;
import static java.util.Optional.empty;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import nl.wehkamp.everest.util.Uuids; import nl.wehkamp.everest.util.Uuids;
@ -18,6 +21,7 @@ public class Prediction {
private String response; private String response;
private int responseStatus; private int responseStatus;
private Optional<Headers> responseHeaders = empty();
public boolean requestMatches(String requesturl) { public boolean requestMatches(String requesturl) {
return urlPattern.matcher(requesturl).matches(); return urlPattern.matcher(requesturl).matches();
@ -28,13 +32,14 @@ public class Prediction {
} }
private Prediction(Dto predictionDto) { private Prediction(Dto predictionDto) {
this.id = predictionDto.id; this.id = predictionDto.id != null ? predictionDto.id : Uuids.create();
this.name = predictionDto.name; this.name = predictionDto.name;
setUrl(predictionDto.url); setUrl(predictionDto.url);
this.method = predictionDto.method; this.method = predictionDto.method;
this.requestHeaders = new Headers(predictionDto.requestHeaders); this.requestHeaders = new Headers(predictionDto.requestHeaders);
this.response = predictionDto.response; this.response = predictionDto.response;
this.responseStatus = predictionDto.responseStatus; this.responseStatus = predictionDto.responseStatus;
this.responseHeaders = predictionDto.getResponseHeaders() != null ? Optional.of(new Headers(predictionDto.getResponseHeaders())) : empty();
} }
public String getMethod() { public String getMethod() {
@ -89,6 +94,18 @@ public class Prediction {
this.responseStatus = responseStatus; this.responseStatus = responseStatus;
} }
public boolean hasReponseHeaders() {
return responseHeaders.isPresent();
}
public Headers getResponseHeaders() {
return responseHeaders.get();
}
public void setResponseHeaders(Headers responseHeaders) {
this.responseHeaders = Optional.ofNullable(responseHeaders);
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
@ -114,7 +131,7 @@ public class Prediction {
return true; return true;
} }
public boolean containsHeaders() { public boolean containsRequestHeaders() {
return requestHeaders != null && requestHeaders.areSet(); return requestHeaders != null && requestHeaders.areSet();
} }
@ -124,7 +141,8 @@ public class Prediction {
} }
public Dto toDto() { public Dto toDto() {
return new Dto(id, name, url, method, requestHeaders.getContent(), response, responseStatus); Map<String, List<String>> responseHeaderMap = hasReponseHeaders() ? getResponseHeaders().getContent() : null;
return new Dto(id, name, url, method, requestHeaders.getContent(), response, responseStatus, responseHeaderMap);
} }
public static Prediction fromDto(Dto predictionDto) { public static Prediction fromDto(Dto predictionDto) {
@ -141,11 +159,13 @@ public class Prediction {
private String response; private String response;
private int responseStatus; private int responseStatus;
private Map<String, List<String>> responseHeaders;
public Dto() { public Dto() {
} }
private Dto(String id, String name, String url, String method, Map<String, List<String>> requestHeaders, String response, int responseStatus) { private Dto(String id, String name, String url, String method, Map<String, List<String>> requestHeaders, String response, int responseStatus,
Map<String, List<String>> responseHeaders) {
super(); super();
this.id = id; this.id = id;
this.name = name; this.name = name;
@ -154,6 +174,7 @@ public class Prediction {
this.requestHeaders = requestHeaders; this.requestHeaders = requestHeaders;
this.response = response; this.response = response;
this.responseStatus = responseStatus; this.responseStatus = responseStatus;
this.responseHeaders = responseHeaders;
} }
public String getId() { public String getId() {
@ -212,6 +233,14 @@ public class Prediction {
this.responseStatus = responseStatus; this.responseStatus = responseStatus;
} }
public Map<String, List<String>> getResponseHeaders() {
return responseHeaders;
}
public void setResponseHeaders(Map<String, List<String>> responseHeaders) {
this.responseHeaders = responseHeaders;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;

View file

@ -0,0 +1,29 @@
//package nl.wehkamp.everest.proxy;
//
//import io.netty.channel.ChannelHandlerContext;
//import io.netty.handler.codec.http.HttpRequest;
//
//import org.littleshoot.proxy.HttpFilters;
//import org.littleshoot.proxy.HttpFiltersAdapter;
//import org.littleshoot.proxy.HttpFiltersSourceAdapter;
//import org.littleshoot.proxy.HttpProxyServer;
//import org.littleshoot.proxy.impl.DefaultHttpProxyServer;
//
//public class Proxy {
// private int port = 8080;
// private HttpProxyServer server;
//
// public void start() {
// server = DefaultHttpProxyServer.bootstrap().withPort(port).withFiltersSource(new HttpFiltersSourceAdapter() {
// public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) {
// return new HttpFiltersAdapter(originalRequest) {
//
// };
// }
// }).start();
// }
//
// public void setPort(int port) {
// this.port = port;
// }
// }

View file

@ -0,0 +1,17 @@
package nl.wehkamp.everest.service;
import static nl.wehkamp.everest.model.Prediction.fromDto;
import java.io.IOException;
import nl.wehkamp.everest.model.Prediction;
import com.fasterxml.jackson.databind.ObjectMapper;
public class PredictionFactory {
private static ObjectMapper objectMapper = new ObjectMapper();
public static Prediction newPrediction(String json) throws IOException {
return fromDto(objectMapper.readValue(json, Prediction.Dto.class));
}
}

View file

@ -13,7 +13,7 @@ import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import nl.wehkamp.everest.dao.RequestResponseRepository; import nl.wehkamp.everest.dao.PredictionRepository;
import nl.wehkamp.everest.model.Prediction; import nl.wehkamp.everest.model.Prediction;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -25,31 +25,31 @@ import org.springframework.stereotype.Service;
@Service @Service
public class ResponseFinder { public class ResponseFinder {
@Autowired @Autowired
private RequestResponseRepository requestResponseRepository; private PredictionRepository predictionJsonFileRepository;
public Optional<Prediction> find(HttpServletRequest request) { public Optional<Prediction> find(HttpServletRequest request) {
Optional<Prediction> response = Optional.empty(); Optional<Prediction> response = Optional.empty();
Set<Prediction> all = requestResponseRepository.findAll(); Set<Prediction> all = predictionJsonFileRepository.findAll();
for (Prediction prediction : all) { for (Prediction prediction : all) {
response = matchUrlAndMethodAndHeaders(request, response, prediction); response = matchUrlAndMethodAndHeaders(request, response, prediction);
} }
return response; return response;
} }
private Optional<Prediction> matchUrlAndMethodAndHeaders(HttpServletRequest request, Optional<Prediction> response, Prediction rr) { private Optional<Prediction> matchUrlAndMethodAndHeaders(HttpServletRequest request, Optional<Prediction> response, Prediction prediction) {
if (rr.requestMatches(request.getPathInfo())) { if (prediction.requestMatches(request.getPathInfo())) {
response = matchMethodAndHeaders(request, response, rr); response = matchMethodAndHeaders(request, response, prediction);
} }
return response; return response;
} }
private Optional<Prediction> matchMethodAndHeaders(HttpServletRequest request, Optional<Prediction> response, Prediction rr) { private Optional<Prediction> matchMethodAndHeaders(HttpServletRequest request, Optional<Prediction> response, Prediction prediction) {
if (rr.getMethod().equals(request.getMethod())) { if (prediction.getMethod().equals(request.getMethod())) {
if (rr.containsHeaders()) { if (prediction.containsRequestHeaders()) {
response = matchHeaders(request, response, rr); response = matchHeaders(request, response, prediction);
} else { } else {
response = Optional.of(rr); response = Optional.of(prediction);
} }
} }
return response; return response;
@ -62,7 +62,7 @@ public class ResponseFinder {
return response; return response;
} }
public void setRequestResponseRepository(RequestResponseRepository requestResponseRepository) { public void setPredictionRepository(PredictionRepository predictionJsonFileRepository) {
this.requestResponseRepository = requestResponseRepository; this.predictionJsonFileRepository = predictionJsonFileRepository;
} }
} }

View file

@ -1,40 +0,0 @@
package nl.wehkamp.everest.web;
import java.io.IOException;
import java.util.Optional;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nl.wehkamp.everest.model.Prediction;
import nl.wehkamp.everest.service.ResponseFinder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.DispatcherServlet;
/**
* Mocks http requests
*
*/
@SuppressWarnings("serial")
@Controller
public class MockingServlet extends DispatcherServlet {
@Autowired
private ResponseFinder responseFinder;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Optional<Prediction> someRequestResponse = responseFinder.find(req);
if (someRequestResponse.isPresent()) {
Prediction requestResponse = someRequestResponse.get();
resp.getWriter().print(requestResponse.getResponse());
resp.setStatus(requestResponse.getResponseStatus());
} else {
resp.getWriter().print("Not found");
resp.setStatus(404);
}
}
}

View file

@ -0,0 +1,106 @@
package nl.wehkamp.everest.web;
import static nl.wehkamp.everest.service.PredictionFactory.newPrediction;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Optional;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nl.wehkamp.everest.dao.PredictionRepository;
import nl.wehkamp.everest.model.Prediction;
import nl.wehkamp.everest.service.ResponseFinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.DispatcherServlet;
/**
* Mocks http requests using prefabricated predictions
*
*/
@SuppressWarnings("serial")
@Controller
public class PredictableResponseServlet extends DispatcherServlet {
private final static Logger log = LoggerFactory.getLogger(PredictableResponseServlet.class);
@Autowired
private ResponseFinder responseFinder;
@Autowired
private PredictionRepository predictionJsonFileRepository;
@Override
protected void service(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws ServletException, IOException {
if (isUploadRequest(httpRequest)) {
handleUpload(httpRequest, httpResponse);
} else {
handleMockRequest(httpRequest, httpResponse);
}
}
private void handleMockRequest(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException {
Optional<Prediction> someRequestResponse = responseFinder.find(httpRequest);
if (someRequestResponse.isPresent()) {
Prediction prediction = someRequestResponse.get();
setPredictedResponseValues(httpResponse, prediction);
} else {
httpResponse.getWriter().print("Not found");
httpResponse.setStatus(404);
}
}
private void setPredictedResponseValues(HttpServletResponse httpResponse, Prediction prediction) throws IOException {
httpResponse.getWriter().print(prediction.getResponse());
httpResponse.setStatus(prediction.getResponseStatus());
if (prediction.hasReponseHeaders()) {
setPredictedResponseHeaders(httpResponse, prediction);
}
}
private void setPredictedResponseHeaders(HttpServletResponse httpResponse, Prediction prediction) {
for (String headername : prediction.getResponseHeaders().getHeaderNames()) {
for (String headervalue : prediction.getResponseHeaders().getAll(headername)) {
httpResponse.addHeader(headername, headervalue);
}
}
}
private void handleUpload(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException {
try {
predictionJsonFileRepository.save(newPrediction(readJsonFromHttpBody(httpRequest)));
httpResponse.setStatus(201);
} catch (IOException e) {
httpResponse.setStatus(500);
httpResponse.getWriter().print(e.getClass().getName() + ":" + e.getMessage());
}
}
private String readJsonFromHttpBody(HttpServletRequest httprequest) throws IOException {
BufferedReader reader = httprequest.getReader();
String line;
StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {
builder.append(line);
}
String json = builder.toString();
log.info("upload of json {}", json);
return json;
}
private boolean isUploadRequest(HttpServletRequest req) {
return req.getMethod().equals("POST") && req.getPathInfo().startsWith("/__api/upload") && req.getHeader("Content-Type").equals("application/json");
}
public void setPredictionRepository(PredictionRepository predictionJsonFileRepository) {
this.predictionJsonFileRepository = predictionJsonFileRepository;
}
}

View file

@ -11,6 +11,7 @@ import java.util.List;
import nl.wehkamp.everest.model.Headers; import nl.wehkamp.everest.model.Headers;
import nl.wehkamp.everest.model.Prediction; import nl.wehkamp.everest.model.Prediction;
import nl.wehkamp.everest.util.FileLoader;
import nl.wehkamp.everest.util.Uuids; import nl.wehkamp.everest.util.Uuids;
import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterMethod;
@ -37,15 +38,13 @@ public class RecordRepositoryTest {
record.setHeaders(headers); record.setHeaders(headers);
record.setResponseStatus(200); record.setResponseStatus(200);
record.setResponse("<html>"); record.setResponse("<html>");
new RequestResponseJsonFileRepository().save(record); new PredictionJsonFileRepository().save(record);
List<String> lines = Files.readAllLines(Paths.get("everest_data", "wehkamp.nl.json"), StandardCharsets.UTF_8); List<String> lines = Files.readAllLines(Paths.get("everest_data", "wehkamp.nl.json"), StandardCharsets.UTF_8);
assertFalse(lines.isEmpty()); assertFalse(lines.isEmpty());
System.out.println(lines.get(0)); System.out.println(lines.get(0));
assertEquals( assertEquals(lines.get(0), FileLoader.load("test.json"));
lines.get(0),
"{\"id\":\"91f83cd9-a0a5-49f5-b740-78ba8f504797\",\"name\":\"wehkamp.nl\",\"url\":\"http://www.wehkamp.nl\",\"method\":\"GET\",\"requestHeaders\":{\"Accept\":[\"application/json\"]},\"response\":\"<html>\",\"responseStatus\":200}");
} }
} }

View file

@ -0,0 +1,16 @@
package nl.wehkamp.everest.util;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.ClassPathResource;
public class FileLoader {
public static String load(String resource) {
try {
return IOUtils.toString(new ClassPathResource(resource).getInputStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View file

@ -1,21 +1,24 @@
package nl.wehkamp.everest.web; package nl.wehkamp.everest.util;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map; import java.util.Map;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.HttpClients;
public class TestClient { public class TestClient {
private static HttpClient httpclient = HttpClients.createDefault(); private static HttpClient httpclient = HttpClients.createDefault();
private static HttpHost target = new HttpHost("localhost", 8080, "http"); private static HttpHost target = new HttpHost("localhost", 8080, "http");
public static String get(String url) { public static String httpGet(String url) {
try { try {
HttpGet httpGet = new HttpGet(url); HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpclient.execute(target, httpGet); HttpResponse httpResponse = httpclient.execute(target, httpGet);
@ -26,7 +29,7 @@ public class TestClient {
} }
} }
public static String get(String url, Map<String, String> headers) { public static String httpGet(String url, Map<String, String> headers) {
HttpGet httpGet = new HttpGet(url); HttpGet httpGet = new HttpGet(url);
for (Map.Entry<String, String> header : headers.entrySet()) { for (Map.Entry<String, String> header : headers.entrySet()) {
httpGet.addHeader(header.getKey(), header.getValue()); httpGet.addHeader(header.getKey(), header.getValue());
@ -40,9 +43,21 @@ public class TestClient {
} }
} }
public static String post(String url, String postBody) { public static String httpPost(String url, String postBody) {
try { try {
HttpPost httpPost = new HttpPost(url); HttpPost httpPost = createPost(url, postBody, null);
HttpResponse httpResponse = httpclient.execute(target, httpPost);
String responseBody = IOUtils.toString(httpResponse.getEntity().getContent());
return httpResponse.getStatusLine().getStatusCode() + ":" + responseBody;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String httpPost(String url, String postBody, Map<String, String> headers) {
try {
HttpPost httpPost = createPost(url, postBody, headers);
HttpResponse httpResponse = httpclient.execute(target, httpPost); HttpResponse httpResponse = httpclient.execute(target, httpPost);
String body = IOUtils.toString(httpResponse.getEntity().getContent()); String body = IOUtils.toString(httpResponse.getEntity().getContent());
return httpResponse.getStatusLine().getStatusCode() + ":" + body; return httpResponse.getStatusLine().getStatusCode() + ":" + body;
@ -50,4 +65,17 @@ public class TestClient {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
private static HttpPost createPost(String url, String postBody, Map<String, String> headers) throws UnsupportedEncodingException {
HttpPost httpPost = new HttpPost(url);
HttpEntity entity = new ByteArrayEntity(postBody.getBytes("UTF-8"));
httpPost.setEntity(entity);
if (headers != null) {
for (Map.Entry<String, String> header : headers.entrySet()) {
httpPost.addHeader(header.getKey(), header.getValue());
}
}
return httpPost;
}
} }

View file

@ -1,11 +1,11 @@
package nl.wehkamp.everest.web; package nl.wehkamp.everest.web;
import static java.util.Collections.singletonMap; import static java.util.Collections.singletonMap;
import static nl.wehkamp.everest.web.TestClient.get; import static nl.wehkamp.everest.util.TestClient.httpGet;
import static nl.wehkamp.everest.web.TestClient.post; import static nl.wehkamp.everest.util.TestClient.httpPost;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import nl.wehkamp.everest.WebServer; import nl.wehkamp.everest.WebServer;
import nl.wehkamp.everest.dao.RequestResponseMemoryRepository; import nl.wehkamp.everest.dao.PredictionMemoryRepository;
import nl.wehkamp.everest.model.Prediction; import nl.wehkamp.everest.model.Prediction;
import nl.wehkamp.everest.service.ResponseFinder; import nl.wehkamp.everest.service.ResponseFinder;
@ -18,14 +18,14 @@ import org.testng.annotations.Test;
*/ */
public class MockingServletTests { public class MockingServletTests {
private RequestResponseMemoryRepository requestResponseRepository; private PredictionMemoryRepository requestResponseRepository;
@BeforeSuite @BeforeSuite
public void setup() { public void setup() {
WebServer.start(); WebServer.start();
ResponseFinder responseFinder = WebServer.instance.getBean(ResponseFinder.class); ResponseFinder responseFinder = WebServer.instance.getBean(ResponseFinder.class);
requestResponseRepository = new RequestResponseMemoryRepository(); requestResponseRepository = new PredictionMemoryRepository();
responseFinder.setRequestResponseRepository(requestResponseRepository); responseFinder.setPredictionRepository(requestResponseRepository);
} }
@AfterMethod @AfterMethod
@ -41,7 +41,7 @@ public class MockingServletTests {
record.setResponse("get successful"); record.setResponse("get successful");
record.setResponseStatus(200); record.setResponseStatus(200);
requestResponseRepository.save(record); requestResponseRepository.save(record);
assertEquals(get("/testget"), "200:get successful"); assertEquals(httpGet("/testget"), "200:get successful");
} }
@Test @Test
@ -53,7 +53,7 @@ public class MockingServletTests {
record.setResponse("getWithHeader successful"); record.setResponse("getWithHeader successful");
record.setResponseStatus(200); record.setResponseStatus(200);
requestResponseRepository.save(record); requestResponseRepository.save(record);
assertEquals(get("/testget", singletonMap("Content-Type", "application/json")), "200:getWithHeader successful"); assertEquals(httpGet("/testget", singletonMap("Content-Type", "application/json")), "200:getWithHeader successful");
} }
@Test @Test
@ -65,7 +65,7 @@ public class MockingServletTests {
record.setResponse("getWithHeader successful"); record.setResponse("getWithHeader successful");
record.setResponseStatus(200); record.setResponseStatus(200);
requestResponseRepository.save(record); requestResponseRepository.save(record);
assertEquals(get("/testget", singletonMap("Content-Type", "application/json")), "404:Not found"); assertEquals(httpGet("/testget", singletonMap("Content-Type", "application/json")), "404:Not found");
} }
@Test @Test
@ -76,7 +76,7 @@ public class MockingServletTests {
record.setResponse("get wildcard successful"); record.setResponse("get wildcard successful");
record.setResponseStatus(200); record.setResponseStatus(200);
requestResponseRepository.save(record); requestResponseRepository.save(record);
assertEquals(get("/testget/foo"), "200:get wildcard successful"); assertEquals(httpGet("/testget/foo"), "200:get wildcard successful");
} }
@Test @Test
@ -87,6 +87,6 @@ public class MockingServletTests {
record.setResponse("post successful"); record.setResponse("post successful");
record.setResponseStatus(200); record.setResponseStatus(200);
requestResponseRepository.save(record); requestResponseRepository.save(record);
assertEquals(post("/testpost", "body"), "200:post successful"); assertEquals(httpPost("/testpost", "body"), "200:post successful");
} }
} }

View file

@ -0,0 +1,42 @@
package nl.wehkamp.everest.web;
import static java.util.Collections.singletonMap;
import static nl.wehkamp.everest.util.FileLoader.load;
import static nl.wehkamp.everest.util.TestClient.httpPost;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Optional;
import nl.wehkamp.everest.WebServer;
import nl.wehkamp.everest.dao.PredictionMemoryRepository;
import nl.wehkamp.everest.model.Prediction;
import nl.wehkamp.everest.service.ResponseFinder;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
public class UploadTests {
private PredictionMemoryRepository predictionMemoryRepository;
@BeforeSuite
public void setup() {
WebServer.start();
ResponseFinder responseFinder = WebServer.instance.getBean(ResponseFinder.class);
predictionMemoryRepository = new PredictionMemoryRepository();
responseFinder.setPredictionRepository(predictionMemoryRepository);
PredictableResponseServlet servlet = WebServer.instance.getBean(PredictableResponseServlet.class);
servlet.setPredictionRepository(predictionMemoryRepository);
predictionMemoryRepository.clear();
}
@Test
public void test() {
httpPost("/__api/upload", load("uploadtest.json"), singletonMap("Content-Type", "application/json"));
Optional<Prediction> prediction = predictionMemoryRepository.findByName("test.nl");
assertTrue(prediction.isPresent());
assertEquals(prediction.get().getUrl(), "/entry");
}
}

View file

@ -0,0 +1 @@
{"id":"91f83cd9-a0a5-49f5-b740-78ba8f504797","name":"wehkamp.nl","url":"http://www.wehkamp.nl","method":"GET","requestHeaders":{"Accept":["application/json"]},"response":"<html>","responseStatus":200,"responseHeaders":null}

View file

@ -0,0 +1 @@
{"id":"1","name":"test.nl","url":"/entry","method":"GET","requestHeaders":{"Accept":["application/json"]},"response":"<html>","responseStatus":200,"responseHeaders":null}