/atlassian-plugins-webresource-common/src/test/java/com/atlassian/plugin/servlet/cache/filter/ETagCachingFilterTest.java
Java | 134 lines | 87 code | 18 blank | 29 comment | 0 complexity | 727f8f00dea3204f5c1f92d9dbc759e5 MD5 | raw file
- package com.atlassian.plugin.servlet.cache.filter;
- import com.atlassian.plugin.servlet.cache.model.CacheableResponse;
- import com.atlassian.plugin.servlet.cache.model.ETagToken;
- import org.junit.Test;
- import javax.servlet.*;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.nio.charset.StandardCharsets;
- import java.util.Optional;
- import java.util.function.Consumer;
- import static com.atlassian.plugin.servlet.util.function.FailableConsumer.wrapper;
- import static com.google.common.net.HttpHeaders.IF_NONE_MATCH;
- import static java.lang.Void.TYPE;
- import static java.util.Arrays.stream;
- import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED;
- import static org.mockito.Mockito.*;
- public class ETagCachingFilterTest {
- /**
- * Representation of a real URI used to serve a batch javascript file.
- */
- private static final String BATCH_JS_FILE_URL = new StringBuilder("https://localhost:8080")
- .append("/s/27a5fa98bce4cd77093c8b11702e0c82-CDN/-airmqf/814000/cb046e2294e854f76e4eff70d7d3d5ce/02192afb1120393751ce10f9f002f180")
- .append("/_/download/contextbatch/js/_super/batch.js")
- .toString();
- /**
- * WHEN If-None-Match matches the ETag generated from a Response body.
- * THEN set the ETag header with the current ETag and set Http Status code to 304.
- * AND an empty response body.
- */
- @Test
- public void testWhenIfNoneMatchHeaderMatchesETag_shouldNotSetResponseBodyAndNotModifiedStatusCode() throws IOException, ServletException {
- final String ifNoneMatchHeader = "ceb57c850c288bc938f074693631a2dc"; // Hash representation of the following responseContentBody.
- final String responseContentBody = "<script>console.log('Hello World!')</script>";
- final Consumer<HttpServletResponse> verifier = wrapper((response) -> {
- verify(response.getOutputStream(), never()).flush();
- verify(response.getOutputStream(), never()).write(responseContentBody.getBytes());
- verify(response, never()).setContentLength(responseContentBody.length());
- verify(response, times(1)).setStatus(SC_NOT_MODIFIED);
- });
- test(ifNoneMatchHeader, responseContentBody, verifier);
- }
- /**
- * WHEN If-None-Match does not match the ETag generated from a response body.
- * THEN set the ETag header with the current ETag.
- * AND set the response body with the current content.
- */
- @Test
- public void testWhenIfNoneMatchHeaderDoesNotMatchETag_shouldSetResponseBody() throws IOException, ServletException {
- final String ifNoneMatchHeader = "ceb57c850c288bc938f074693631a2d4"; // Hash that does not represents the following responseContentBody.
- final String responseContentBody = "<script>console.log('Hello Universe!')</script>";
- final Consumer<HttpServletResponse> verifier = wrapper((httpServletResponse) -> {
- verify(httpServletResponse, times(1)).setContentLength(responseContentBody.length());
- verify(httpServletResponse.getOutputStream(), times(1)).write(responseContentBody.getBytes());
- verify(httpServletResponse.getOutputStream(), times(1)).flush();
- });
- test(ifNoneMatchHeader, responseContentBody, verifier);
- }
- /**
- * WHEN If-None-Match is null.
- * THEN set the ETag header with the current ETag.
- * AND set the response body with the current content.
- */
- @Test
- public void testWhenThereIsNotAnyIfNoneMatchHeader_shouldSetResponseBody() throws IOException, ServletException {
- final String ifNoneMatchHeader = null;
- final String responseContentBody = "<script>console.log('Hello World!')</script>";
- final Consumer<HttpServletResponse> verifier = wrapper((response) -> {
- verify(response, times(1)).setContentLength(responseContentBody.length());
- verify(response.getOutputStream(), times(1)).write(responseContentBody.getBytes());
- verify(response.getOutputStream(), times(1)).flush();
- });
- test(ifNoneMatchHeader, responseContentBody, verifier);
- }
- private void test(final String ifNoneMatchHeader,
- final String responseContentBody,
- final Consumer<HttpServletResponse> verifier) throws IOException, ServletException {
- //given
- final HttpServletRequest request = mock(HttpServletRequest.class);
- when(request.getHeader(IF_NONE_MATCH)).thenReturn(ifNoneMatchHeader);
- when(request.getRequestURI()).thenReturn(BATCH_JS_FILE_URL);
- final HttpServletResponse response = mock(HttpServletResponse.class);
- final ServletOutputStream responseBodyOutputStream = mock(ServletOutputStream.class);
- when(response.getOutputStream()).thenReturn(responseBodyOutputStream);
- final FilterChain filterChain = mockFilterChain(responseContentBody);
- //when
- new ETagCachingFilter().doFilter(request, response, filterChain);
- //then
- verifier.accept(response);
- }
- /**
- * <p>Generates a mock of {@link FilterChain} which will modify the content body of a {@link CacheableResponse}
- * to have its value as the response content body when {@link FilterChain#doFilter(ServletRequest, ServletResponse)} is called.
- *
- * @return The mocked version of a {@link FilterChain}.
- * @throws IOException Error while writing to the response output stream.
- * @throws ServletException Error while performing the filtering.
- */
- private FilterChain mockFilterChain(final String responseContentBody) throws IOException, ServletException {
- final FilterChain filterChain = mock(FilterChain.class);
- doAnswer(invocation -> {
- final Optional<CacheableResponse> possibleCacheableResponse = stream(invocation.getArguments())
- .filter(argument -> argument instanceof CacheableResponse)
- .map(argument -> (CacheableResponse) argument)
- .findAny();
- possibleCacheableResponse
- .ifPresent(wrapper((cacheableResponse) -> cacheableResponse
- .getOutputStream()
- .write(responseContentBody.getBytes())));
- return TYPE;
- })
- .when(filterChain)
- .doFilter(any(ServletRequest.class), any(ServletResponse.class));
- return filterChain;
- }
- }