/atlassian-pretty-urls-plugin/src/test/java/com/atlassian/prettyurls/internal/route/UrlRouterImplTest.java
Java | 392 lines | 289 code | 94 blank | 9 comment | 8 complexity | dcc724d43a09e9583e21dfeed98708fd MD5 | raw file
- package com.atlassian.prettyurls.internal.route;
- import com.atlassian.plugin.servlet.filter.FilterLocation;
- import com.atlassian.prettyurls.api.route.DefaultUrlRouteRuleSetKey;
- import com.atlassian.prettyurls.api.route.RoutePredicates;
- import com.atlassian.prettyurls.api.route.UrlRouteRuleSet;
- import com.atlassian.prettyurls.mocks.MockHttpServletRequest;
- import com.google.common.collect.Lists;
- import com.google.common.collect.Sets;
- import com.sun.jersey.api.uri.UriTemplate;
- import org.apache.http.NameValuePair;
- import org.apache.http.client.utils.URLEncodedUtils;
- import org.junit.Before;
- import org.junit.Test;
- import javax.ws.rs.core.UriBuilder;
- import java.net.URI;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.List;
- import java.util.Set;
- import static com.atlassian.plugin.servlet.filter.FilterLocation.BEFORE_DISPATCH;
- import static org.hamcrest.CoreMatchers.equalTo;
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertFalse;
- import static org.junit.Assert.assertNotNull;
- import static org.junit.Assert.assertNull;
- import static org.junit.Assert.assertThat;
- import static org.junit.Assert.assertTrue;
- public class UrlRouterImplTest {
- private UrlRouteRuleSet routeRuleSet;
- private UrlRouterImpl router;
- private MockHttpServletRequest request;
- private UrlRouteRuleSet.Builder builder;
- @Before
- public void setUp() throws Exception {
- builder = newRouteSetBuilder();
- router = new UrlRouterImpl(null) {
- Set<UrlRouteRuleSet> getRouteRuleSets(FilterLocation filterLocation, String requestURI) {
- return Sets.newHashSet(routeRuleSet);
- }
- };
- }
- private UrlRouteRuleSet.Builder newRouteSetBuilder() {
- UrlRouteRuleSet.Builder builder = new UrlRouteRuleSet.Builder();
- builder.setKey(new DefaultUrlRouteRuleSetKey("test.module"));
- builder.addTopLevelPath("avenger");
- return builder;
- }
- @Test
- public void testRoute() throws Exception {
- builder.addRule(
- "/avenger/thor/{id}/{weapon}",
- "/secure/Thor.jspa"
- );
- builder.addRule(
- "/avenger/thor/{id}/{weapon}/hair{style}",
- "/secure/Thor!flickHair.jspa");
- builder.addRule(
- "/avenger/hulk/{id}",
- "/secure/Hulk!rage.jspa");
- routeRuleSet = builder.build();
- request = new MockHttpServletRequest("/avenger/thor/id123/weapon1");
- //
- // we no longer put the extra parameters into the redirect URL
- // as the requestDispatcher code does this for us
- //
- request.addParameter("heat", "high");
- UrlRouter.Result actual = router.route(request, BEFORE_DISPATCH);
- assertURLEquals("/secure/Thor.jspa?id=id123&weapon=weapon1", actual);
- request = new MockHttpServletRequest("/miss/thor/id123/weapon1");
- actual = router.route(request, BEFORE_DISPATCH);
- assertFalse(actual.isRouted());
- request = new MockHttpServletRequest("/avenger/thor/id123/weapon1/hairWAVY");
- request.addParameter("heat", "high");
- actual = router.route(request, BEFORE_DISPATCH);
- assertURLEquals("/secure/Thor!flickHair.jspa?id=id123&weapon=weapon1&style=WAVY&", actual);
- request = new MockHttpServletRequest("/avenger/hulk/greenHair");
- actual = router.route(request, BEFORE_DISPATCH);
- assertURLEquals("/secure/Hulk!rage.jspa?id=greenHair", actual);
- }
- @Test
- public void testRouteWithGeneratorFunction() throws Exception {
- builder.addRule(
- new UriTemplate("/avenger/thor/{id}/{weapon}"),
- (request, variables) -> "/avenger/thor/" + variables.get("id") + "/big_" + variables.get("weapon"),
- Collections.emptyList());
- routeRuleSet = builder.build();
- request = new MockHttpServletRequest("/avenger/thor/id123/weapon1");
- UrlRouter.Result actual = router.route(request, BEFORE_DISPATCH);
- assertURLEquals("/avenger/thor/id123/big_weapon1", actual);
- }
- @Test
- public void testWithContext() throws Exception {
- builder.addRule(
- "/avenger/thor/{id}/{weapon}",
- "/secure/Thor.jspa");
- routeRuleSet = builder.build();
- request = new MockHttpServletRequest("/somecontext/avenger/thor/id123/weapon1");
- request.setContextPath("/somecontext");
- assertURLEquals("/secure/Thor.jspa?id=id123&weapon=weapon1", router.route(request, BEFORE_DISPATCH));
- }
- @Test
- public void testToURIMapping() throws Exception {
- builder.addRule(
- "/avenger/{character}/{id}/{weapon}",
- "/secure/LookIts{character}.jspa");
- routeRuleSet = builder.build();
- request = new MockHttpServletRequest("/avenger/Thor/id123/hammer");
- assertURLEquals("/secure/LookItsThor.jspa?id=id123&weapon=hammer", router.route(request, BEFORE_DISPATCH));
- request = new MockHttpServletRequest("/avenger/TheHulk/id456/rage");
- assertURLEquals("/secure/LookItsTheHulk.jspa?id=id456&weapon=rage", router.route(request, BEFORE_DISPATCH));
- }
- @Test
- public void testToURIMappingToRequestParams() throws Exception {
- builder.addRule(
- "/avenger/{character}/{id}/{weapon}",
- "/secure/LookIts{character}.jspa?tool={weapon}");
- routeRuleSet = builder.build();
- request = new MockHttpServletRequest("/avenger/Thor/id123/hammer");
- assertURLEquals("/secure/LookItsThor.jspa?tool=hammer&id=id123", router.route(request, BEFORE_DISPATCH));
- }
- @Test
- public void testHttpVerbs() throws Exception {
- builder.addRule(
- "/avenger/Thor",
- "/secure/Thor.jspa",
- Lists.newArrayList("GET"));
- builder.addRule(
- "/avenger/Thor/POSTorGET",
- "/secure/Thor.jspa",
- Lists.newArrayList("GET", "POST"));
- routeRuleSet = builder.build();
- request = new MockHttpServletRequest("/avenger/Thor");
- request.setMethod("POST");
- UrlRouterImpl.Result result = router.route(request, BEFORE_DISPATCH);
- assertFalse(result.isRouted());
- request.setMethod("get");
- assertURLEquals("/secure/Thor.jspa", router.route(request, BEFORE_DISPATCH));
- request.setMethod("GET");
- assertURLEquals("/secure/Thor.jspa", router.route(request, BEFORE_DISPATCH));
- request = new MockHttpServletRequest("/avenger/Thor/POSTorGET");
- request.setMethod("DELETE");
- result = router.route(request, BEFORE_DISPATCH);
- assertFalse(result.isRouted());
- request.setMethod("GET");
- assertURLEquals("/secure/Thor.jspa", router.route(request, BEFORE_DISPATCH));
- request.setMethod("POST");
- assertURLEquals("/secure/Thor.jspa", router.route(request, BEFORE_DISPATCH));
- }
- @Test
- public void uriWithDirectoryTraversalIsNormalised() throws Exception {
- request = new MockHttpServletRequest("/avenger/Thor/../CaptainAmerica");
- request.setMethod("get");
- String requestUri = router.makeRequestURI(request);
- assertNotNull(requestUri);
- assertThat(requestUri, equalTo("/avenger/CaptainAmerica"));
- }
- @Test
- public void badUriReturnsUnRoutableRoute() {
- request = new MockHttpServletRequest("http://avenger/^Thor^");
- request.setMethod("get");
- UrlRouterImpl.Result route = router.route(request, BEFORE_DISPATCH);
- assertNotNull(route);
- assertFalse(route.isRouted());
- assertNull(route.toURI());
- }
- @Test
- public void testLowLevelRoutePredicates() throws Exception {
- builder.addRule(
- "/avenger/Thor",
- "/secure/Thor.jspa",
- Lists.newArrayList("GET"),
- RoutePredicates.alwaysFalse());
- builder.addRule(
- "/avenger/Thor/POSTorGET",
- "/secure/Thor.jspa",
- Lists.newArrayList("GET", "POST"),
- RoutePredicates.alwaysTrue());
- routeRuleSet = builder.build();
- request = new MockHttpServletRequest("/avenger/Thor");
- request.setMethod("GET");
- UrlRouterImpl.Result result = router.route(request, BEFORE_DISPATCH);
- assertFalse(result.isRouted());
- request = new MockHttpServletRequest("/avenger/Thor/POSTorGET");
- request.setMethod("GET");
- result = router.route(request, BEFORE_DISPATCH);
- assertTrue(result.isRouted());
- }
- @Test
- public void testTopLevelRoutePredicates_when_off() throws Exception {
- // turn the top level off
- builder.setPredicate(RoutePredicates.<UrlRouteRuleSet>alwaysFalse());
- builder.addRule(
- "/avenger/Thor",
- "/secure/Thor.jspa",
- Lists.newArrayList("GET"),
- RoutePredicates.alwaysTrue());
- builder.addRule(
- "/avenger/Thor/POSTorGET",
- "/secure/Thor.jspa",
- Lists.newArrayList("GET", "POST"),
- RoutePredicates.alwaysTrue());
- routeRuleSet = builder.build();
- request = new MockHttpServletRequest("/avenger/Thor");
- UrlRouterImpl.Result result = router.route(request, BEFORE_DISPATCH);
- assertFalse(result.isRouted());
- request = new MockHttpServletRequest("/avenger/Thor/POSTorGET");
- result = router.route(request, BEFORE_DISPATCH);
- assertFalse(result.isRouted());
- }
- @Test
- public void testTopLevelRoutePredicates_when_on() throws Exception {
- builder.setPredicate(RoutePredicates.<UrlRouteRuleSet>alwaysTrue());
- builder.addRule(
- "/avenger/Thor",
- "/secure/Thor.jspa",
- Lists.newArrayList("GET"),
- RoutePredicates.alwaysTrue());
- builder.addRule(
- "/avenger/Thor/POSTorGET",
- "/secure/Thor.jspa",
- Lists.newArrayList("GET", "POST"),
- RoutePredicates.alwaysTrue());
- routeRuleSet = builder.build();
- request = new MockHttpServletRequest("/avenger/Thor");
- UrlRouterImpl.Result result = router.route(request, BEFORE_DISPATCH);
- assertTrue(result.isRouted());
- request = new MockHttpServletRequest("/avenger/Thor/POSTorGET");
- result = router.route(request, BEFORE_DISPATCH);
- assertTrue(result.isRouted());
- }
- @Test
- public void testMultipleRuleSetsDoesJaxRSMatching() throws Exception {
- builder = newRouteSetBuilder();
- builder.addRule(
- "/avenger/{character}/{id}/{weapon}",
- "/secure/LookIts{character}.jspa?withHis={weapon}");
- UrlRouteRuleSet routeRuleSet1 = builder.build();
- // in a single set world the former would over-ride this
- // but not when there are 2 sets
- builder = newRouteSetBuilder();
- builder.addRule(
- "/avenger/{character}/{id}/{weapon}/{shield}",
- "/secure/LookItsAlso{character}.jspa");
- UrlRouteRuleSet routeRuleSet2 = builder.build();
- router = new UrlRouterImpl(null) {
- Set<UrlRouteRuleSet> getRouteRuleSets(FilterLocation filterLocation, String requestURI) {
- return Sets.newHashSet(routeRuleSet1, routeRuleSet2);
- }
- };
- //
- // with multiple rule sets we use JAX-RS matching.
- request = new MockHttpServletRequest("/avenger/Thor/1/Hammer/Hair");
- UrlRouter.Result actual = router.route(request, BEFORE_DISPATCH);
- assertURLEquals("/secure/LookItsAlsoThor.jspa", actual);
- request = new MockHttpServletRequest("/avenger/Thor/1/Hammer/Hair");
- request = new MockHttpServletRequest("/avenger/Hulk/1/Fists");
- actual = router.route(request, BEFORE_DISPATCH);
- assertURLEquals("/secure/LookItsHulk.jspa?withHis=Fists", actual);
- }
- private void assertURLEquals(String expected, UrlRouter.Result result) {
- assertTrue(result.isRouted());
- URI expectedURI = UriBuilder.fromUri(expected).build();
- URI actualURI = UriBuilder.fromUri(result.toURI()).build();
- assertEquals(expectedURI.getPath(), actualURI.getPath());
- List<NameValuePair> expectedPairs = URLEncodedUtils.parse(expectedURI, "UTF-8");
- List<NameValuePair> actualPairs = URLEncodedUtils.parse(actualURI, "UTF-8");
- assertTrue(sameNVP(expectedPairs, actualPairs));
- }
- private boolean sameNVP(List<NameValuePair> expectedPairs, List<NameValuePair> actualPairs) {
- return containsNVPs(expectedPairs, actualPairs) && containsNVPs(expectedPairs, actualPairs);
- }
- private boolean containsNVPs(List<NameValuePair> expectedPairs, List<NameValuePair> actualPairs) {
- for (NameValuePair expectedPair : expectedPairs) {
- boolean containedWithin = false;
- for (NameValuePair actualPair : actualPairs) {
- if (NVP_COMPARATOR.compare(expectedPair, actualPair) == 0) {
- containedWithin = true;
- break;
- }
- }
- if (!containedWithin) {
- return false;
- }
- }
- return true;
- }
- public static final NVPComparator NVP_COMPARATOR = new NVPComparator();
- private static class NVPComparator implements Comparator<NameValuePair> {
- @Override
- public int compare(NameValuePair o1, NameValuePair o2) {
- int rc = o1.getName().compareTo(o2.getName());
- if (rc == 0) {
- rc = o1.getValue().compareTo(o2.getValue());
- }
- return rc;
- }
- }
- }