/**
* Copyright (C) 2012-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ninja.utils;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Optional;
import ninja.Context;
import ninja.Result;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class HttpCacheToolkitImplTest {
@Mock
NinjaProperties ninjaProperties;
@Mock
Result result;
@Mock
Context context;
@Test
public void testIsModified() {
HttpCacheToolkit httpCacheToolkit = new HttpCacheToolkitImpl(
ninjaProperties);
// test etag support:
when(context.getHeader(HttpHeaderConstants.IF_NONE_MATCH)).thenReturn(
"etag_xyz");
// same etag => not modified
assertFalse(httpCacheToolkit.isModified(Optional.of("etag_xyz"), Optional.of(0L), context));
// new etag => modified
assertTrue(httpCacheToolkit
.isModified(Optional.of("etag_xyz_modified"), Optional.of(0L), context));
// remove etag to test modified timestamp caching:
when(context.getHeader(HttpHeaderConstants.IF_NONE_MATCH)).thenReturn(
null);
// => no if modified since request => null
when(context.getHeader(HttpHeaderConstants.IF_MODIFIED_SINCE))
.thenReturn(null);
assertTrue(httpCacheToolkit
.isModified(Optional.of("etag_xyz_modified"), Optional.of(0L), context));
// => older timestamp => modified
when(context.getHeader(HttpHeaderConstants.IF_MODIFIED_SINCE))
.thenReturn("Thu, 01 Jan 1970 00:00:00 GMT");
assertTrue(httpCacheToolkit.isModified(Optional.of("etag_xyz_modified"), Optional.of(1000L),
context));
// => same timestamp => not modified
when(context.getHeader(HttpHeaderConstants.IF_MODIFIED_SINCE))
.thenReturn("Thu, 01 Jan 1970 00:00:00 GMT");
assertFalse(httpCacheToolkit.isModified(Optional.of("etag_xyz_modified"), Optional.of(0L),
context));
// => newer timestamp => not modified
when(context.getHeader(HttpHeaderConstants.IF_MODIFIED_SINCE))
.thenReturn("Thu, 01 Jan 1971 00:00:00 GMT");
assertFalse(httpCacheToolkit.isModified(Optional.of("etag_xyz_modified"), Optional.of(0L),
context));
// => strange timestamp => modified
when(context.getHeader(HttpHeaderConstants.IF_MODIFIED_SINCE))
.thenReturn("STRANGE_TIMESTAMP");
assertTrue(httpCacheToolkit
.isModified(Optional.of("etag_xyz_modified"), Optional.of(0L), context));
}
@Test
public void testAddETag() {
HttpCacheToolkit httpCacheToolkit = new HttpCacheToolkitImpl(
ninjaProperties);
////////////////////////////////////////////////
// test Cache-Control header
////////////////////////////////////////////////
// check Cache header:
// if not in production => no cache:
when(ninjaProperties.isProd()).thenReturn(false);
httpCacheToolkit.addEtag(context, result, 0L);
verify(result).addHeader(HttpHeaderConstants.CACHE_CONTROL, "no-cache");
// in production => make sure cache header is set accordingly:
when(ninjaProperties.isProd()).thenReturn(true);
// set regular header with request to http cache control constant:
reset(result);
when(
ninjaProperties.getWithDefault(
NinjaConstant.HTTP_CACHE_CONTROL,
NinjaConstant.HTTP_CACHE_CONTROL_DEFAULT)).thenReturn(
"1234");
httpCacheToolkit.addEtag(context, result, 0L);
verify(result).addHeader(HttpHeaderConstants.CACHE_CONTROL,
"max-age=1234");
// if cache time = 0 => set to no-cache:
reset(result);
when(
ninjaProperties.getWithDefault(
NinjaConstant.HTTP_CACHE_CONTROL,
NinjaConstant.HTTP_CACHE_CONTROL_DEFAULT)).thenReturn(
"0");
httpCacheToolkit.addEtag(context, result, 0L);
verify(result).addHeader(HttpHeaderConstants.CACHE_CONTROL, "no-cache");
////////////////////////////////////////////////
// Test Add etag header
////////////////////////////////////////////////
// do not add etag when not configured:
reset(result);
when(ninjaProperties.getBooleanWithDefault(
NinjaConstant.HTTP_USE_ETAG,
NinjaConstant.HTTP_USE_ETAG_DEFAULT)).thenReturn(
false);
httpCacheToolkit.addEtag(context, result, 0L);
// not in prod => no-cache
verify(result).addHeader(HttpHeaderConstants.CACHE_CONTROL, "no-cache");
// IMPORTANT: etag not added
verify(result, never()).addHeader(HttpHeaderConstants.ETAG, eq(anyString()));
// add etag when configured:
reset(result);
when(ninjaProperties.getBooleanWithDefault(
NinjaConstant.HTTP_USE_ETAG,
NinjaConstant.HTTP_USE_ETAG_DEFAULT)).thenReturn(
true);
httpCacheToolkit.addEtag(context, result, 1234L);
// not in prod => no-cache
verify(result).addHeader(HttpHeaderConstants.CACHE_CONTROL, "no-cache");
// IMPORTANT: etag added
verify(result).addHeader(HttpHeaderConstants.ETAG, "\"1234\"");
////////////////////////////////////////////////
// Test isModified 304 setting in result
////////////////////////////////////////////////
// test lastmodified is added when etags match:
when(context.getMethod()).thenReturn("GET");
when(context.getHeader(HttpHeaderConstants.IF_NONE_MATCH)).thenReturn("\"1234\"");
reset(result);
httpCacheToolkit.addEtag(context, result, 1234L);
verify(result).status(Result.SC_304_NOT_MODIFIED);
// test lastmodified not added when stuff does not match
// => but Last-Modified header is added
when(context.getMethod()).thenReturn("GET");
when(context.getHeader(HttpHeaderConstants.IF_NONE_MATCH)).thenReturn("\"12___34\"");
reset(result);
httpCacheToolkit.addEtag(context, result, 1234L);
verify(result, never()).status(Result.SC_304_NOT_MODIFIED);
verify(result).addHeader(HttpHeaderConstants.LAST_MODIFIED,
DateUtil.formatForHttpHeader(1234L));
}
}