[BAEL-11597] Move and update Etags article

* Moved etags article related code
* Fixed existing etag Ignored test
* Added etag scentsio adding etag support to a single endpoint
* Added tests for single endpoint etag scenario
* Cleaned now unused code in spring-rest-full module
This commit is contained in:
Ger Roza
2019-02-23 14:49:01 -03:00
parent 23eecb7cb1
commit 52b164ffca
18 changed files with 256 additions and 255 deletions
@@ -1,21 +1,28 @@
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> {
@@ -97,7 +104,82 @@ public abstract class AbstractBasicLiveTest<T extends Serializable> extends Abst
final String uriToNextPage = extractURIByRel(response.getHeader(HttpHeaders.LINK), "next");
assertNull(uriToNextPage);
}
// etags
// count
@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);
}
}
@@ -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 = "/auth/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\""));
}
}
@@ -8,8 +8,8 @@ import org.junit.runners.Suite;
@Suite.SuiteClasses({
// @formatter:off
FooDiscoverabilityLiveTest.class,
FooLiveTest.class
,FooPageableLiveTest.class
FooLiveTest.class,
FooPageableLiveTest.class
}) //
public class LiveTestSuiteLiveTest {