diff --git a/ui/web/pom.xml b/ui/web/pom.xml
index 3714ae5..57d2b8b 100644
--- a/ui/web/pom.xml
+++ b/ui/web/pom.xml
@@ -25,6 +25,7 @@
UTF-8
${project.build.sourceEncoding}
3.6
+ 1.2.5
1.8
@@ -238,6 +239,30 @@
batik-svggen
+
+ info.cukes
+ cucumber-core
+ ${cucumber.java.version}
+ test
+
+
+ info.cukes
+ cucumber-java
+ ${cucumber.java.version}
+ test
+
+
+ info.cukes
+ cucumber-junit
+ ${cucumber.java.version}
+ test
+
+
+ info.cukes
+ cucumber-spring
+ ${cucumber.java.version}
+ test
+
diff --git a/ui/web/src/test/java/gallerymine/test/ui/CucumberIntegrationTest.java b/ui/web/src/test/java/gallerymine/test/ui/CucumberIntegrationTest.java
new file mode 100644
index 0000000..34cf84c
--- /dev/null
+++ b/ui/web/src/test/java/gallerymine/test/ui/CucumberIntegrationTest.java
@@ -0,0 +1,14 @@
+package gallerymine.test.ui;
+
+import org.junit.runner.RunWith;
+
+import cucumber.api.CucumberOptions;
+import cucumber.api.junit.Cucumber;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestTemplate;
+
+@RunWith(Cucumber.class)
+@CucumberOptions(features = "src/test/resources")
+public class CucumberIntegrationTest extends SpringIntegrationTest {
+
+}
\ No newline at end of file
diff --git a/ui/web/src/test/java/gallerymine/test/ui/CucumberLocalTest.java b/ui/web/src/test/java/gallerymine/test/ui/CucumberLocalTest.java
new file mode 100644
index 0000000..06b2687
--- /dev/null
+++ b/ui/web/src/test/java/gallerymine/test/ui/CucumberLocalTest.java
@@ -0,0 +1,12 @@
+package gallerymine.test.ui;
+
+import cucumber.api.CucumberOptions;
+import cucumber.api.java.Before;
+import cucumber.api.junit.Cucumber;
+import org.junit.runner.RunWith;
+
+@RunWith(Cucumber.class)
+@CucumberOptions(features = "src/test/resources")
+public class CucumberLocalTest extends SpringIntegrationTest {
+
+}
\ No newline at end of file
diff --git a/ui/web/src/test/java/gallerymine/test/ui/HeaderSettingRequestCallback.java b/ui/web/src/test/java/gallerymine/test/ui/HeaderSettingRequestCallback.java
new file mode 100644
index 0000000..37a9f8d
--- /dev/null
+++ b/ui/web/src/test/java/gallerymine/test/ui/HeaderSettingRequestCallback.java
@@ -0,0 +1,33 @@
+package gallerymine.test.ui;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.client.ClientHttpRequest;
+import org.springframework.web.client.RequestCallback;
+
+import java.io.IOException;
+import java.util.Map;
+
+public class HeaderSettingRequestCallback implements RequestCallback {
+ final Map requestHeaders;
+
+ private String body;
+
+ public HeaderSettingRequestCallback(final Map headers) {
+ this.requestHeaders = headers;
+ }
+
+ public void setBody(final String postBody) {
+ this.body = postBody;
+ }
+
+ @Override
+ public void doWithRequest(ClientHttpRequest request) throws IOException {
+ final HttpHeaders clientHeaders = request.getHeaders();
+ for (final Map.Entry entry : requestHeaders.entrySet()) {
+ clientHeaders.add(entry.getKey(), entry.getValue());
+ }
+ if (null != body) {
+ request.getBody().write(body.getBytes());
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/web/src/test/java/gallerymine/test/ui/ResponseResults.java b/ui/web/src/test/java/gallerymine/test/ui/ResponseResults.java
new file mode 100644
index 0000000..a706b2a
--- /dev/null
+++ b/ui/web/src/test/java/gallerymine/test/ui/ResponseResults.java
@@ -0,0 +1,29 @@
+package gallerymine.test.ui;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.http.client.ClientHttpResponse;
+
+public class ResponseResults {
+ private final ClientHttpResponse theResponse;
+ private final String body;
+
+ ResponseResults(final ClientHttpResponse response) throws IOException {
+ this.theResponse = response;
+ final InputStream bodyInputStream = response.getBody();
+ final StringWriter stringWriter = new StringWriter();
+ IOUtils.copy(bodyInputStream, stringWriter);
+ this.body = stringWriter.toString();
+ }
+
+ ClientHttpResponse getTheResponse() {
+ return theResponse;
+ }
+
+ String getBody() {
+ return body;
+ }
+}
\ No newline at end of file
diff --git a/ui/web/src/test/java/gallerymine/test/ui/SpringIntegrationTest.java b/ui/web/src/test/java/gallerymine/test/ui/SpringIntegrationTest.java
new file mode 100644
index 0000000..07cc749
--- /dev/null
+++ b/ui/web/src/test/java/gallerymine/test/ui/SpringIntegrationTest.java
@@ -0,0 +1,91 @@
+package gallerymine.test.ui;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import cucumber.api.java.Before;
+import gallerymine.GalleryMineApplication;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.embedded.LocalServerPort;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.web.client.ResponseErrorHandler;
+import org.springframework.web.client.RestTemplate;
+
+//@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = GalleryMineApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
+@ContextConfiguration
+public class SpringIntegrationTest {
+ static ResponseResults latestResponse = null;
+ static ResponseEntity latestResponseMap = null;
+
+ @LocalServerPort
+ public int serverPort;
+
+ @Autowired
+ protected RestTemplate restTemplate;
+
+ void executeGet(String url) throws IOException {
+ final Map headers = new HashMap<>();
+ headers.put("Accept", "application/json");
+ final HeaderSettingRequestCallback requestCallback = new HeaderSettingRequestCallback(headers);
+ final ResponseResultErrorHandler errorHandler = new ResponseResultErrorHandler();
+
+ restTemplate.setErrorHandler(errorHandler);
+ latestResponse = restTemplate.execute(url, HttpMethod.GET, requestCallback, response -> {
+ if (errorHandler.hadError) {
+ return (errorHandler.getResults());
+ } else {
+ return (new ResponseResults(response));
+ }
+ });
+ }
+
+ void executePost() throws IOException {
+ final Map headers = new HashMap<>();
+ headers.put("Accept", "application/json");
+ final HeaderSettingRequestCallback requestCallback = new HeaderSettingRequestCallback(headers);
+ final ResponseResultErrorHandler errorHandler = new ResponseResultErrorHandler();
+
+ if (restTemplate == null) {
+ restTemplate = new RestTemplate();
+ }
+
+ restTemplate.setErrorHandler(errorHandler);
+ latestResponse = restTemplate
+ .execute("http://localhost:"+serverPort+"/baeldung", HttpMethod.POST, requestCallback, response -> {
+ if (errorHandler.hadError) {
+ return (errorHandler.getResults());
+ } else {
+ return (new ResponseResults(response));
+ }
+ });
+ }
+
+ private class ResponseResultErrorHandler implements ResponseErrorHandler {
+ private ResponseResults results = null;
+ private Boolean hadError = false;
+
+ private ResponseResults getResults() {
+ return results;
+ }
+
+ @Override
+ public boolean hasError(ClientHttpResponse response) throws IOException {
+ hadError = response.getRawStatusCode() >= 400;
+ return hadError;
+ }
+
+ @Override
+ public void handleError(ClientHttpResponse response) throws IOException {
+ results = new ResponseResults(response);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/web/src/test/java/gallerymine/test/ui/StepDefsIntegrationTest.java b/ui/web/src/test/java/gallerymine/test/ui/StepDefsIntegrationTest.java
new file mode 100644
index 0000000..3ce1608
--- /dev/null
+++ b/ui/web/src/test/java/gallerymine/test/ui/StepDefsIntegrationTest.java
@@ -0,0 +1,102 @@
+package gallerymine.test.ui;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import cucumber.api.java.en.Given;
+import gallerymine.model.mvc.SourceCriteria;
+import gallerymine.model.support.PictureGrade;
+import org.springframework.context.expression.MapAccessor;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.Expression;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.SpelParserConfiguration;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.ReflectivePropertyAccessor;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+
+import cucumber.api.java.en.And;
+import cucumber.api.java.en.Then;
+import cucumber.api.java.en.When;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+
+import java.util.HashMap;
+
+public class StepDefsIntegrationTest extends SpringIntegrationTest {
+
+ @When("^the client calls /baeldung$")
+ public void the_client_issues_POST_hello() throws Throwable {
+ executePost();
+ }
+
+ @Given("^the client calls /hello$")
+ public void the_client_issues_GET_hello() throws Throwable {
+ executeGet("http://localhost:"+serverPort+"/hello");
+ }
+
+ @Given("^api call /listFolders")
+ public void the_client_issues_list_folders() {
+ SourceCriteria searchCriteria = new SourceCriteria();
+ searchCriteria.setPage(0);
+ searchCriteria.setSize(10);
+ searchCriteria.setPath("test");
+ searchCriteria.setGrade(PictureGrade.GALLERY);
+ MultiValueMap headers = new LinkedMultiValueMap<>();
+ headers.add("Accept", "application/json");
+ headers.add("Content-Type", "application/json; charset=UTF-8");
+ HttpEntity request = new HttpEntity<>(searchCriteria, headers);
+ latestResponseMap = restTemplate .exchange("http://localhost:"+serverPort+"/sources/findPath", HttpMethod.POST, request, HashMap.class);
+ System.out.print("Run");
+ }
+
+ @When("^the client calls /version$")
+ public void the_client_issues_GET_version() throws Throwable {
+ executeGet("http://localhost:"+serverPort+"/version");
+ }
+
+ @Then("^response status code is (\\d+)$")
+ public void the_client_receives_status_code_of(int statusCode) {
+ final HttpStatus currentStatusCode = latestResponseMap.getStatusCode();
+ assertThat("status code is incorrect : " + latestResponseMap.getStatusCode(), currentStatusCode.value(), is(statusCode));
+ }
+
+ @And("^the client receives server version (.+)$")
+ public void the_client_receives_server_version_body(String version) {
+ assertThat(latestResponse.getBody(), is(version));
+ }
+
+ @And("^response has (.+)$")
+ public void responseHas(String key) {
+ assertTrue("Key not found in response key='"+key+"'", latestResponseMap.getBody().containsKey(key));
+ }
+
+ @And("^response key (.+) equal to (.+)$")
+ public void responseValue(String key, String valueStr) {
+ Object valueExpected = resolveExpression(valueStr);
+ Object valueActual = valueExpected == null ? resolveExpression(key) : resolveExpression(key, valueExpected.getClass());
+ assertEquals("Value not equal for '"+key+"' which is '"+valueActual+"' != '"+valueExpected+"'",valueExpected, valueActual);
+ }
+
+ public Object resolveExpression(String expression) {
+ return resolveExpression(expression , null);
+ }
+
+ public Object resolveExpression(String expression, Class clazzRequired) {
+ SpelParserConfiguration config = new SpelParserConfiguration(true,true);
+ ExpressionParser parser = new SpelExpressionParser(config);
+ StandardEvaluationContext context = new StandardEvaluationContext(latestResponseMap);
+ context.addPropertyAccessor(new MapAccessor());
+ Expression exp = parser.parseExpression(expression);
+ if (clazzRequired != null) {
+ return exp.getValue(context, clazzRequired);
+ } else {
+ return exp.getValue(context);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/web/src/test/resources/application.yml b/ui/web/src/test/resources/application.yml
new file mode 100644
index 0000000..92b2b40
--- /dev/null
+++ b/ui/web/src/test/resources/application.yml
@@ -0,0 +1,8 @@
+spring:
+ data:
+ mongodb.uri: mongodb://localhost:27017/galleryMineTest
+
+javamelody:
+ # Enable JavaMelody auto-configuration (optional, default: true)
+ enabled: false
+
diff --git a/ui/web/src/test/resources/folders.feature b/ui/web/src/test/resources/folders.feature
new file mode 100644
index 0000000..58fb84e
--- /dev/null
+++ b/ui/web/src/test/resources/folders.feature
@@ -0,0 +1,7 @@
+Feature: Test Main Controller methods
+
+ Scenario: Test list Folders of gallery
+ When api call /listFolders
+ Then response status code is 200
+ And response key body.status equal to 200
+ And response key body.list.size equal to 10