/*
* 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 ro.pippo.core;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import ro.pippo.core.route.DefaultRouter;
import ro.pippo.core.route.Route;
import ro.pippo.core.route.RouteGroup;
import ro.pippo.core.route.RouteHandler;
import ro.pippo.core.route.RouteMatch;
import ro.pippo.core.route.WebjarsResourceHandler;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.*;
/**
* @author Decebal Suiu
*/
public class DefaultRouterTest {
private static final RouteHandler emptyRouteHandler = new EmptyRouteHandler();
private DefaultRouter router;
@Rule
public ExpectedException thrown = ExpectedException.none();
@Before
public void before() {
router = new DefaultRouter();
}
@After
public void after() {
router = null;
}
@Test
public void testNullUriPatternRoute() throws Exception {
Route route = Route.GET(null, emptyRouteHandler);
thrown.expect(Exception.class);
thrown.expectMessage("The uri pattern cannot be null or empty");
router.addRoute(route);
}
@Test
public void testEmptyUriPatternRoute() throws Exception {
Route route = Route.GET("", emptyRouteHandler);
thrown.expect(Exception.class);
thrown.expectMessage("The uri pattern cannot be null or empty");
router.addRoute(route);
}
@Test
public void testUnspecifiedMethodRequestRoute() throws Exception {
Route route = new Route("", "/.*", emptyRouteHandler);
thrown.expect(Exception.class);
thrown.expectMessage("Unspecified request method");
router.addRoute(route);
}
@Test
public void testAddRoute() throws Exception {
Route route = Route.GET("/.*", emptyRouteHandler);
router.addRoute(route);
assertEquals(1, router.getRoutes().size());
assertEquals(1, router.getRoutes(HttpConstants.Method.GET).size());
}
@Test
public void testRemoveRoute() throws Exception {
Route route = Route.GET("/.*", emptyRouteHandler);
router.addRoute(route);
assertEquals(1, router.getRoutes().size());
assertEquals(1, router.getRoutes(HttpConstants.Method.GET).size());
router.removeRoute(route);
assertEquals(0, router.getRoutes().size());
assertEquals(0, router.getRoutes(HttpConstants.Method.GET).size());
}
@Test
public void testFindRoutes() throws Exception {
Route route = Route.GET("/contact", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/contact");
assertNotNull(routeMatches);
assertEquals(1, routeMatches.size());
routeMatches = router.findRoutes(HttpConstants.Method.POST, "/contact");
assertNotNull(routeMatches);
assertEquals(0, routeMatches.size());
routeMatches = router.findRoutes(HttpConstants.Method.GET, "/");
assertNotNull(routeMatches);
assertEquals(0, routeMatches.size());
}
@Test
public void testPathParamsRoute() throws Exception {
Route route = Route.GET("/contact/{id}", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/contact/3");
assertEquals(1, routeMatches.size());
Map<String, String> pathParameters = routeMatches.get(0).getPathParameters();
assertNotNull(pathParameters);
assertEquals(1, pathParameters.size());
assertTrue(pathParameters.containsKey("id"));
assertEquals(String.valueOf(3), pathParameters.get("id"));
}
@Test
public void testWildcardRoute() throws Exception {
Route route = Route.GET("/.*", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/contact/3");
assertEquals(1, routeMatches.size());
}
@Test
public void testPatchRoute() throws Exception {
Route route = Route.PATCH("/contact/{id}", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.PATCH, "/contact/3");
assertEquals(1, routeMatches.size());
Map<String, String> pathParameters = routeMatches.get(0).getPathParameters();
assertNotNull(pathParameters);
assertEquals(1, pathParameters.size());
assertTrue(pathParameters.containsKey("id"));
assertEquals(String.valueOf(3), pathParameters.get("id"));
}
@Test
public void testIntIdRoute() throws Exception {
Route route = Route.PATCH("/contact/{id: [0-9]+}", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.PATCH, "/contact/3");
assertEquals(1, routeMatches.size());
Map<String, String> pathParameters = routeMatches.get(0).getPathParameters();
assertNotNull(pathParameters);
assertEquals(1, pathParameters.size());
assertTrue(pathParameters.containsKey("id"));
assertEquals(String.valueOf(3), pathParameters.get("id"));
routeMatches = router.findRoutes(HttpConstants.Method.PATCH, "/contact/a");
assertEquals(0, routeMatches.size());
}
@Test
public void testIntIdRoute2() throws Exception {
Route route = Route.GET("/contact/{id: [0-9]+}/something/{else: [A-z]*}", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/contact/3/something/borrowed");
assertEquals(1, routeMatches.size());
Map<String, String> pathParameters = routeMatches.get(0).getPathParameters();
assertNotNull(pathParameters);
assertEquals(2, pathParameters.size());
assertTrue(pathParameters.containsKey("id"));
assertEquals(String.valueOf(3), pathParameters.get("id"));
assertEquals("borrowed", pathParameters.get("else"));
}
@Test
public void testPosixAlpha() throws Exception {
Route route = Route.GET("/user/{login: :alpha:+}/todo/{id: :digit:+}", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/user/jämяs/todo/57");
assertEquals(1, routeMatches.size());
Map<String, String> pathParameters = routeMatches.get(0).getPathParameters();
assertNotNull(pathParameters);
assertEquals(2, pathParameters.size());
assertTrue(pathParameters.containsKey("login"));
assertEquals("jämяs", pathParameters.get("login"));
assertTrue(pathParameters.containsKey("id"));
assertEquals("57", pathParameters.get("id"));
}
@Test
public void testPosixAlpha2() throws Exception {
Route route = Route.GET("/user/{login: [:digit::alpha:-_\\+\\.]+}/todo/{id: :digit:+}", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/user/j.ä_я3-s/todo/57");
assertEquals(1, routeMatches.size());
Map<String, String> pathParameters = routeMatches.get(0).getPathParameters();
assertNotNull(pathParameters);
assertEquals(2, pathParameters.size());
assertTrue(pathParameters.containsKey("login"));
assertEquals("j.ä_я3-s", pathParameters.get("login"));
assertTrue(pathParameters.containsKey("id"));
assertEquals("57", pathParameters.get("id"));
}
@Test
public void testPosixAlnum() throws Exception {
Route route = Route.GET("/user/{login: :alnum:+}", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/user/james5");
assertEquals(1, routeMatches.size());
Map<String, String> pathParameters = routeMatches.get(0).getPathParameters();
assertNotNull(pathParameters);
assertEquals(1, pathParameters.size());
assertTrue(pathParameters.containsKey("login"));
assertEquals("james5", pathParameters.get("login"));
}
@Test
public void testPosixDigit() throws Exception {
Route route = Route.GET("/contact/{id: :digit:+}/{field: :alpha:+}", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/contact/57/telephone");
assertEquals(1, routeMatches.size());
Map<String, String> pathParameters = routeMatches.get(0).getPathParameters();
assertNotNull(pathParameters);
assertEquals(2, pathParameters.size());
assertTrue(pathParameters.containsKey("id"));
assertEquals("57", pathParameters.get("id"));
assertTrue(pathParameters.containsKey("field"));
assertEquals("telephone", pathParameters.get("field"));
}
@Test
public void testPosixHexDigit() throws Exception {
Route route = Route.GET("/contact/{id: :xdigit:+}/{field: :digit:+}", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/contact/5ace076/97");
assertEquals(1, routeMatches.size());
Map<String, String> pathParameters = routeMatches.get(0).getPathParameters();
assertNotNull(pathParameters);
assertEquals(2, pathParameters.size());
assertTrue(pathParameters.containsKey("id"));
assertEquals("5ace076", pathParameters.get("id"));
assertTrue(pathParameters.containsKey("field"));
assertEquals("97", pathParameters.get("field"));
}
@Test
public void testPosixASCII() throws Exception {
Route route = Route.GET("/contact/{id: :ascii:+}/{field: :digit:+}", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/contact/5ace076/97");
assertEquals(1, routeMatches.size());
Map<String, String> pathParameters = routeMatches.get(0).getPathParameters();
assertNotNull(pathParameters);
assertEquals(2, pathParameters.size());
assertTrue(pathParameters.containsKey("id"));
assertEquals("5ace076", pathParameters.get("id"));
assertTrue(pathParameters.containsKey("field"));
assertEquals("97", pathParameters.get("field"));
}
@Test
public void testWebjarsRoute() throws Exception {
WebjarsResourceHandler webjars = new WebjarsResourceHandler();
Route route = Route.GET(webjars.getUriPattern(), emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, "/webjars/bootstrap/3.0.2/css/bootstrap.min.css");
assertEquals(1, routeMatches.size());
}
@Test
public void testParameters() throws Exception {
///////////////////////////////////////////////////////////////////////
// One parameter:
///////////////////////////////////////////////////////////////////////
router.addRoute(Route.GET("/{name}/dashboard", emptyRouteHandler));
assertEquals(0, router.findRoutes(HttpConstants.Method.GET, "/dashboard").size());
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/John/dashboard");
assertEquals(1, matches.size());
assertEquals("John", matches.get(0).getPathParameters().get("name"));
///////////////////////////////////////////////////////////////////////
// More parameters
///////////////////////////////////////////////////////////////////////
router.addRoute(Route.GET("/{name}/{id}/dashboard", emptyRouteHandler));
assertEquals(0, router.findRoutes(HttpConstants.Method.GET, "/dashboard").size());
matches = router.findRoutes(HttpConstants.Method.GET, "/John/20/dashboard");
assertEquals(1, matches.size());
assertEquals("John", matches.get(0).getPathParameters().get("name"));
assertEquals("20", matches.get(0).getPathParameters().get("id"));
}
@Test
public void testParametersAndRegex() throws Exception {
router.addRoute(Route.GET("/John/{id}/.*", emptyRouteHandler));
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/John/20/dashboard");
assertEquals(1, matches.size());
RouteMatch match = matches.get(0);
assertEquals(1, match.getPathParameters().size());
assertEquals("20", match.getPathParameters().get("id"));
matches = router.findRoutes(HttpConstants.Method.GET, "/John/20/admin");
assertEquals(1, matches.size());
match = matches.get(0);
assertEquals(1, match.getPathParameters().size());
assertEquals("20", match.getPathParameters().get("id"));
matches = router.findRoutes(HttpConstants.Method.GET, "/John/20/mock");
assertEquals(1, matches.size());
match = matches.get(0);
assertEquals(1, match.getPathParameters().size());
assertEquals("20", match.getPathParameters().get("id"));
}
@Test
public void testParametersAndRegexInsideVariableParts() throws Exception {
router.addRoute(Route.GET("/public/{path: .*}", emptyRouteHandler));
String pathUnderTest = "/public/css/app.css";
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, pathUnderTest);
assertEquals(1, matches.size());
RouteMatch match = matches.get(0);
assertEquals(1, match.getPathParameters().size());
assertEquals("css/app.css", match.getPathParameters().get("path"));
pathUnderTest = "/public/js/main.js";
matches = router.findRoutes(HttpConstants.Method.GET, pathUnderTest);
assertEquals(1, matches.size());
match = matches.get(0);
assertEquals(1, match.getPathParameters().size());
assertEquals("js/main.js", match.getPathParameters().get("path"));
pathUnderTest = "/public/robots.txt";
matches = router.findRoutes(HttpConstants.Method.GET, pathUnderTest);
assertEquals(1, matches.size());
match = matches.get(0);
assertEquals(1, match.getPathParameters().size());
assertEquals("robots.txt", match.getPathParameters().get("path"));
// multiple parameter parsing with regex expressions
router.addRoute(Route.GET("/{name: .+}/photos/{id: [0-9]+}", emptyRouteHandler));
pathUnderTest = "/John/photos/2201";
matches = router.findRoutes(HttpConstants.Method.GET, pathUnderTest);
assertEquals(1, matches.size());
match = matches.get(0);
assertEquals(2, match.getPathParameters().size());
assertEquals("John", match.getPathParameters().get("name"));
assertEquals("2201", match.getPathParameters().get("id"));
assertEquals(0, router.findRoutes(HttpConstants.Method.GET, "John/photos/first").size());
}
@Test
public void testParametersDontCrossSlashes() throws Exception {
router.addRoute(Route.GET("/blah/{id}/{id2}/{id3}/morestuff/at/the/end", emptyRouteHandler));
// this must match
assertEquals(1, router.findRoutes(HttpConstants.Method.GET, "/blah/id/id2/id3/morestuff/at/the/end").size());
// this should not match as the last "end" is missing
assertEquals(0, router.findRoutes(HttpConstants.Method.GET, "/blah/id/id2/id3/morestuff/at/the").size());
}
@Test
public void testPointsInRegexDontCrashRegexInTheMiddleOfTheRoute() throws Exception {
router.addRoute(Route.GET("/blah/{id}/myname", emptyRouteHandler));
// the "." in the route should not make any trouble:
String routeFromServer = "/blah/my.id/myname";
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, routeFromServer);
assertEquals(1, matches.size());
RouteMatch match = matches.get(0);
assertEquals(1, match.getPathParameters().size());
assertEquals("my.id", match.getPathParameters().get("id"));
// and another slightly different route
routeFromServer = "/blah/my.id/myname/should_not_match";
matches = router.findRoutes(HttpConstants.Method.GET, routeFromServer);
assertEquals(0, matches.size());
}
@Test
public void testPointsInRegexDontCrashRegexAtEnd() throws Exception {
router.addRoute(Route.GET("/blah/{id}", emptyRouteHandler));
// the "." in the route should not make any trouble:
// even if it's the last part of the route
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/blah/my.id");
assertEquals(1, matches.size());
RouteMatch match = matches.get(0);
assertEquals(1, match.getPathParameters().size());
assertEquals("my.id", match.getPathParameters().get("id"));
}
@Test
public void testRegexInRouteWorksWithEscapes() throws Exception {
// Test escaped constructs in regex
// regex with escaped construct in a route
router.addRoute(Route.GET("/customers/\\d+", emptyRouteHandler));
assertEquals(1, router.findRoutes(HttpConstants.Method.GET, "/customers/1234").size());
assertEquals(0, router.findRoutes(HttpConstants.Method.GET, "/customers/12ab").size());
// regex with escaped construct in a route with variable parts
router = new DefaultRouter();
router.addRoute(Route.GET("/customers/{id: \\d+}", emptyRouteHandler));
assertEquals(1, router.findRoutes(HttpConstants.Method.GET, "/customers/1234").size());
assertEquals(0, router.findRoutes(HttpConstants.Method.GET, "/customers/12x").size());
RouteMatch routeMatch = router.findRoutes(HttpConstants.Method.GET, "/customers/1234").get(0);
Map<String, String> map = routeMatch.getPathParameters();
assertEquals(1, map.size());
assertEquals("1234", map.get("id"));
}
@Test
public void testRegexInRouteWorksWithoutSlashAtTheEnd() throws Exception {
Route route = Route.GET("/blah/{id}/.*", emptyRouteHandler);
router.addRoute(route);
// the "." in the real route should work without any problems:
String routeFromServer = "/blah/my.id/and/some/more/stuff";
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, routeFromServer);
assertEquals(1, routeMatches.size());
RouteMatch routeMatch = routeMatches.get(0);
assertEquals(route, routeMatch.getRoute());
assertEquals(1, routeMatch.getPathParameters().size());
assertEquals("my.id", routeMatch.getPathParameters().get("id"));
// another slightly different route.
routeFromServer = "/blah/my.id/";
routeMatches = router.findRoutes(HttpConstants.Method.GET, routeFromServer);
assertEquals(1, routeMatches.size());
routeMatch = routeMatches.get(0);
assertEquals(route, routeMatch.getRoute());
assertEquals(1, routeMatch.getPathParameters().size());
assertEquals("my.id", routeMatch.getPathParameters().get("id"));
routeMatches = router.findRoutes(HttpConstants.Method.GET, "/blah/my.id");
assertEquals(0, routeMatches.size());
}
@Test
public void testRouteWithUrlEncodedSlashGetsChoppedCorrectly() throws Exception {
Route route = Route.GET("/blah/{id}/.*", emptyRouteHandler);
router.addRoute(route);
// Just a simple test to make sure everything works on a not encoded
// uri: decoded this would be /blah/my/id/and/some/more/stuff
String routeFromServer = "/blah/my%2fid/and/some/more/stuff";
List<RouteMatch> routeMatches = router.findRoutes(HttpConstants.Method.GET, routeFromServer);
assertEquals(1, routeMatches.size());
RouteMatch routeMatch = routeMatches.get(0);
assertEquals(route, routeMatch.getRoute());
assertEquals(1, routeMatch.getPathParameters().size());
assertEquals("my%2fid", routeMatch.getPathParameters().get("id"));
}
@Test
public void testUriForWithRegex() throws Exception {
Route route = Route.GET("/user/{email}/{id: .*}", emptyRouteHandler);
router.addRoute(route);
Map<String, Object> parameters = new HashMap<>();
parameters.put("email", "test@test.com");
parameters.put("id", 5);
String path = router.uriFor(route.getUriPattern(), parameters);
assertThat(path, equalTo("/user/test@test.com/5"));
}
@Test
public void testUriForWithMultipleRegex() throws Exception {
Route route = Route.GET("/user/{email: .*}/test/{id: .*}", emptyRouteHandler);
router.addRoute(route);
Map<String, Object> parameters = new HashMap<>();
parameters.put("email", "test@test.com");
parameters.put("id", 5);
String path = router.uriFor(route.getUriPattern(), parameters);
assertThat(path, equalTo("/user/test@test.com/test/5"));
}
@Test
public void testUriForWithSplat() throws Exception {
Route route = Route.GET("/repository/{repo: .*}/ticket/{id: .*}", emptyRouteHandler);
router.addRoute(route);
Map<String, Object> parameters = new HashMap<>();
parameters.put("repo", "test/myrepo");
parameters.put("id", 5);
String path = router.uriFor(route.getUriPattern(), parameters);
assertThat(path, equalTo("/repository/test/myrepo/ticket/5"));
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/repository/test/myrepo/ticket/5");
assertFalse(matches.isEmpty());
assertEquals("test/myrepo", matches.get(0).getPathParameters().get("repo"));
assertEquals("5", matches.get(0).getPathParameters().get("id"));
}
@Test
public void testUriForWithRegexAndQueryParameters() throws Exception {
Route route = Route.GET("/user/{email}/{id: .*}", emptyRouteHandler);
router.addRoute(route);
Map<String, Object> parameters = new HashMap<>();
parameters.put("email", "test@test.com");
parameters.put("id", 5);
parameters.put("query", "recent_changes");
String path = router.uriFor(route.getUriPattern(), parameters);
assertThat(path, equalTo("/user/test@test.com/5?query=recent_changes"));
}
@Test
public void testUriForWithEncodedParameters() throws Exception {
Route route = Route.GET("/user/{email}", emptyRouteHandler);
router.addRoute(route);
Map<String, Object> parameters = new HashMap<>();
parameters.put("email", "test@test.com");
parameters.put("name", "Decebal Suiu");
String path = router.uriFor(route.getUriPattern(), parameters);
assertThat(path, equalTo("/user/test@test.com?name=Decebal+Suiu"));
}
@Test
public void testExclusionFilter() throws Exception {
Route route = Route.ALL("^(?!/(webjars|public)/).*", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/test/route");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/webjars/route");
assertEquals(0, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/public/route");
assertEquals(0, matches.size());
}
@Test
public void testOptionalSuffixGroup() throws Exception {
Route route = Route.ALL("/api/contact/{id: [0-9]+}(\\.(json|xml|yaml))?", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/api/contact/5");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/api/contact/5.json");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/api/contact/5.xml");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/api/contact/5.yaml");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/api/contact/5.unknown");
assertEquals(0, matches.size());
}
@Test
public void testRequiredSuffixGroup() throws Exception {
Route route = Route.ALL("/api/contact/{id: [0-9]+}(\\.(json|xml|yaml))", emptyRouteHandler);
router.addRoute(route);
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/api/contact/5");
assertEquals(0, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/api/contact/5.json");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/api/contact/5.xml");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/api/contact/5.yaml");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/api/contact/5.unknown");
assertEquals(0, matches.size());
}
@Test
public void testAddGroup() {
RouteGroup group = new RouteGroup("/users");
group.GET("{id}", emptyRouteHandler);
router.addRouteGroup(group);
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/users/1");
assertEquals(1, matches.size());
}
@Test
public void testGroupAddRoute() {
RouteGroup group = new RouteGroup("/users");
Route route = Route.GET("{id}", emptyRouteHandler);
group.addRoute(route);
router.addRouteGroup(group);
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/users/1");
assertEquals(1, matches.size());
}
@Test
public void testNestGroup() {
RouteGroup group = new RouteGroup("/users");
RouteGroup child = new RouteGroup(group, "{id}");
child.POST("like", emptyRouteHandler);
child.addRoute(Route.GET("help", emptyRouteHandler));
router.addRouteGroup(group);
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.POST, "/users/1/like");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/users/2/help");
assertEquals(1, matches.size());
}
@Test
public void testNestGroupWithCRUD() {
RouteGroup admin = new RouteGroup("/admin");
admin.GET("login", emptyRouteHandler);
admin.GET("logout", emptyRouteHandler);
// RouteGroup users = new RouteGroup(admin, "users");
RouteGroup users = new RouteGroup("users");
users.GET("{id}", emptyRouteHandler); // retrieves (all or a specific user)
users.PUT("{id}", emptyRouteHandler); // update a specific user
users.POST("", emptyRouteHandler); // create a new user
users.DELETE("/{id}", emptyRouteHandler); // delete a specific user
admin.addRouteGroup(users);
router.addRouteGroup(admin);
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/admin/login");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.GET, "/admin/logout");
assertEquals(1, matches.size());
/*
matches = router.findRoutes(HttpConstants.Method.GET, "/admin/users");
assertEquals(1, matches.size());
*/
matches = router.findRoutes(HttpConstants.Method.GET, "/admin/users/1");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.PUT, "/admin/users/2");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.POST, "/admin/users");
assertEquals(1, matches.size());
matches = router.findRoutes(HttpConstants.Method.DELETE, "/admin/users/3");
assertEquals(1, matches.size());
}
@Test
public void testCustomGroup() {
UserGroup userGroup = new UserGroup();
router.addRouteGroup(userGroup);
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/users");
assertEquals(1, matches.size());
}
@Test
public void testGroupWithName() {
RouteGroup users = new RouteGroup("/users").named("users.");
users.GET("{id: [0-9]+}", emptyRouteHandler).named("get"); // retrieves (all or a specific user)
users.PUT("{id}", emptyRouteHandler).named("update"); // update a specific user
users.POST("", emptyRouteHandler).named("new"); // create a new user
users.DELETE("/{id}", emptyRouteHandler).named("delete"); // delete a specific user
users.GET("/test", emptyRouteHandler);
router.addRouteGroup(users);
String uri = router.uriFor("users.get", Collections.emptyMap());
assertNotNull(uri);
uri = router.uriFor("users.update", Collections.emptyMap());
assertNotNull(uri);
uri = router.uriFor("users.new", Collections.emptyMap());
assertNotNull(uri);
uri = router.uriFor("users.delete", Collections.emptyMap());
assertNotNull(uri);
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/users/test");
assertEquals(1, matches.size());
assertNull(matches.get(0).getRoute().getName());
}
@Test
public void testGroupWithAttributes() {
RouteGroup group = new RouteGroup("/users");
group.bind("audit", true);
group.GET("/", emptyRouteHandler).bind("secure", true);
router.addRouteGroup(group);
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/users");
assertEquals(1, matches.size());
Route route = matches.get(0).getRoute();
assertTrue(route.getAttributes().containsKey("audit"));
assertTrue(route.getAttribute("audit"));
assertTrue(route.getAttributes().containsKey("secure"));
assertTrue(route.getAttribute("secure"));
}
@Test
public void testEmptyStringAsPathParameter() {
router.addRoute(Route.GET("/", emptyRouteHandler));
router.addRoute(Route.GET("/{id}", emptyRouteHandler));
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/");
assertEquals(1, matches.size());
}
@Test
public void testUnderlineInPathParameter() throws Exception {
router.addRoute(Route.GET("/{user_id}", emptyRouteHandler));
List<RouteMatch> matches = router.findRoutes(HttpConstants.Method.GET, "/123");
assertEquals(1, matches.size());
}
private class UserGroup extends RouteGroup {
public UserGroup() {
super("/users");
GET("", emptyRouteHandler);
}
}
}