/*
* Copyright (c) 2014 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 io.werval.test.cache;
import io.werval.api.cache.Cache;
import io.werval.api.http.Request;
import io.werval.api.outcomes.Outcome;
import io.werval.filters.Cached;
import io.werval.runtime.routes.RoutesParserProvider;
import io.werval.runtime.routes.RoutesProvider;
import io.werval.test.WervalTest;
import org.junit.Test;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static io.werval.api.context.CurrentContext.outcomes;
import static io.werval.api.http.Headers.Names.ETAG;
import static io.werval.api.http.Headers.Names.IF_NONE_MATCH;
import static io.werval.api.http.Method.GET;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* Cache Test.
* <p>
* Assert that a Cache Plugin and the @{@link Cached} annotation work as expected.
* <p>
* Extends in your Cache Plugin implementations to test it easily.
*
* @navassoc 1 test * Cache
*/
public abstract class CacheTest
extends WervalTest
{
/**
* Controller.
*/
public static class Controller
{
private static int hits = 0;
@Cached
public Outcome cached()
{
hits++;
return outcomes().ok( "CACHED" ).build();
}
}
private static final String FOO = "foo";
private static final String BAR = "bar";
@Override
protected RoutesProvider routesProvider()
{
return new RoutesParserProvider( "GET /cached io.werval.test.cache.CacheTest$Controller.cached" );
}
@Test
public void cachedControllerMethod()
{
Controller.hits = 0;
Request request = newRequestBuilder().method( GET ).uri( "/cached" ).build();
// Request
assertThat(
application().handleRequest( request ).join().responseHeader().status().code(),
is( 200 )
);
assertThat( Controller.hits, is( 1 ) );
// Assert Server-Side Cache
Outcome outcome = application().handleRequest( request ).join();
assertThat(
outcome.responseHeader().status().code(),
is( 200 )
);
assertThat( Controller.hits, is( 1 ) );
// Assert Client-Side Cache
request = newRequestBuilder().method( GET ).uri( "/cached" ).headers(
singletonMap( IF_NONE_MATCH, singletonList( outcome.responseHeader().headers().singleValue( ETAG ) ) )
).build();
assertThat(
application().handleRequest( request ).join().responseHeader().status().code(),
is( 304 )
);
assertThat( Controller.hits, is( 1 ) );
}
@Test
public void hasSetHasGetRemoveHas()
{
Cache cache = application().cache();
assertFalse( cache.has( FOO ) );
cache.set( FOO, BAR );
assertTrue( cache.has( FOO ) );
assertThat( cache.get( FOO ), equalTo( BAR ) );
cache.remove( FOO );
assertFalse( cache.has( FOO ) );
}
@Test
public void getOptional()
{
Cache cache = application().cache();
assertFalse( cache.getOptional( FOO ).isPresent() );
cache.set( FOO, BAR );
assertTrue( cache.getOptional( FOO ).isPresent() );
assertThat( cache.getOptional( FOO ).get(), equalTo( BAR ) );
cache.remove( FOO );
assertFalse( cache.getOptional( FOO ).isPresent() );
}
@Test
public void getOrSetDefault()
{
Cache cache = application().cache();
assertFalse( cache.has( FOO ) );
assertThat( cache.getOrSetDefault( FOO, BAR ), equalTo( BAR ) );
assertTrue( cache.has( FOO ) );
cache.set( FOO, "bazar" );
assertThat( cache.getOrSetDefault( FOO, BAR ), equalTo( "bazar" ) );
}
@Test
public void setTimeToLive()
throws InterruptedException
{
Cache cache = application().cache();
assertFalse( cache.has( FOO ) );
cache.set( 1, FOO, BAR );
assertThat( cache.get( FOO ), equalTo( BAR ) );
Thread.sleep( 1100 );
assertFalse( cache.has( FOO ) );
}
@Test
public void getOrSetDefaultTimeToLive()
throws InterruptedException
{
Cache cache = application().cache();
assertFalse( cache.has( FOO ) );
assertThat( cache.getOrSetDefault( FOO, 1, BAR ), equalTo( BAR ) );
Thread.sleep( 1100 );
assertFalse( cache.has( FOO ) );
cache.set( 1, FOO, "bazar" );
assertThat( cache.getOrSetDefault( FOO, 1, BAR ), equalTo( "bazar" ) );
Thread.sleep( 1100 );
assertThat( cache.getOrSetDefault( FOO, BAR ), equalTo( BAR ) );
}
@Test
public void setTimeToLiveZero()
throws InterruptedException
{
Cache cache = application().cache();
assertFalse( cache.has( FOO ) );
cache.set( 0, FOO, BAR );
assertThat( cache.get( FOO ), equalTo( BAR ) );
Thread.sleep( 1100 );
assertTrue( cache.has( FOO ) );
}
@Test
public void getOrSetDefaultTimeToZero()
throws InterruptedException
{
Cache cache = application().cache();
assertFalse( cache.has( FOO ) );
assertThat( cache.getOrSetDefault( FOO, 0, BAR ), equalTo( BAR ) );
Thread.sleep( 1100 );
assertTrue( cache.has( FOO ) );
cache.set( 0, FOO, "bazar" );
assertThat( cache.getOrSetDefault( FOO, 0, BAR ), equalTo( "bazar" ) );
Thread.sleep( 1100 );
assertThat( cache.get( FOO ), equalTo( "bazar" ) );
}
@Test
public void removeAbsent()
{
Cache cache = application().cache();
assertFalse( cache.has( FOO ) );
cache.remove( FOO );
}
}