/*
* Copyright (C) 2014 Civilian Framework.
*
* Licensed under the Civilian License (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.civilian-framework.org/license.txt
*
* 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 org.civilian.resource;
import org.junit.Test;
import org.civilian.CivTest;
import org.civilian.response.UriEncoder;
public class RouteTest extends CivTest
{
public static final PathParam<String> PATTERN1 = PathParams.forSegment("p1");
public static final PathParam<String> PATTERN2 = PathParams.forSegment("p2");
public static final PathParam<String> PATTERN3 = PathParams.forSegment("p3");
public static final UriEncoder ENCODER = new UriEncoder();
/**
* Test create methods.
*/
@Test public void testCreate()
{
// Route.root()
assertCreate("/", RootRoute.class, Route.root());
// Route.path()
assertCreate("/", RootRoute.class, Route.constant(null));
assertCreate("/", RootRoute.class, Route.constant(""));
assertCreate("/", RootRoute.class, Route.constant("/"));
assertCreate("/abc", ConstantRoute.class, Route.constant("/abc"));
assertCreate("abc", ConstantRoute.class, Route.constant("abc"));
assertCreate("/abc", ConstantRoute.class, Route.constant("/abc"));
assertCreate("http:x", ConstantRoute.class, Route.constant("http:x"));
assertCreate("http:x/", ConstantRoute.class, Route.constant("http:x/"));
}
/**
* Test properties of root route.
*/
@Test public void testRootRoute()
{
Route route = Route.root();
assertEquals("/", route.build(null, ENCODER));
assertTrue(route.isRoot());
assertEquals(1, route.size());
assertEquals(0, route.getPathParamCount());
assertEquals(null, route.getPathParam(0));
assertEquals(-1, route.indexOf(PATTERN1));
// can be invoked without failure and side-effects
route.extractPathParams(null, null);
assertSame(route, route.add((String)null));
assertSame(route, route.add(""));
assertSame(route, route.add("/"));
Route route2 = route.add("def");
assertNotSame(route2, route);
assertEquals("/def", route2.build(null, ENCODER));
}
/**
* Test properties of constant routes.
*/
@Test public void testConstantRoute()
{
Route route = assertCreate("/abc", ConstantRoute.class, Route.constant("/abc"));
assertEquals("/abc", route.build(null, ENCODER));
assertFalse(route.isRoot());
assertEquals(1, route.size());
assertEquals(0, route.getPathParamCount());
assertEquals(null, route.getPathParam(0));
assertEquals(-1, route.indexOf(PATTERN1));
// can be invoked without failure and side-effects
route.extractPathParams(null, null);
assertSame(route, route.add((String)null));
assertSame(route, route.add(""));
assertSame(route, route.add("/"));
Route route2 = route.add("def");
assertNotSame(route2, route);
assertEquals("/abc/def", route2.build(null, ENCODER));
assertCreate("/abc/{p1}", RouteList.class, route.add(PATTERN1));
route = assertCreate("http://www.test.com/", ConstantRoute.class, Route.constant("http://www.test.com/"));
route2 = route.add("/def");
assertNotSame(route2, route);
assertEquals("http://www.test.com/def", route2.build(null, ENCODER));
assertTrue(route2 instanceof ConstantRoute);
}
/**
* Test Urls that start with an arbitrary prefix.
*/
public void testUrlConstantRoutes()
{
Route url1 = Route.constant("http://test.com");
Route url2 = Route.constant("http://test.com/");
assertEquals("http://test.com", url1.build(null, ENCODER));
assertEquals("http://test.com/", url1.build(null, ENCODER));
assertEquals("http://test.com/customers", url1.add("/customers").build(null, ENCODER));
assertEquals("http://test.com/customers/", url1.add("/customers/").build(null, ENCODER));
assertEquals("http://test.com/customers", url2.add("/customers").build(null, ENCODER));
assertEquals("http://test.com/customers/", url2.add("/customers/").build(null, ENCODER));
Object[] params = new Object[] { "pp" };
assertEquals("http://test.com/pp", url1.add(PATTERN1).build(params, ENCODER));
assertEquals("http://test.com/pp", url2.add(PATTERN1).build(params, ENCODER));
}
/**
* Test Route.toString when the passed string builder is not empty.
* (as done by Url)
*/
public void testUrlBuild()
{
StringBuilder s = new StringBuilder("http://test.com/");
Route.constant("/customers/").build(null, ENCODER);
assertEquals("http://test.com/customers/", s.toString());
Object[] params = new Object[] { "pp" };
Route.root().add(PATTERN1).build(params, ENCODER);
assertEquals("http://test.com/pp", s.toString());
}
/**
* Test properties of pattern routes.
*/
@Test public void testPatternRoute()
{
Route route = assertCreate("/{p1}", PathParamRoute.class, Route.root().add(PATTERN1));
assertEquals(1, route.size());
assertFalse(route.isRoot());
// build fails if path param not set
Object[] params = new Object[1];
try
{
assertEquals("ignore", route.build(params, ENCODER));
fail();
}
catch(IllegalStateException e)
{
}
// build fails if path param has wrong value
try
{
params[0] = Boolean.TRUE; // String is expected
assertEquals("ignore", route.build(params, ENCODER));
fail();
}
catch(IllegalArgumentException e)
{
}
params[0] = "www";
assertEquals("/www", route.build(params, ENCODER));
assertEquals(1, route.getPathParamCount());
assertEquals(PATTERN1, route.getPathParam(0));
assertEquals(null, route.getPathParam(1));
assertEquals(0, route.indexOf(PATTERN1));
assertEquals(-1, route.indexOf(PATTERN2));
assertSame(route, route.add((String)null));
assertSame(route, route.add(""));
assertSame(route, route.add("/"));
}
/**
* Test properties of route lists.
*/
@Test public void testRouteList()
{
Route route = assertCreate("/{p1}/x/{p2}", RouteList.class, Route.root().add(PATTERN1).add("x").add(PATTERN2));
Object[] params = new Object[2];
params[0] = "www";
params[1] = "yyy";
assertFalse(route.isRoot());
assertEquals(3, route.size());
assertEquals("/www/x/yyy", route.build(params, ENCODER));
assertEquals(2, route.getPathParamCount());
assertEquals(PATTERN1, route.getPathParam(0));
assertEquals(PATTERN2, route.getPathParam(1));
assertEquals(null, route.getPathParam(2));
assertEquals(0, route.indexOf(PATTERN1));
assertEquals(1, route.indexOf(PATTERN2));
assertEquals(-1, route.indexOf(PATTERN3));
assertSame(route, route.add((String)null));
route = route.add("y");
assertEquals(4, route.size());
assertEquals("/{p1}/x/{p2}/y", route.toString());
// test append of
route = assertCreate("/{p1}/x", RouteList.class, Route.root().add(PATTERN1).add("x"));
assertEquals(2, route.size());
route = route.add("y");
assertEquals(2, route.size());
assertEquals("/{p1}/x/y", route.toString());
}
/**
* Make sure that patterns are properly escaped.
*/
@Test public void testPatternEscaping()
{
Route route = assertCreate("/{p1}/x", RouteList.class, Route.root().add(PATTERN1).add("x"));
Object[] params = new Object[1];
params[0] = "%/ ";
assertEquals("/%25%2F%20/x", route.build(params, ENCODER));
}
private Route assertCreate(Class<? extends Route> c, Route route)
{
assertEquals(c, route.getClass());
return route;
}
@SuppressWarnings("unchecked")
private <T extends Route> T assertCreate(String s, Class<T> c, Route route)
{
assertCreate(c, route);
assertEquals(s, route.toString());
return (T)route;
}
}