BAEL-20884 Revert move of spring-boot-rest module
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
package com.baeldung;
|
||||
|
||||
public interface Consts {
|
||||
int APPLICATION_PORT = 8080;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = {SpringBootRestApplication.class})
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package com.baeldung.common.web;
|
||||
|
||||
import static com.baeldung.web.util.HTTPLinkHeaderUtil.extractURIByRel;
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.http.ContentType;
|
||||
import io.restassured.response.Response;
|
||||
|
||||
public abstract class AbstractBasicLiveTest<T extends Serializable> extends AbstractLiveTest<T> {
|
||||
|
||||
public AbstractBasicLiveTest(final Class<T> clazzToSet) {
|
||||
super(clazzToSet);
|
||||
}
|
||||
|
||||
// find - all - paginated
|
||||
|
||||
@Test
|
||||
public void whenResourcesAreRetrievedPaged_then200IsReceived() {
|
||||
create();
|
||||
|
||||
final Response response = RestAssured.get(getURL() + "?page=0&size=10");
|
||||
|
||||
assertThat(response.getStatusCode(), is(200));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenPageOfResourcesAreRetrievedOutOfBounds_then404IsReceived() {
|
||||
final String url = getURL() + "?page=" + randomNumeric(5) + "&size=10";
|
||||
final Response response = RestAssured.get(url);
|
||||
|
||||
assertThat(response.getStatusCode(), is(404));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenResourcesExist_whenFirstPageIsRetrieved_thenPageContainsResources() {
|
||||
create();
|
||||
|
||||
final Response response = RestAssured.get(getURL() + "?page=0&size=10");
|
||||
|
||||
assertFalse(response.body().as(List.class).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFirstPageOfResourcesAreRetrieved_thenSecondPageIsNext() {
|
||||
create();
|
||||
create();
|
||||
create();
|
||||
|
||||
final Response response = RestAssured.get(getURL() + "?page=0&size=2");
|
||||
|
||||
final String uriToNextPage = extractURIByRel(response.getHeader(HttpHeaders.LINK), "next");
|
||||
assertEquals(getURL() + "?page=1&size=2", uriToNextPage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFirstPageOfResourcesAreRetrieved_thenNoPreviousPage() {
|
||||
final Response response = RestAssured.get(getURL() + "?page=0&size=2");
|
||||
|
||||
final String uriToPrevPage = extractURIByRel(response.getHeader(HttpHeaders.LINK), "prev");
|
||||
assertNull(uriToPrevPage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSecondPageOfResourcesAreRetrieved_thenFirstPageIsPrevious() {
|
||||
create();
|
||||
create();
|
||||
|
||||
final Response response = RestAssured.get(getURL() + "?page=1&size=2");
|
||||
|
||||
final String uriToPrevPage = extractURIByRel(response.getHeader(HttpHeaders.LINK), "prev");
|
||||
assertEquals(getURL() + "?page=0&size=2", uriToPrevPage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenLastPageOfResourcesIsRetrieved_thenNoNextPageIsDiscoverable() {
|
||||
create();
|
||||
create();
|
||||
create();
|
||||
|
||||
final Response first = RestAssured.get(getURL() + "?page=0&size=2");
|
||||
final String uriToLastPage = extractURIByRel(first.getHeader(HttpHeaders.LINK), "last");
|
||||
|
||||
final Response response = RestAssured.get(uriToLastPage);
|
||||
|
||||
final String uriToNextPage = extractURIByRel(response.getHeader(HttpHeaders.LINK), "next");
|
||||
assertNull(uriToNextPage);
|
||||
}
|
||||
|
||||
// etags
|
||||
|
||||
@Test
|
||||
public void givenResourceExists_whenRetrievingResource_thenEtagIsAlsoReturned() {
|
||||
// Given
|
||||
final String uriOfResource = createAsUri();
|
||||
|
||||
// When
|
||||
final Response findOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.get(uriOfResource);
|
||||
|
||||
// Then
|
||||
assertNotNull(findOneResponse.getHeader(HttpHeaders.ETAG));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenResourceWasRetrieved_whenRetrievingAgainWithEtag_thenNotModifiedReturned() {
|
||||
// Given
|
||||
final String uriOfResource = createAsUri();
|
||||
final Response findOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.get(uriOfResource);
|
||||
final String etagValue = findOneResponse.getHeader(HttpHeaders.ETAG);
|
||||
|
||||
// When
|
||||
final Response secondFindOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.headers("If-None-Match", etagValue)
|
||||
.get(uriOfResource);
|
||||
|
||||
// Then
|
||||
assertTrue(secondFindOneResponse.getStatusCode() == 304);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenResourceWasRetrievedThenModified_whenRetrievingAgainWithEtag_thenResourceIsReturned() {
|
||||
// Given
|
||||
final String uriOfResource = createAsUri();
|
||||
final Response firstFindOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.get(uriOfResource);
|
||||
final String etagValue = firstFindOneResponse.getHeader(HttpHeaders.ETAG);
|
||||
final long createdId = firstFindOneResponse.jsonPath().getLong("id");
|
||||
|
||||
Foo updatedFoo = new Foo("updated value");
|
||||
updatedFoo.setId(createdId);
|
||||
Response updatedResponse = RestAssured.given().contentType(ContentType.JSON).body(updatedFoo)
|
||||
.put(uriOfResource);
|
||||
assertThat(updatedResponse.getStatusCode() == 200);
|
||||
|
||||
// When
|
||||
final Response secondFindOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.headers("If-None-Match", etagValue)
|
||||
.get(uriOfResource);
|
||||
|
||||
// Then
|
||||
assertTrue(secondFindOneResponse.getStatusCode() == 200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Not Yet Implemented By Spring - https://jira.springsource.org/browse/SPR-10164")
|
||||
public void givenResourceExists_whenRetrievedWithIfMatchIncorrectEtag_then412IsReceived() {
|
||||
// Given
|
||||
final String uriOfResource = createAsUri();
|
||||
|
||||
// When
|
||||
final Response findOneResponse = RestAssured.given()
|
||||
.header("Accept", "application/json")
|
||||
.headers("If-Match", randomAlphabetic(8))
|
||||
.get(uriOfResource);
|
||||
|
||||
// Then
|
||||
assertTrue(findOneResponse.getStatusCode() == 412);
|
||||
}
|
||||
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package com.baeldung.common.web;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
import com.baeldung.web.util.HTTPLinkHeaderUtil;
|
||||
import org.hamcrest.core.AnyOf;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.google.common.net.HttpHeaders;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.response.Response;
|
||||
|
||||
public abstract class AbstractDiscoverabilityLiveTest<T extends Serializable> extends AbstractLiveTest<T> {
|
||||
|
||||
public AbstractDiscoverabilityLiveTest(final Class<T> clazzToSet) {
|
||||
super(clazzToSet);
|
||||
}
|
||||
|
||||
// tests
|
||||
|
||||
// discoverability
|
||||
|
||||
@Test
|
||||
public void whenInvalidPOSTIsSentToValidURIOfResource_thenAllowHeaderListsTheAllowedActions() {
|
||||
// Given
|
||||
final String uriOfExistingResource = createAsUri();
|
||||
|
||||
// When
|
||||
final Response res = RestAssured.post(uriOfExistingResource);
|
||||
|
||||
// Then
|
||||
final String allowHeader = res.getHeader(HttpHeaders.ALLOW);
|
||||
assertThat(allowHeader, AnyOf.anyOf(containsString("GET"), containsString("PUT"), containsString("DELETE")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenResourceIsCreated_thenUriOfTheNewlyCreatedResourceIsDiscoverable() {
|
||||
// When
|
||||
final Foo newResource = new Foo(randomAlphabetic(6));
|
||||
final Response createResp = RestAssured.given()
|
||||
.contentType(MediaType.APPLICATION_JSON_VALUE)
|
||||
.body(newResource)
|
||||
.post(getURL());
|
||||
final String uriOfNewResource = createResp.getHeader(HttpHeaders.LOCATION);
|
||||
|
||||
// Then
|
||||
final Response response = RestAssured.given()
|
||||
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
||||
.get(uriOfNewResource);
|
||||
|
||||
final Foo resourceFromServer = response.body().as(Foo.class);
|
||||
assertThat(newResource, equalTo(resourceFromServer));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenResourceIsRetrieved_thenUriToGetAllResourcesIsDiscoverable() {
|
||||
// Given
|
||||
final String uriOfExistingResource = createAsUri();
|
||||
|
||||
// When
|
||||
final Response getResponse = RestAssured.get(uriOfExistingResource);
|
||||
|
||||
// Then
|
||||
final String uriToAllResources = HTTPLinkHeaderUtil.extractURIByRel(getResponse.getHeader("Link"), "collection");
|
||||
|
||||
final Response getAllResponse = RestAssured.get(uriToAllResources);
|
||||
assertThat(getAllResponse.getStatusCode(), is(200));
|
||||
}
|
||||
|
||||
// template method
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.baeldung.common.web;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.response.Response;
|
||||
|
||||
import static com.baeldung.Consts.APPLICATION_PORT;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.baeldung.test.IMarshaller;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
|
||||
public abstract class AbstractLiveTest<T extends Serializable> {
|
||||
|
||||
protected final Class<T> clazz;
|
||||
|
||||
@Autowired
|
||||
protected IMarshaller marshaller;
|
||||
|
||||
public AbstractLiveTest(final Class<T> clazzToSet) {
|
||||
super();
|
||||
|
||||
Preconditions.checkNotNull(clazzToSet);
|
||||
clazz = clazzToSet;
|
||||
}
|
||||
|
||||
// template method
|
||||
|
||||
public abstract void create();
|
||||
|
||||
public abstract String createAsUri();
|
||||
|
||||
protected final void create(final T resource) {
|
||||
createAsUri(resource);
|
||||
}
|
||||
|
||||
protected final String createAsUri(final T resource) {
|
||||
final Response response = createAsResponse(resource);
|
||||
Preconditions.checkState(response.getStatusCode() == 201, "create operation: " + response.getStatusCode());
|
||||
|
||||
final String locationOfCreatedResource = response.getHeader(HttpHeaders.LOCATION);
|
||||
Preconditions.checkNotNull(locationOfCreatedResource);
|
||||
return locationOfCreatedResource;
|
||||
}
|
||||
|
||||
final Response createAsResponse(final T resource) {
|
||||
Preconditions.checkNotNull(resource);
|
||||
|
||||
final String resourceAsString = marshaller.encode(resource);
|
||||
return RestAssured.given()
|
||||
.contentType(marshaller.getMime())
|
||||
.body(resourceAsString)
|
||||
.post(getURL());
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
protected String getURL() {
|
||||
return "http://localhost:" + APPLICATION_PORT + "/spring-boot-rest/foos";
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.baeldung.controllers;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import com.baeldung.SpringBootRestApplication;
|
||||
import com.baeldung.requestresponsebody.ExamplePostController;
|
||||
import com.baeldung.requestresponsebody.LoginForm;
|
||||
import com.baeldung.services.ExampleService;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = SpringBootRestApplication.class)
|
||||
public class ExamplePostControllerRequestIntegrationTest {
|
||||
|
||||
MockMvc mockMvc;
|
||||
@Mock private ExampleService exampleService;
|
||||
@InjectMocks private ExamplePostController exampleController;
|
||||
private final String jsonBody = "{\"username\": \"username\", \"password\": \"password\"}";
|
||||
private LoginForm lf = new LoginForm();
|
||||
|
||||
@Before
|
||||
public void preTest() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mockMvc = MockMvcBuilders
|
||||
.standaloneSetup(exampleController)
|
||||
.build();
|
||||
lf.setPassword("password");
|
||||
lf.setUsername("username");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestBodyTest() {
|
||||
try {
|
||||
when(exampleService.fakeAuthenticate(lf)).thenReturn(true);
|
||||
mockMvc
|
||||
.perform(post("/post/request")
|
||||
.content(jsonBody)
|
||||
.contentType("application/json"))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk());
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.baeldung.controllers;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import com.baeldung.SpringBootRestApplication;
|
||||
import com.baeldung.requestresponsebody.ExamplePostController;
|
||||
import com.baeldung.requestresponsebody.LoginForm;
|
||||
import com.baeldung.services.ExampleService;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = SpringBootRestApplication.class)
|
||||
public class ExamplePostControllerResponseIntegrationTest {
|
||||
|
||||
MockMvc mockMvc;
|
||||
@Mock private ExampleService exampleService;
|
||||
@InjectMocks private ExamplePostController exampleController;
|
||||
private final String jsonBody = "{\"username\": \"username\", \"password\": \"password\"}";
|
||||
private LoginForm lf = new LoginForm();
|
||||
|
||||
@Before
|
||||
public void preTest() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mockMvc = MockMvcBuilders
|
||||
.standaloneSetup(exampleController)
|
||||
.build();
|
||||
lf.setPassword("password");
|
||||
lf.setUsername("username");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestBodyTest() {
|
||||
try {
|
||||
when(exampleService.fakeAuthenticate(lf)).thenReturn(true);
|
||||
mockMvc
|
||||
.perform(post("/post/response")
|
||||
.content(jsonBody)
|
||||
.contentType("application/json"))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().json("{\"text\":\"Thanks For Posting!!!\"}"));
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.rest;
|
||||
|
||||
public class GitHubUser {
|
||||
|
||||
private String login;
|
||||
|
||||
public GitHubUser() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public void setLogin(final String login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.baeldung.rest;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
|
||||
public class GithubBasicLiveTest {
|
||||
|
||||
// simple request - response
|
||||
|
||||
@Test
|
||||
public void givenUserDoesNotExists_whenUserInfoIsRetrieved_then404IsReceived() throws ClientProtocolException, IOException {
|
||||
// Given
|
||||
final String name = randomAlphabetic(8);
|
||||
final HttpUriRequest request = new HttpGet("https://api.github.com/users/" + name);
|
||||
|
||||
// When
|
||||
final HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
|
||||
|
||||
// Then
|
||||
assertThat(httpResponse.getStatusLine().getStatusCode(), equalTo(HttpStatus.SC_NOT_FOUND));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenRequestWithNoAcceptHeader_whenRequestIsExecuted_thenDefaultResponseContentTypeIsJson() throws ClientProtocolException, IOException {
|
||||
// Given
|
||||
final String jsonMimeType = "application/json";
|
||||
final HttpUriRequest request = new HttpGet("https://api.github.com/users/eugenp");
|
||||
|
||||
// When
|
||||
final HttpResponse response = HttpClientBuilder.create().build().execute(request);
|
||||
|
||||
// Then
|
||||
final String mimeType = ContentType.getOrDefault(response.getEntity()).getMimeType();
|
||||
assertEquals(jsonMimeType, mimeType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUserExists_whenUserInformationIsRetrieved_thenRetrievedResourceIsCorrect() throws ClientProtocolException, IOException {
|
||||
// Given
|
||||
final HttpUriRequest request = new HttpGet("https://api.github.com/users/eugenp");
|
||||
|
||||
// When
|
||||
final HttpResponse response = HttpClientBuilder.create().build().execute(request);
|
||||
|
||||
// Then
|
||||
final GitHubUser resource = RetrieveUtil.retrieveResourceFromResponse(response, GitHubUser.class);
|
||||
assertThat("eugenp", Matchers.is(resource.getLogin()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.rest;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public class RetrieveUtil {
|
||||
|
||||
// API
|
||||
|
||||
public static <T> T retrieveResourceFromResponse(final HttpResponse response, final Class<T> clazz) throws IOException {
|
||||
final String jsonFromResponse = EntityUtils.toString(response.getEntity());
|
||||
final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
return mapper.readValue(jsonFromResponse, clazz);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.spring;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan("com.baeldung.test")
|
||||
public class ConfigIntegrationTest implements WebMvcConfigurer {
|
||||
|
||||
public ConfigIntegrationTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package com.baeldung.springhateoas;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.hateoas.MediaTypes;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import com.baeldung.persistence.model.Customer;
|
||||
import com.baeldung.persistence.model.Order;
|
||||
import com.baeldung.services.CustomerService;
|
||||
import com.baeldung.services.OrderService;
|
||||
import com.baeldung.web.controller.CustomerController;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@WebMvcTest(CustomerController.class)
|
||||
public class CustomerControllerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mvc;
|
||||
|
||||
@MockBean
|
||||
private CustomerService customerService;
|
||||
|
||||
@MockBean
|
||||
private OrderService orderService;
|
||||
|
||||
private static final String DEFAULT_CUSTOMER_ID = "customer1";
|
||||
private static final String DEFAULT_ORDER_ID = "order1";
|
||||
|
||||
@Test
|
||||
public void givenExistingCustomer_whenCustomerRequested_thenResourceRetrieved() throws Exception {
|
||||
given(this.customerService.getCustomerDetail(DEFAULT_CUSTOMER_ID))
|
||||
.willReturn(new Customer(DEFAULT_CUSTOMER_ID, "customerJohn", "companyOne"));
|
||||
|
||||
this.mvc.perform(get("/customers/" + DEFAULT_CUSTOMER_ID))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links").doesNotExist())
|
||||
.andExpect(jsonPath("$.customerId", is(DEFAULT_CUSTOMER_ID)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExistingOrder_whenOrderRequested_thenResourceRetrieved() throws Exception {
|
||||
given(this.orderService.getOrderByIdForCustomer(DEFAULT_CUSTOMER_ID, DEFAULT_ORDER_ID))
|
||||
.willReturn(new Order(DEFAULT_ORDER_ID, 1., 1));
|
||||
|
||||
this.mvc.perform(get("/customers/" + DEFAULT_CUSTOMER_ID + "/" + DEFAULT_ORDER_ID))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._links").doesNotExist())
|
||||
.andExpect(jsonPath("$.orderId", is(DEFAULT_ORDER_ID)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExistingCustomerWithOrders_whenOrdersRequested_thenHalResourceRetrieved() throws Exception {
|
||||
Order order1 = new Order(DEFAULT_ORDER_ID, 1., 1);
|
||||
List<Order> orders = Collections.singletonList(order1);
|
||||
given(this.orderService.getAllOrdersForCustomer(DEFAULT_CUSTOMER_ID)).willReturn(orders);
|
||||
|
||||
this.mvc.perform(get("/customers/" + DEFAULT_CUSTOMER_ID + "/orders").accept(MediaTypes.HAL_JSON_VALUE))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.orders[0]._links.self.href",
|
||||
is("http://localhost/customers/customer1/order1")))
|
||||
.andExpect(jsonPath("$._links.self.href", is("http://localhost/customers/customer1/orders")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExistingCustomer_whenAllCustomersRequested_thenHalResourceRetrieved() throws Exception {
|
||||
// customers
|
||||
Customer retrievedCustomer = new Customer(DEFAULT_CUSTOMER_ID, "customerJohn", "companyOne");
|
||||
List<Customer> customers = Collections.singletonList(retrievedCustomer);
|
||||
given(this.customerService.allCustomers()).willReturn(customers);
|
||||
// orders
|
||||
Order order1 = new Order(DEFAULT_ORDER_ID, 1., 1);
|
||||
List<Order> orders = Collections.singletonList(order1);
|
||||
given(this.orderService.getAllOrdersForCustomer(DEFAULT_CUSTOMER_ID)).willReturn(orders);
|
||||
|
||||
this.mvc.perform(get("/customers/").accept(MediaTypes.HAL_JSON_VALUE))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(
|
||||
jsonPath("$._embedded.customers[0]._links.self.href", is("http://localhost/customers/customer1")))
|
||||
.andExpect(jsonPath("$._embedded.customers[0]._links.allOrders.href",
|
||||
is("http://localhost/customers/customer1/orders")))
|
||||
.andExpect(jsonPath("$._links.self.href", is("http://localhost/customers")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.springpagination;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
import org.junit.Test;
|
||||
import org.modelmapper.ModelMapper;
|
||||
|
||||
import com.baeldung.springpagination.dto.PostDto;
|
||||
import com.baeldung.springpagination.model.Post;
|
||||
|
||||
public class PostDtoUnitTest {
|
||||
|
||||
private ModelMapper modelMapper = new ModelMapper();
|
||||
|
||||
@Test
|
||||
public void whenConvertPostEntityToPostDto_thenCorrect() {
|
||||
Post post = new Post();
|
||||
post.setId(1L);
|
||||
post.setTitle(randomAlphabetic(6));
|
||||
post.setUrl("www.test.com");
|
||||
|
||||
PostDto postDto = modelMapper.map(post, PostDto.class);
|
||||
assertEquals(post.getId(), postDto.getId());
|
||||
assertEquals(post.getTitle(), postDto.getTitle());
|
||||
assertEquals(post.getUrl(), postDto.getUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertPostDtoToPostEntity_thenCorrect() {
|
||||
PostDto postDto = new PostDto();
|
||||
postDto.setId(1L);
|
||||
postDto.setTitle(randomAlphabetic(6));
|
||||
postDto.setUrl("www.test.com");
|
||||
|
||||
Post post = modelMapper.map(postDto, Post.class);
|
||||
assertEquals(postDto.getId(), post.getId());
|
||||
assertEquals(postDto.getTitle(), post.getTitle());
|
||||
assertEquals(postDto.getUrl(), post.getUrl());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IMarshaller {
|
||||
|
||||
<T> String encode(final T entity);
|
||||
|
||||
<T> T decode(final String entityAsString, final Class<T> clazz);
|
||||
|
||||
<T> List<T> decodeList(final String entitiesAsString, final Class<T> clazz);
|
||||
|
||||
String getMime();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.baeldung.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
public final class JacksonMarshaller implements IMarshaller {
|
||||
private final Logger logger = LoggerFactory.getLogger(JacksonMarshaller.class);
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public JacksonMarshaller() {
|
||||
super();
|
||||
|
||||
objectMapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@Override
|
||||
public final <T> String encode(final T resource) {
|
||||
Preconditions.checkNotNull(resource);
|
||||
String entityAsJSON = null;
|
||||
try {
|
||||
entityAsJSON = objectMapper.writeValueAsString(resource);
|
||||
} catch (final IOException ioEx) {
|
||||
logger.error("", ioEx);
|
||||
}
|
||||
|
||||
return entityAsJSON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> T decode(final String resourceAsString, final Class<T> clazz) {
|
||||
Preconditions.checkNotNull(resourceAsString);
|
||||
|
||||
T entity = null;
|
||||
try {
|
||||
entity = objectMapper.readValue(resourceAsString, clazz);
|
||||
} catch (final IOException ioEx) {
|
||||
logger.error("", ioEx);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final <T> List<T> decodeList(final String resourcesAsString, final Class<T> clazz) {
|
||||
Preconditions.checkNotNull(resourcesAsString);
|
||||
|
||||
List<T> entities = null;
|
||||
try {
|
||||
if (clazz.equals(Foo.class)) {
|
||||
entities = objectMapper.readValue(resourcesAsString, new TypeReference<List<Foo>>() {
|
||||
// ...
|
||||
});
|
||||
} else {
|
||||
entities = objectMapper.readValue(resourcesAsString, List.class);
|
||||
}
|
||||
} catch (final IOException ioEx) {
|
||||
logger.error("", ioEx);
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getMime() {
|
||||
return MediaType.APPLICATION_JSON.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.baeldung.test;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Profile("test")
|
||||
public class TestMarshallerFactory implements FactoryBean<IMarshaller> {
|
||||
|
||||
@Autowired
|
||||
private Environment env;
|
||||
|
||||
public TestMarshallerFactory() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@Override
|
||||
public IMarshaller getObject() {
|
||||
final String testMime = env.getProperty("test.mime");
|
||||
if (testMime != null) {
|
||||
switch (testMime) {
|
||||
case "json":
|
||||
return new JacksonMarshaller();
|
||||
case "xml":
|
||||
return new XStreamMarshaller();
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
return new JacksonMarshaller();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<IMarshaller> getObjectType() {
|
||||
return IMarshaller.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.baeldung.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
|
||||
public final class XStreamMarshaller implements IMarshaller {
|
||||
|
||||
private XStream xstream;
|
||||
|
||||
public XStreamMarshaller() {
|
||||
super();
|
||||
|
||||
xstream = new XStream();
|
||||
xstream.autodetectAnnotations(true);
|
||||
xstream.processAnnotations(Foo.class);
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@Override
|
||||
public final <T> String encode(final T resource) {
|
||||
Preconditions.checkNotNull(resource);
|
||||
return xstream.toXML(resource);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final <T> T decode(final String resourceAsString, final Class<T> clazz) {
|
||||
Preconditions.checkNotNull(resourceAsString);
|
||||
return (T) xstream.fromXML(resourceAsString);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> List<T> decodeList(final String resourcesAsString, final Class<T> clazz) {
|
||||
return this.decode(resourcesAsString, List.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getMime() {
|
||||
return MediaType.APPLICATION_XML.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
|
||||
/**
|
||||
*
|
||||
* We'll start the whole context, but not the server. We'll mock the REST calls instead.
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
public class FooControllerAppIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Test
|
||||
public void whenFindPaginatedRequest_thenEmptyResponse() throws Exception {
|
||||
this.mockMvc.perform(get("/foos").param("page", "0")
|
||||
.param("size", "2"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().json("[]"));
|
||||
}
|
||||
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc(addFilters = false)
|
||||
public class FooControllerCustomEtagIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mvc;
|
||||
|
||||
private String FOOS_ENDPOINT = "/foos/";
|
||||
private String CUSTOM_ETAG_ENDPOINT_SUFFIX = "/custom-etag";
|
||||
|
||||
private static String serializeFoo(Foo foo) throws Exception {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
return mapper.writeValueAsString(foo);
|
||||
}
|
||||
|
||||
private static String createFooJson() throws Exception {
|
||||
return serializeFoo(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
|
||||
private static Foo deserializeFoo(String fooJson) throws Exception {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
return mapper.readValue(fooJson, Foo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenResourceExists_whenRetrievingResourceUsingCustomEtagEndpoint_thenEtagIsAlsoReturned()
|
||||
throws Exception {
|
||||
// Given
|
||||
String createdResourceUri = this.mvc.perform(post(FOOS_ENDPOINT).contentType(MediaType.APPLICATION_JSON)
|
||||
.content(createFooJson()))
|
||||
.andExpect(status().isCreated())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getHeader(HttpHeaders.LOCATION);
|
||||
|
||||
// When
|
||||
ResultActions result = this.mvc
|
||||
.perform(get(createdResourceUri + CUSTOM_ETAG_ENDPOINT_SUFFIX).contentType(MediaType.APPLICATION_JSON));
|
||||
|
||||
// Then
|
||||
result.andExpect(status().isOk())
|
||||
.andExpect(header().string(HttpHeaders.ETAG, "\"0\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenResourceWasRetrieved_whenRetrievingAgainWithEtagUsingCustomEtagEndpoint_thenNotModifiedReturned() throws Exception {
|
||||
// Given
|
||||
String createdResourceUri = this.mvc.perform(post(FOOS_ENDPOINT).contentType(MediaType.APPLICATION_JSON)
|
||||
.content(createFooJson()))
|
||||
.andExpect(status().isCreated())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getHeader(HttpHeaders.LOCATION);
|
||||
ResultActions findOneResponse = this.mvc
|
||||
.perform(get(createdResourceUri + CUSTOM_ETAG_ENDPOINT_SUFFIX).contentType(MediaType.APPLICATION_JSON));
|
||||
String etag = findOneResponse.andReturn().getResponse().getHeader(HttpHeaders.ETAG);
|
||||
|
||||
// When
|
||||
ResultActions result = this.mvc
|
||||
.perform(get(createdResourceUri + CUSTOM_ETAG_ENDPOINT_SUFFIX).contentType(MediaType.APPLICATION_JSON).header(HttpHeaders.IF_NONE_MATCH, etag));
|
||||
|
||||
// Then
|
||||
result.andExpect(status().isNotModified());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenResourceWasRetrievedThenModified_whenRetrievingAgainWithEtagUsingCustomEtagEndpoint_thenResourceIsReturned() throws Exception {
|
||||
// Given
|
||||
String createdResourceUri = this.mvc.perform(post(FOOS_ENDPOINT).contentType(MediaType.APPLICATION_JSON)
|
||||
.content(createFooJson()))
|
||||
.andExpect(status().isCreated())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getHeader(HttpHeaders.LOCATION);
|
||||
ResultActions findOneResponse = this.mvc
|
||||
.perform(get(createdResourceUri + CUSTOM_ETAG_ENDPOINT_SUFFIX).contentType(MediaType.APPLICATION_JSON));
|
||||
String etag = findOneResponse.andReturn().getResponse().getHeader(HttpHeaders.ETAG);
|
||||
Foo createdFoo = deserializeFoo(findOneResponse.andReturn().getResponse().getContentAsString());
|
||||
createdFoo.setName("updated name");
|
||||
this.mvc
|
||||
.perform(put(createdResourceUri).contentType(MediaType.APPLICATION_JSON).content(serializeFoo(createdFoo)));
|
||||
|
||||
// When
|
||||
ResultActions result = this.mvc
|
||||
.perform(get(createdResourceUri + CUSTOM_ETAG_ENDPOINT_SUFFIX).contentType(MediaType.APPLICATION_JSON).header(HttpHeaders.IF_NONE_MATCH, etag));
|
||||
|
||||
// Then
|
||||
result.andExpect(status().isOk())
|
||||
.andExpect(header().string(HttpHeaders.ETAG, "\"1\""));
|
||||
}
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
import com.baeldung.persistence.service.IFooService;
|
||||
import com.baeldung.web.controller.FooController;
|
||||
import com.baeldung.web.hateoas.event.PaginatedResultsRetrievedEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* We'll start only the web layer.
|
||||
*
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@WebMvcTest(FooController.class)
|
||||
public class FooControllerWebLayerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
private IFooService service;
|
||||
|
||||
@MockBean
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
@Test()
|
||||
public void givenPresentFoo_whenFindPaginatedRequest_thenPageWithFooRetrieved() throws Exception {
|
||||
Page<Foo> page = new PageImpl<>(Collections.singletonList(new Foo("fooName")));
|
||||
when(service.findPaginated(0, 2)).thenReturn(page);
|
||||
doNothing().when(publisher)
|
||||
.publishEvent(any(PaginatedResultsRetrievedEvent.class));
|
||||
|
||||
this.mockMvc.perform(get("/foos").param("page", "0")
|
||||
.param("size", "2"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$",Matchers.hasSize(1)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
|
||||
import com.baeldung.common.web.AbstractDiscoverabilityLiveTest;
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
import com.baeldung.spring.ConfigIntegrationTest;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { ConfigIntegrationTest.class }, loader = AnnotationConfigContextLoader.class)
|
||||
@ActiveProfiles("test")
|
||||
public class FooDiscoverabilityLiveTest extends AbstractDiscoverabilityLiveTest<Foo> {
|
||||
|
||||
public FooDiscoverabilityLiveTest() {
|
||||
super(Foo.class);
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@Override
|
||||
public final void create() {
|
||||
create(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String createAsUri() {
|
||||
return createAsUri(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import com.baeldung.common.web.AbstractBasicLiveTest;
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
import com.baeldung.spring.ConfigIntegrationTest;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { ConfigIntegrationTest.class }, loader = AnnotationConfigContextLoader.class)
|
||||
@ActiveProfiles("test")
|
||||
public class FooLiveTest extends AbstractBasicLiveTest<Foo> {
|
||||
|
||||
public FooLiveTest() {
|
||||
super(Foo.class);
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@Override
|
||||
public final void create() {
|
||||
create(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String createAsUri() {
|
||||
return createAsUri(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import static com.baeldung.Consts.APPLICATION_PORT;
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import com.baeldung.common.web.AbstractBasicLiveTest;
|
||||
import com.baeldung.persistence.model.Foo;
|
||||
import com.baeldung.spring.ConfigIntegrationTest;
|
||||
|
||||
import io.restassured.RestAssured;
|
||||
import io.restassured.response.Response;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = { ConfigIntegrationTest.class }, loader = AnnotationConfigContextLoader.class)
|
||||
@ActiveProfiles("test")
|
||||
public class FooPageableLiveTest extends AbstractBasicLiveTest<Foo> {
|
||||
|
||||
public FooPageableLiveTest() {
|
||||
super(Foo.class);
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@Override
|
||||
public final void create() {
|
||||
super.create(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String createAsUri() {
|
||||
return createAsUri(new Foo(randomAlphabetic(6)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void whenResourcesAreRetrievedPaged_then200IsReceived() {
|
||||
this.create();
|
||||
|
||||
final Response response = RestAssured.get(getPageableURL() + "?page=0&size=10");
|
||||
|
||||
assertThat(response.getStatusCode(), is(200));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void whenPageOfResourcesAreRetrievedOutOfBounds_then404IsReceived() {
|
||||
final String url = getPageableURL() + "?page=" + randomNumeric(5) + "&size=10";
|
||||
final Response response = RestAssured.get(url);
|
||||
|
||||
assertThat(response.getStatusCode(), is(404));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void givenResourcesExist_whenFirstPageIsRetrieved_thenPageContainsResources() {
|
||||
create();
|
||||
|
||||
final Response response = RestAssured.get(getPageableURL() + "?page=0&size=10");
|
||||
|
||||
assertFalse(response.body().as(List.class).isEmpty());
|
||||
}
|
||||
|
||||
protected String getPageableURL() {
|
||||
return "http://localhost:" + APPLICATION_PORT + "/spring-boot-rest/foos/pageable";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import com.baeldung.web.FooDiscoverabilityLiveTest;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({
|
||||
// @formatter:off
|
||||
FooDiscoverabilityLiveTest.class,
|
||||
FooLiveTest.class,
|
||||
FooPageableLiveTest.class
|
||||
}) //
|
||||
public class LiveTestSuiteLiveTest {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.web.server.MediaTypeNotSupportedStatusException;
|
||||
|
||||
import com.baeldung.web.controller.students.Student;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
public class StudentControllerIntegrationTest {
|
||||
|
||||
private static final String STUDENTS_PATH = "/students/";
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Test
|
||||
public void whenReadAll_thenStatusIsOk() throws Exception {
|
||||
this.mockMvc.perform(get(STUDENTS_PATH))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadOne_thenStatusIsOk() throws Exception {
|
||||
this.mockMvc.perform(get(STUDENTS_PATH + 1))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCreate_thenStatusIsCreated() throws Exception {
|
||||
Student student = new Student(10, "Albert", "Einstein");
|
||||
this.mockMvc.perform(post(STUDENTS_PATH).content(asJsonString(student))
|
||||
.contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||
.andExpect(status().isCreated());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUpdate_thenStatusIsOk() throws Exception {
|
||||
Student student = new Student(1, "Nikola", "Tesla");
|
||||
this.mockMvc.perform(put(STUDENTS_PATH + 1)
|
||||
.content(asJsonString(student))
|
||||
.contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDelete_thenStatusIsNoContent() throws Exception {
|
||||
this.mockMvc.perform(delete(STUDENTS_PATH + 3))
|
||||
.andExpect(status().isNoContent());
|
||||
}
|
||||
|
||||
private String asJsonString(final Object obj) {
|
||||
try {
|
||||
return new ObjectMapper().writeValueAsString(obj);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.baeldung.web.error;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.hasKey;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.isA;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static com.baeldung.Consts.APPLICATION_PORT;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
|
||||
public class ErrorHandlingLiveTest {
|
||||
|
||||
private static final String BASE_URL = "http://localhost:" + APPLICATION_PORT + "/spring-boot-rest";
|
||||
private static final String EXCEPTION_ENDPOINT = BASE_URL + "/exception";
|
||||
|
||||
private static final String ERROR_RESPONSE_KEY_PATH = "error";
|
||||
private static final String XML_RESPONSE_KEY_PATH = "xmlkey";
|
||||
private static final String LOCALE_RESPONSE_KEY_PATH = "locale";
|
||||
private static final String CAUSE_RESPONSE_KEY_PATH = "cause";
|
||||
private static final String RESPONSE_XML_ROOT = "Map";
|
||||
private static final String XML_RESPONSE_KEY_XML_PATH = RESPONSE_XML_ROOT + "." + XML_RESPONSE_KEY_PATH;
|
||||
private static final String LOCALE_RESPONSE_KEY_XML_PATH = RESPONSE_XML_ROOT + "." + LOCALE_RESPONSE_KEY_PATH;
|
||||
private static final String CAUSE_RESPONSE_KEY_XML_PATH = RESPONSE_XML_ROOT + "." + CAUSE_RESPONSE_KEY_PATH;
|
||||
private static final String CAUSE_RESPONSE_VALUE = "Error in the faulty controller!";
|
||||
private static final String XML_RESPONSE_VALUE = "the XML response is different!";
|
||||
|
||||
@Test
|
||||
public void whenRequestingFaultyEndpointAsJson_thenReceiveDefaultResponseWithConfiguredAttrs() {
|
||||
given().header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
|
||||
.get(EXCEPTION_ENDPOINT)
|
||||
.then()
|
||||
.body("$", hasKey(LOCALE_RESPONSE_KEY_PATH))
|
||||
.body(CAUSE_RESPONSE_KEY_PATH, is(CAUSE_RESPONSE_VALUE))
|
||||
.body("$", not(hasKey(ERROR_RESPONSE_KEY_PATH)))
|
||||
.body("$", not(hasKey(XML_RESPONSE_KEY_PATH)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRequestingFaultyEndpointAsXml_thenReceiveXmlResponseWithConfiguredAttrs() {
|
||||
given().header(HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_VALUE)
|
||||
.get(EXCEPTION_ENDPOINT)
|
||||
.then()
|
||||
.body(LOCALE_RESPONSE_KEY_XML_PATH, isA(String.class))
|
||||
.body(CAUSE_RESPONSE_KEY_XML_PATH, is(CAUSE_RESPONSE_VALUE))
|
||||
.body(RESPONSE_XML_ROOT, not(hasKey(ERROR_RESPONSE_KEY_PATH)))
|
||||
.body(XML_RESPONSE_KEY_XML_PATH, is(XML_RESPONSE_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRequestingFaultyEndpointAsHtml_thenReceiveWhitelabelPageResponse() throws Exception {
|
||||
try (WebClient webClient = new WebClient()) {
|
||||
webClient.getOptions()
|
||||
.setThrowExceptionOnFailingStatusCode(false);
|
||||
HtmlPage page = webClient.getPage(EXCEPTION_ENDPOINT);
|
||||
assertThat(page.getBody()
|
||||
.asText()).contains("Whitelabel Error Page");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.web.util;
|
||||
|
||||
public final class HTTPLinkHeaderUtil {
|
||||
|
||||
private HTTPLinkHeaderUtil() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public static String extractURIByRel(final String linkHeader, final String rel) {
|
||||
if (linkHeader == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String uriWithSpecifiedRel = null;
|
||||
final String[] links = linkHeader.split(", ");
|
||||
String linkRelation;
|
||||
for (final String link : links) {
|
||||
final int positionOfSeparator = link.indexOf(';');
|
||||
linkRelation = link.substring(positionOfSeparator + 1, link.length()).trim();
|
||||
if (extractTypeOfRelation(linkRelation).equals(rel)) {
|
||||
uriWithSpecifiedRel = link.substring(1, positionOfSeparator - 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return uriWithSpecifiedRel;
|
||||
}
|
||||
|
||||
private static Object extractTypeOfRelation(final String linkRelation) {
|
||||
final int positionOfEquals = linkRelation.indexOf('=');
|
||||
return linkRelation.substring(positionOfEquals + 2, linkRelation.length() - 1).trim();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user