/*
* Copyright 2012-2016 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 org.springframework.hateoas.core;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import org.junit.Test;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* Unit tests for {@link AnnotationMappingDiscoverer}.
*
* @author Oliver Gierke
* @author Kevin Conaway
* @author Mark Paluch
*/
public class AnnotationMappingDiscovererUnitTest {
MappingDiscoverer discoverer = new AnnotationMappingDiscoverer(RequestMapping.class);
@Test(expected = IllegalArgumentException.class)
public void rejectsNullAnnotation() {
new AnnotationMappingDiscoverer(null);
}
@Test
public void discoversTypeLevelMapping() {
assertThat(discoverer.getMapping(MyController.class), is("/type"));
}
@Test
public void discoversMethodLevelMapping() throws Exception {
Method method = MyController.class.getMethod("method");
assertThat(discoverer.getMapping(method), is("/type/method"));
}
@Test
public void returnsNullForNonExistentTypeLevelMapping() {
assertThat(discoverer.getMapping(ControllerWithoutTypeLevelMapping.class), is(nullValue()));
}
@Test
public void resolvesMethodLevelMappingWithoutTypeLevelMapping() throws Exception {
Method method = ControllerWithoutTypeLevelMapping.class.getMethod("method");
assertThat(discoverer.getMapping(method), is("/method"));
}
@Test
public void resolvesMethodLevelMappingWithSlashRootMapping() throws Exception {
Method method = SlashRootMapping.class.getMethod("method");
assertThat(discoverer.getMapping(method), is("/method"));
}
/**
* @see #46
*/
@Test
public void treatsMissingMethodMappingAsEmptyMapping() throws Exception {
Method method = MyController.class.getMethod("noMethodMapping");
assertThat(discoverer.getMapping(method), is("/type"));
}
/**
* @see #114
*/
@Test
public void detectsClassMappingOnSuperType() throws Exception {
Method method = ChildController.class.getMethod("mapping");
assertThat(discoverer.getMapping(method), is("/parent/child"));
}
/**
* @see #114
*/
@Test
public void includesTypeMappingFromChildClass() throws Exception {
Method method = ParentWithMethod.class.getMethod("mapping");
assertThat(discoverer.getMapping(ChildWithTypeMapping.class, method), is("/child/parent"));
}
/**
* @see #269
*/
@Test
public void handlesSlashes() throws Exception {
Method method = ControllerWithoutSlashes.class.getMethod("noslash");
assertThat(discoverer.getMapping(method), is("slashes/noslash"));
method = ControllerWithoutSlashes.class.getMethod("withslash");
assertThat(discoverer.getMapping(method), is("slashes/withslash"));
method = ControllerWithTrailingSlashes.class.getMethod("noslash");
assertThat(discoverer.getMapping(method), is("trailing/noslash"));
method = ControllerWithTrailingSlashes.class.getMethod("withslash");
assertThat(discoverer.getMapping(method), is("trailing/withslash"));
}
/**
* @see #269
*/
@Test
public void removesMultipleSlashes() throws Exception {
Method method = ControllerWithMultipleSlashes.class.getMethod("withslash");
assertThat(discoverer.getMapping(method), is("trailing/withslash"));
}
/**
* @see #186
*/
@Test
public void usesFirstMappingInCaseMultipleOnesAreDefined() throws Exception {
Method method = MultipleMappingsController.class.getMethod("method");
assertThat(discoverer.getMapping(method), is("/type/method"));
}
/**
* @see #471
*/
@Test
public void discoversMethodLevelMappingUsingComposedAnnotation() throws Exception {
Method method = MyController.class.getMethod("methodWithComposedAnnotation");
assertThat(discoverer.getMapping(method), is("/type/otherMethod"));
}
@RequestMapping("/type")
interface MyController {
@RequestMapping("/method")
void method();
@GetMapping("/otherMethod")
void methodWithComposedAnnotation();
@RequestMapping
void noMethodMapping();
}
interface ControllerWithoutTypeLevelMapping {
@RequestMapping("/method")
void method();
}
@RequestMapping("/")
interface SlashRootMapping {
@RequestMapping("/method")
void method();
}
@RequestMapping("/parent")
interface ParentController {
}
interface ChildController extends ParentController {
@RequestMapping("/child")
void mapping();
}
interface ParentWithMethod {
@RequestMapping("/parent")
void mapping();
}
@RequestMapping("/child")
interface ChildWithTypeMapping extends ParentWithMethod {}
@RequestMapping("slashes")
interface ControllerWithoutSlashes {
@RequestMapping("noslash")
void noslash();
@RequestMapping("/withslash")
void withslash();
}
@RequestMapping("trailing/")
interface ControllerWithTrailingSlashes {
@RequestMapping("noslash")
void noslash();
@RequestMapping("/withslash")
void withslash();
}
@RequestMapping("trailing///")
interface ControllerWithMultipleSlashes {
@RequestMapping("////withslash")
void withslash();
}
@RequestMapping({ "/type", "/typeAlias" })
interface MultipleMappingsController {
@RequestMapping({ "/method", "/methodAlias" })
void method();
}
}