/* * JBoss, Home of Professional Open Source. * Copyright 2014 Red Hat, Inc., and individual contributors * as indicated by the @author tags. * * 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.undertow.util; import io.undertow.testutils.category.UnitTest; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import java.util.HashMap; import java.util.Map; import java.util.TreeSet; /** * @author Stuart Douglas */ @Category(UnitTest.class) public class PathTemplateTestCase { @Test public void testMatches() { // test normal use testMatch("/docs/mydoc", "/docs/mydoc"); testMatch("/docs/{docId}", "/docs/mydoc", "docId", "mydoc"); testMatch("/docs/{docId}/{op}", "/docs/mydoc/read", "docId", "mydoc", "op", "read"); testMatch("/docs/{docId}/{op}/{allowed}", "/docs/mydoc/read/true", "docId", "mydoc", "op", "read", "allowed", "true"); testMatch("/docs/{docId}/operation/{op}", "/docs/mydoc/operation/read", "docId", "mydoc", "op", "read"); testMatch("/docs/{docId}/read", "/docs/mydoc/read", "docId", "mydoc"); testMatch("/docs/{docId}/read", "/docs/mydoc/read?myQueryParam", "docId", "mydoc"); // test no leading slash testMatch("docs/mydoc", "/docs/mydoc"); testMatch("docs/{docId}", "/docs/mydoc", "docId", "mydoc"); testMatch("docs/{docId}/{op}", "/docs/mydoc/read", "docId", "mydoc", "op", "read"); testMatch("docs/{docId}/{op}/{allowed}", "/docs/mydoc/read/true", "docId", "mydoc", "op", "read", "allowed", "true"); testMatch("docs/{docId}/operation/{op}", "/docs/mydoc/operation/read", "docId", "mydoc", "op", "read"); testMatch("docs/{docId}/read", "/docs/mydoc/read", "docId", "mydoc"); testMatch("docs/{docId}/read", "/docs/mydoc/read?myQueryParam", "docId", "mydoc"); // test trailing slashes testMatch("/docs/mydoc/", "/docs/mydoc/"); testMatch("/docs/{docId}/", "/docs/mydoc", "docId", "mydoc"); testMatch("/docs/{docId}/{op}/", "/docs/mydoc/read", "docId", "mydoc", "op", "read"); testMatch("/docs/{docId}/{op}/{allowed}/", "/docs/mydoc/read/true", "docId", "mydoc", "op", "read", "allowed", "true"); testMatch("/docs/{docId}/operation/{op}/", "/docs/mydoc/operation/read", "docId", "mydoc", "op", "read"); testMatch("/docs/{docId}/read/", "/docs/mydoc/read", "docId", "mydoc"); // test straight replacement of template testMatch("/{foo}", "/bob", "foo", "bob"); testMatch("{foo}", "/bob", "foo", "bob"); testMatch("/{foo}/", "/bob", "foo", "bob"); // test that brackets (and the possibility of recursive templates) don't mess up the matching testMatch("/{value}", "/{value}", "value", "{value}"); } @Test public void wildCardTests() { // wildcard matches testMatch("/*", "/docs/mydoc/test","*","docs/mydoc/test"); testMatch("/docs/*", "/docs/mydoc/test","*","mydoc/test"); testMatch("/docs*", "/docs/mydoc/test","*","/mydoc/test"); testMatch("/docs/*", "/docs/mydoc/test/test2","*","mydoc/test/test2"); testMatch("/docs/{docId}/*", "/docs/mydoc/test", "docId", "mydoc", "*","test"); testMatch("/docs/{docId}/*", "/docs/mydoc/", "docId", "mydoc", "*",""); testMatch("/docs/{docId}/*", "/docs/mydoc/test/test2/test3/test4", "docId", "mydoc", "*","test/test2/test3/test4"); testMatch("/docs/{docId}/{docId2}/*", "/docs/mydoc/test/test2/test3/test4", "docId", "mydoc","docId2", "test", "*","test2/test3/test4"); } @Test(expected=IllegalArgumentException.class) public void testNullPath() { PathTemplate.create(null); } @Test public void testDetectDuplicates() { final TreeSet<PathTemplate> seen = new TreeSet<>(); seen.add(PathTemplate.create("/bob/{foo}")); Assert.assertTrue(seen.contains(PathTemplate.create("/bob/{ak}"))); Assert.assertFalse(seen.contains(PathTemplate.create("/bob/{ak}/other"))); } private void testMatch(final String template, final String path, final String ... pathParams) { Assert.assertEquals(0, pathParams.length % 2); final Map<String, String> expected = new HashMap<>(); for(int i = 0; i < pathParams.length; i+=2) { expected.put(pathParams[i], pathParams[i+1]); } final Map<String, String> params = new HashMap<>(); PathTemplate pathTemplate = PathTemplate.create(template); Assert.assertTrue("Failed. Template: " + pathTemplate, pathTemplate.matches(path, params)); Assert.assertEquals(expected, params); if(template.endsWith("*") && ! template.contains("{")){ Assert.assertEquals("Failed. Template: "+pathTemplate+"Must have a part representing the wildcard",1,new PathTemplateFriend(pathTemplate).getPartAmount()); } } static class PathTemplateFriend { private final PathTemplate template; PathTemplateFriend(PathTemplate template) { this.template = template; } int getPartAmount() { return template.parts.size(); } } }