From 1407b21b4df5ad4087a4be3f5d1b6a0a4276ed31 Mon Sep 17 00:00:00 2001 From: Sander Hautvast Date: Thu, 11 Jun 2015 16:33:34 +0200 Subject: [PATCH] added json upload and response headers --- README.md | 14 ++- build.gradle | 1 + .../java/nl/wehkamp/everest/WebServer.java | 8 +- ...java => PredictionJsonFileRepository.java} | 12 +- ...y.java => PredictionMemoryRepository.java} | 14 ++- ...ository.java => PredictionRepository.java} | 4 +- .../nl/wehkamp/everest/model/Headers.java | 5 + .../nl/wehkamp/everest/model/Prediction.java | 37 +++++- .../java/nl/wehkamp/everest/proxy/Proxy.java | 29 +++++ .../everest/service/PredictionFactory.java | 17 +++ .../everest/service/ResponseFinder.java | 26 ++--- .../wehkamp/everest/web/MockingServlet.java | 40 ------- .../web/PredictableResponseServlet.java | 106 ++++++++++++++++++ .../everest/dao/RecordRepositoryTest.java | 7 +- .../nl/wehkamp/everest/util/FileLoader.java | 16 +++ .../everest/{web => util}/TestClient.java | 38 ++++++- .../everest/web/MockingServletTests.java | 22 ++-- .../nl/wehkamp/everest/web/UploadTests.java | 42 +++++++ src/test/resources/test.json | 1 + src/test/resources/uploadtest.json | 1 + 20 files changed, 346 insertions(+), 94 deletions(-) rename src/main/java/nl/wehkamp/everest/dao/{RequestResponseJsonFileRepository.java => PredictionJsonFileRepository.java} (91%) rename src/main/java/nl/wehkamp/everest/dao/{RequestResponseMemoryRepository.java => PredictionMemoryRepository.java} (58%) rename src/main/java/nl/wehkamp/everest/dao/{RequestResponseRepository.java => PredictionRepository.java} (66%) create mode 100644 src/main/java/nl/wehkamp/everest/proxy/Proxy.java create mode 100644 src/main/java/nl/wehkamp/everest/service/PredictionFactory.java delete mode 100644 src/main/java/nl/wehkamp/everest/web/MockingServlet.java create mode 100644 src/main/java/nl/wehkamp/everest/web/PredictableResponseServlet.java create mode 100644 src/test/java/nl/wehkamp/everest/util/FileLoader.java rename src/test/java/nl/wehkamp/everest/{web => util}/TestClient.java (54%) create mode 100644 src/test/java/nl/wehkamp/everest/web/UploadTests.java create mode 100644 src/test/resources/test.json create mode 100644 src/test/resources/uploadtest.json diff --git a/README.md b/README.md index 970eaa0..e4b7e89 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,12 @@ Simple universal mocking tool for http requests - requires java 8 - 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 - replay

Sample json

{
-"id": "91f83cd9-a0a5-49f5-b740-78ba8f504797",
"name": "wehkamp.nl",
"url": "http://www.wehkamp.nl",
"method": "GET",
@@ -18,10 +17,17 @@ Simple universal mocking tool for http requests   },
"response": "",
"responseStatus": 200
+"responseHeaders":
+  "Accept": ["application/json"]
+  },
}
- url can be java regex expression +- json files are reloaded on the fly + +

api for json upload

+- the JSON above can be uploaded to a running server using a POST to http://[server]:[port]/__api/upload +- use Content-Type=application/json

TODO's

-- implement response headers -- build a proxy that generates json +- build a proxy that generates the json from actual requests/responses diff --git a/build.gradle b/build.gradle index 07506ef..c278aa5 100644 --- a/build.gradle +++ b/build.gradle @@ -35,6 +35,7 @@ dependencies{ compile 'org.springframework.boot:spring-boot-starter-web' compile 'commons-io:commons-io:2.0.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.springframework:spring-test:4.0.6.RELEASE" diff --git a/src/main/java/nl/wehkamp/everest/WebServer.java b/src/main/java/nl/wehkamp/everest/WebServer.java index 0698779..75e725f 100644 --- a/src/main/java/nl/wehkamp/everest/WebServer.java +++ b/src/main/java/nl/wehkamp/everest/WebServer.java @@ -2,7 +2,7 @@ package nl.wehkamp.everest; import javax.servlet.Servlet; -import nl.wehkamp.everest.web.MockingServlet; +import nl.wehkamp.everest.web.PredictableResponseServlet; import org.springframework.beans.BeansException; import org.springframework.boot.SpringApplication; @@ -30,12 +30,12 @@ public class WebServer implements ApplicationContextAware { @Bean public ServletRegistrationBean servletRegistrationBean() { - return new ServletRegistrationBean(mockingServlet(), "/*"); + return new ServletRegistrationBean(predictableResponseServlet(), "/*"); } @Bean - public Servlet mockingServlet() { - return new MockingServlet(); + public Servlet predictableResponseServlet() { + return new PredictableResponseServlet(); } public static void main(String[] args) { diff --git a/src/main/java/nl/wehkamp/everest/dao/RequestResponseJsonFileRepository.java b/src/main/java/nl/wehkamp/everest/dao/PredictionJsonFileRepository.java similarity index 91% rename from src/main/java/nl/wehkamp/everest/dao/RequestResponseJsonFileRepository.java rename to src/main/java/nl/wehkamp/everest/dao/PredictionJsonFileRepository.java index fbb0ab1..646a8e5 100644 --- a/src/main/java/nl/wehkamp/everest/dao/RequestResponseJsonFileRepository.java +++ b/src/main/java/nl/wehkamp/everest/dao/PredictionJsonFileRepository.java @@ -32,15 +32,15 @@ import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; -@Component("requestResponseRepository") -public class RequestResponseJsonFileRepository extends RequestResponseMemoryRepository { - private static final Logger log = LoggerFactory.getLogger(RequestResponseJsonFileRepository.class); +@Component +public class PredictionJsonFileRepository extends PredictionMemoryRepository { + private static final Logger log = LoggerFactory.getLogger(PredictionJsonFileRepository.class); private String dataDirectoryName = System.getProperty("everest.data", "everest_data"); private ObjectMapper jackson = new ObjectMapper(); - public RequestResponseJsonFileRepository() { + public PredictionJsonFileRepository() { createDataDirectoryIfAbsent(); fillCacheIfEmpty(); } @@ -55,7 +55,9 @@ public class RequestResponseJsonFileRepository extends RequestResponseMemoryRepo throw new RuntimeException(e); } finally { try { - os.close(); + if (os != null) { + os.close(); + } } catch (IOException e) { } } diff --git a/src/main/java/nl/wehkamp/everest/dao/RequestResponseMemoryRepository.java b/src/main/java/nl/wehkamp/everest/dao/PredictionMemoryRepository.java similarity index 58% rename from src/main/java/nl/wehkamp/everest/dao/RequestResponseMemoryRepository.java rename to src/main/java/nl/wehkamp/everest/dao/PredictionMemoryRepository.java index 84b8cc7..a21bcfb 100644 --- a/src/main/java/nl/wehkamp/everest/dao/RequestResponseMemoryRepository.java +++ b/src/main/java/nl/wehkamp/everest/dao/PredictionMemoryRepository.java @@ -1,14 +1,15 @@ package nl.wehkamp.everest.dao; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import nl.wehkamp.everest.model.Prediction; import org.springframework.stereotype.Repository; -@Repository("requestResponseMemoryRepository") -public class RequestResponseMemoryRepository implements RequestResponseRepository { +@Repository +public class PredictionMemoryRepository implements PredictionRepository { protected Set cache = new HashSet<>(); @Override @@ -24,4 +25,13 @@ public class RequestResponseMemoryRepository implements RequestResponseRepositor public void clear() { cache.clear(); } + + public Optional findByName(String name) { + for (Prediction p : cache) { + if (p.getName().equals(name)) { + return Optional.of(p); + } + } + return Optional.empty(); + } } diff --git a/src/main/java/nl/wehkamp/everest/dao/RequestResponseRepository.java b/src/main/java/nl/wehkamp/everest/dao/PredictionRepository.java similarity index 66% rename from src/main/java/nl/wehkamp/everest/dao/RequestResponseRepository.java rename to src/main/java/nl/wehkamp/everest/dao/PredictionRepository.java index 7f386ca..63d8150 100644 --- a/src/main/java/nl/wehkamp/everest/dao/RequestResponseRepository.java +++ b/src/main/java/nl/wehkamp/everest/dao/PredictionRepository.java @@ -4,9 +4,9 @@ import java.util.Set; import nl.wehkamp.everest.model.Prediction; -public interface RequestResponseRepository { +public interface PredictionRepository { - void save(Prediction record); + void save(Prediction prediction); Set findAll(); diff --git a/src/main/java/nl/wehkamp/everest/model/Headers.java b/src/main/java/nl/wehkamp/everest/model/Headers.java index a0cdc2b..631811a 100644 --- a/src/main/java/nl/wehkamp/everest/model/Headers.java +++ b/src/main/java/nl/wehkamp/everest/model/Headers.java @@ -5,6 +5,7 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import javax.servlet.http.HttpServletRequest; @@ -34,6 +35,10 @@ public class Headers { } } + public Set getHeaderNames() { + return headers.keySet(); + } + /** * returns all header values for a given name. Or null if none set */ diff --git a/src/main/java/nl/wehkamp/everest/model/Prediction.java b/src/main/java/nl/wehkamp/everest/model/Prediction.java index 907b01f..fab7d52 100644 --- a/src/main/java/nl/wehkamp/everest/model/Prediction.java +++ b/src/main/java/nl/wehkamp/everest/model/Prediction.java @@ -1,7 +1,10 @@ package nl.wehkamp.everest.model; +import static java.util.Optional.empty; + import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.regex.Pattern; import nl.wehkamp.everest.util.Uuids; @@ -18,6 +21,7 @@ public class Prediction { private String response; private int responseStatus; + private Optional responseHeaders = empty(); public boolean requestMatches(String requesturl) { return urlPattern.matcher(requesturl).matches(); @@ -28,13 +32,14 @@ public class Prediction { } private Prediction(Dto predictionDto) { - this.id = predictionDto.id; + this.id = predictionDto.id != null ? predictionDto.id : Uuids.create(); this.name = predictionDto.name; setUrl(predictionDto.url); this.method = predictionDto.method; this.requestHeaders = new Headers(predictionDto.requestHeaders); this.response = predictionDto.response; this.responseStatus = predictionDto.responseStatus; + this.responseHeaders = predictionDto.getResponseHeaders() != null ? Optional.of(new Headers(predictionDto.getResponseHeaders())) : empty(); } public String getMethod() { @@ -89,6 +94,18 @@ public class Prediction { 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 public int hashCode() { final int prime = 31; @@ -114,7 +131,7 @@ public class Prediction { return true; } - public boolean containsHeaders() { + public boolean containsRequestHeaders() { return requestHeaders != null && requestHeaders.areSet(); } @@ -124,7 +141,8 @@ public class Prediction { } public Dto toDto() { - return new Dto(id, name, url, method, requestHeaders.getContent(), response, responseStatus); + Map> responseHeaderMap = hasReponseHeaders() ? getResponseHeaders().getContent() : null; + return new Dto(id, name, url, method, requestHeaders.getContent(), response, responseStatus, responseHeaderMap); } public static Prediction fromDto(Dto predictionDto) { @@ -141,11 +159,13 @@ public class Prediction { private String response; private int responseStatus; + private Map> responseHeaders; public Dto() { } - private Dto(String id, String name, String url, String method, Map> requestHeaders, String response, int responseStatus) { + private Dto(String id, String name, String url, String method, Map> requestHeaders, String response, int responseStatus, + Map> responseHeaders) { super(); this.id = id; this.name = name; @@ -154,6 +174,7 @@ public class Prediction { this.requestHeaders = requestHeaders; this.response = response; this.responseStatus = responseStatus; + this.responseHeaders = responseHeaders; } public String getId() { @@ -212,6 +233,14 @@ public class Prediction { this.responseStatus = responseStatus; } + public Map> getResponseHeaders() { + return responseHeaders; + } + + public void setResponseHeaders(Map> responseHeaders) { + this.responseHeaders = responseHeaders; + } + @Override public int hashCode() { final int prime = 31; diff --git a/src/main/java/nl/wehkamp/everest/proxy/Proxy.java b/src/main/java/nl/wehkamp/everest/proxy/Proxy.java new file mode 100644 index 0000000..f9591d6 --- /dev/null +++ b/src/main/java/nl/wehkamp/everest/proxy/Proxy.java @@ -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; +// } +// } diff --git a/src/main/java/nl/wehkamp/everest/service/PredictionFactory.java b/src/main/java/nl/wehkamp/everest/service/PredictionFactory.java new file mode 100644 index 0000000..b8bbc2d --- /dev/null +++ b/src/main/java/nl/wehkamp/everest/service/PredictionFactory.java @@ -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)); + } +} diff --git a/src/main/java/nl/wehkamp/everest/service/ResponseFinder.java b/src/main/java/nl/wehkamp/everest/service/ResponseFinder.java index 4db7b83..97ea121 100644 --- a/src/main/java/nl/wehkamp/everest/service/ResponseFinder.java +++ b/src/main/java/nl/wehkamp/everest/service/ResponseFinder.java @@ -13,7 +13,7 @@ import java.util.Set; import javax.servlet.http.HttpServletRequest; -import nl.wehkamp.everest.dao.RequestResponseRepository; +import nl.wehkamp.everest.dao.PredictionRepository; import nl.wehkamp.everest.model.Prediction; import org.springframework.beans.factory.annotation.Autowired; @@ -25,31 +25,31 @@ import org.springframework.stereotype.Service; @Service public class ResponseFinder { @Autowired - private RequestResponseRepository requestResponseRepository; + private PredictionRepository predictionJsonFileRepository; public Optional find(HttpServletRequest request) { Optional response = Optional.empty(); - Set all = requestResponseRepository.findAll(); + Set all = predictionJsonFileRepository.findAll(); for (Prediction prediction : all) { response = matchUrlAndMethodAndHeaders(request, response, prediction); } return response; } - private Optional matchUrlAndMethodAndHeaders(HttpServletRequest request, Optional response, Prediction rr) { - if (rr.requestMatches(request.getPathInfo())) { - response = matchMethodAndHeaders(request, response, rr); + private Optional matchUrlAndMethodAndHeaders(HttpServletRequest request, Optional response, Prediction prediction) { + if (prediction.requestMatches(request.getPathInfo())) { + response = matchMethodAndHeaders(request, response, prediction); } return response; } - private Optional matchMethodAndHeaders(HttpServletRequest request, Optional response, Prediction rr) { - if (rr.getMethod().equals(request.getMethod())) { - if (rr.containsHeaders()) { - response = matchHeaders(request, response, rr); + private Optional matchMethodAndHeaders(HttpServletRequest request, Optional response, Prediction prediction) { + if (prediction.getMethod().equals(request.getMethod())) { + if (prediction.containsRequestHeaders()) { + response = matchHeaders(request, response, prediction); } else { - response = Optional.of(rr); + response = Optional.of(prediction); } } return response; @@ -62,7 +62,7 @@ public class ResponseFinder { return response; } - public void setRequestResponseRepository(RequestResponseRepository requestResponseRepository) { - this.requestResponseRepository = requestResponseRepository; + public void setPredictionRepository(PredictionRepository predictionJsonFileRepository) { + this.predictionJsonFileRepository = predictionJsonFileRepository; } } diff --git a/src/main/java/nl/wehkamp/everest/web/MockingServlet.java b/src/main/java/nl/wehkamp/everest/web/MockingServlet.java deleted file mode 100644 index c620092..0000000 --- a/src/main/java/nl/wehkamp/everest/web/MockingServlet.java +++ /dev/null @@ -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 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); - } - - } -} diff --git a/src/main/java/nl/wehkamp/everest/web/PredictableResponseServlet.java b/src/main/java/nl/wehkamp/everest/web/PredictableResponseServlet.java new file mode 100644 index 0000000..914a4a9 --- /dev/null +++ b/src/main/java/nl/wehkamp/everest/web/PredictableResponseServlet.java @@ -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 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; + } +} diff --git a/src/test/java/nl/wehkamp/everest/dao/RecordRepositoryTest.java b/src/test/java/nl/wehkamp/everest/dao/RecordRepositoryTest.java index a6e3790..3fe19fd 100644 --- a/src/test/java/nl/wehkamp/everest/dao/RecordRepositoryTest.java +++ b/src/test/java/nl/wehkamp/everest/dao/RecordRepositoryTest.java @@ -11,6 +11,7 @@ import java.util.List; import nl.wehkamp.everest.model.Headers; import nl.wehkamp.everest.model.Prediction; +import nl.wehkamp.everest.util.FileLoader; import nl.wehkamp.everest.util.Uuids; import org.testng.annotations.AfterMethod; @@ -37,15 +38,13 @@ public class RecordRepositoryTest { record.setHeaders(headers); record.setResponseStatus(200); record.setResponse(""); - new RequestResponseJsonFileRepository().save(record); + new PredictionJsonFileRepository().save(record); List lines = Files.readAllLines(Paths.get("everest_data", "wehkamp.nl.json"), StandardCharsets.UTF_8); assertFalse(lines.isEmpty()); System.out.println(lines.get(0)); - assertEquals( - lines.get(0), - "{\"id\":\"91f83cd9-a0a5-49f5-b740-78ba8f504797\",\"name\":\"wehkamp.nl\",\"url\":\"http://www.wehkamp.nl\",\"method\":\"GET\",\"requestHeaders\":{\"Accept\":[\"application/json\"]},\"response\":\"\",\"responseStatus\":200}"); + assertEquals(lines.get(0), FileLoader.load("test.json")); } } diff --git a/src/test/java/nl/wehkamp/everest/util/FileLoader.java b/src/test/java/nl/wehkamp/everest/util/FileLoader.java new file mode 100644 index 0000000..407329b --- /dev/null +++ b/src/test/java/nl/wehkamp/everest/util/FileLoader.java @@ -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); + } + } +} diff --git a/src/test/java/nl/wehkamp/everest/web/TestClient.java b/src/test/java/nl/wehkamp/everest/util/TestClient.java similarity index 54% rename from src/test/java/nl/wehkamp/everest/web/TestClient.java rename to src/test/java/nl/wehkamp/everest/util/TestClient.java index cb49730..225872c 100644 --- a/src/test/java/nl/wehkamp/everest/web/TestClient.java +++ b/src/test/java/nl/wehkamp/everest/util/TestClient.java @@ -1,21 +1,24 @@ -package nl.wehkamp.everest.web; +package nl.wehkamp.everest.util; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.util.Map; import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.HttpClients; public class TestClient { private static HttpClient httpclient = HttpClients.createDefault(); private static HttpHost target = new HttpHost("localhost", 8080, "http"); - public static String get(String url) { + public static String httpGet(String url) { try { HttpGet httpGet = new HttpGet(url); HttpResponse httpResponse = httpclient.execute(target, httpGet); @@ -26,7 +29,7 @@ public class TestClient { } } - public static String get(String url, Map headers) { + public static String httpGet(String url, Map headers) { HttpGet httpGet = new HttpGet(url); for (Map.Entry header : headers.entrySet()) { 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 { - 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 headers) { + try { + HttpPost httpPost = createPost(url, postBody, headers); + HttpResponse httpResponse = httpclient.execute(target, httpPost); String body = IOUtils.toString(httpResponse.getEntity().getContent()); return httpResponse.getStatusLine().getStatusCode() + ":" + body; @@ -50,4 +65,17 @@ public class TestClient { throw new RuntimeException(e); } } + + private static HttpPost createPost(String url, String postBody, Map 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 header : headers.entrySet()) { + httpPost.addHeader(header.getKey(), header.getValue()); + } + } + return httpPost; + } + } diff --git a/src/test/java/nl/wehkamp/everest/web/MockingServletTests.java b/src/test/java/nl/wehkamp/everest/web/MockingServletTests.java index 6305623..99230cd 100644 --- a/src/test/java/nl/wehkamp/everest/web/MockingServletTests.java +++ b/src/test/java/nl/wehkamp/everest/web/MockingServletTests.java @@ -1,11 +1,11 @@ package nl.wehkamp.everest.web; import static java.util.Collections.singletonMap; -import static nl.wehkamp.everest.web.TestClient.get; -import static nl.wehkamp.everest.web.TestClient.post; +import static nl.wehkamp.everest.util.TestClient.httpGet; +import static nl.wehkamp.everest.util.TestClient.httpPost; import static org.testng.Assert.assertEquals; 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.service.ResponseFinder; @@ -18,14 +18,14 @@ import org.testng.annotations.Test; */ public class MockingServletTests { - private RequestResponseMemoryRepository requestResponseRepository; + private PredictionMemoryRepository requestResponseRepository; @BeforeSuite public void setup() { WebServer.start(); ResponseFinder responseFinder = WebServer.instance.getBean(ResponseFinder.class); - requestResponseRepository = new RequestResponseMemoryRepository(); - responseFinder.setRequestResponseRepository(requestResponseRepository); + requestResponseRepository = new PredictionMemoryRepository(); + responseFinder.setPredictionRepository(requestResponseRepository); } @AfterMethod @@ -41,7 +41,7 @@ public class MockingServletTests { record.setResponse("get successful"); record.setResponseStatus(200); requestResponseRepository.save(record); - assertEquals(get("/testget"), "200:get successful"); + assertEquals(httpGet("/testget"), "200:get successful"); } @Test @@ -53,7 +53,7 @@ public class MockingServletTests { record.setResponse("getWithHeader successful"); record.setResponseStatus(200); 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 @@ -65,7 +65,7 @@ public class MockingServletTests { record.setResponse("getWithHeader successful"); record.setResponseStatus(200); 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 @@ -76,7 +76,7 @@ public class MockingServletTests { record.setResponse("get wildcard successful"); record.setResponseStatus(200); requestResponseRepository.save(record); - assertEquals(get("/testget/foo"), "200:get wildcard successful"); + assertEquals(httpGet("/testget/foo"), "200:get wildcard successful"); } @Test @@ -87,6 +87,6 @@ public class MockingServletTests { record.setResponse("post successful"); record.setResponseStatus(200); requestResponseRepository.save(record); - assertEquals(post("/testpost", "body"), "200:post successful"); + assertEquals(httpPost("/testpost", "body"), "200:post successful"); } } diff --git a/src/test/java/nl/wehkamp/everest/web/UploadTests.java b/src/test/java/nl/wehkamp/everest/web/UploadTests.java new file mode 100644 index 0000000..0f75798 --- /dev/null +++ b/src/test/java/nl/wehkamp/everest/web/UploadTests.java @@ -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 = predictionMemoryRepository.findByName("test.nl"); + assertTrue(prediction.isPresent()); + assertEquals(prediction.get().getUrl(), "/entry"); + } +} diff --git a/src/test/resources/test.json b/src/test/resources/test.json new file mode 100644 index 0000000..ffb5adf --- /dev/null +++ b/src/test/resources/test.json @@ -0,0 +1 @@ +{"id":"91f83cd9-a0a5-49f5-b740-78ba8f504797","name":"wehkamp.nl","url":"http://www.wehkamp.nl","method":"GET","requestHeaders":{"Accept":["application/json"]},"response":"","responseStatus":200,"responseHeaders":null} \ No newline at end of file diff --git a/src/test/resources/uploadtest.json b/src/test/resources/uploadtest.json new file mode 100644 index 0000000..3d42f72 --- /dev/null +++ b/src/test/resources/uploadtest.json @@ -0,0 +1 @@ +{"id":"1","name":"test.nl","url":"/entry","method":"GET","requestHeaders":{"Accept":["application/json"]},"response":"","responseStatus":200,"responseHeaders":null} \ No newline at end of file