Package br.com.caelum.vraptor.http.route

Source Code of br.com.caelum.vraptor.http.route.MyCustomResource

/***
* Copyright (c) 2009 Caelum - www.caelum.com.br/opensource
* All rights reserved.
*
* 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 br.com.caelum.vraptor.http.route;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.lang.reflect.Method;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.junit.Before;
import org.junit.Test;

import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.core.Converters;
import br.com.caelum.vraptor.http.DefaultParameterNameProvider;
import br.com.caelum.vraptor.http.ParameterNameProvider;
import br.com.caelum.vraptor.http.VRaptorRequest;
import br.com.caelum.vraptor.interceptor.DefaultTypeNameExtractor;
import br.com.caelum.vraptor.interceptor.VRaptorMatchers;
import br.com.caelum.vraptor.proxy.JavassistProxifier;
import br.com.caelum.vraptor.proxy.ObjenesisInstanceCreator;
import br.com.caelum.vraptor.proxy.Proxifier;
import br.com.caelum.vraptor.resource.DefaultResourceClass;
import br.com.caelum.vraptor.resource.HttpMethod;
import br.com.caelum.vraptor.resource.ResourceClass;
import br.com.caelum.vraptor.resource.ResourceMethod;

/**
* Those are more likely to be acceptance than unit tests.
* @author guilherme silveira
*/
public class DefaultRouterTest {

  private Proxifier proxifier;
  private DefaultRouter router;
  private VRaptorRequest request;
  private ResourceMethod method;
  private Converters converters;
  private ParameterNameProvider nameProvider;

  @Before
  public void setup() {
    this.request = new VRaptorRequest(mock(HttpServletRequest.class));
    this.proxifier = new JavassistProxifier(new ObjenesisInstanceCreator());
    this.method = mock(ResourceMethod.class);
    this.converters = mock(Converters.class);
    this.nameProvider = new DefaultParameterNameProvider(new DefaultTypeNameExtractor());

    router = new DefaultRouter(new NoRoutesConfiguration(), proxifier, new NoTypeFinder(), converters, nameProvider, new JavaEvaluator());
  }

  @Test
  public void shouldThrowResourceNotFoundExceptionWhenNoRoutesMatchTheURI() throws Exception {
    Route route = mock(Route.class);
    when(route.canHandle(anyString())).thenReturn(false);

    router.add(route);
   
    try {
      router.parse("any uri", HttpMethod.DELETE, request);
      fail("ResourceNotFoundException is expected");
    } catch (ResourceNotFoundException e) {
     
    }
  }
 
  @Test
  public void shouldThrowMethodNotAllowedExceptionWhenNoRoutesMatchTheURIWithGivenHttpMethod() throws Exception {
    Route route = mock(Route.class);
    when(route.canHandle(anyString())).thenReturn(true);
    when(route.allowedMethods()).thenReturn(EnumSet.of(HttpMethod.GET));

    router.add(route);
   
    try {
      router.parse("any uri", HttpMethod.DELETE, request);
      fail("MethodNotAllowedException is expected");
    } catch (MethodNotAllowedException e) {
      assertThat(e.getAllowedMethods(), is((Set<HttpMethod>)EnumSet.of(HttpMethod.GET)));
    }
  }

  @Test
  public void shouldObeyPriorityOfRoutes() throws Exception {
    Route first = mock(Route.class);
    Route second = mock(Route.class);
   
    ResourceMethod method2 = second.resourceMethod(request, "second");
   
    router.add(second);
    router.add(first);

    when(first.getPriority()).thenReturn(Path.HIGH);
    when(second.getPriority()).thenReturn(Path.LOW);
   
    EnumSet<HttpMethod> get = EnumSet.of(HttpMethod.GET);
    when(first.allowedMethods()).thenReturn(get);
    when(second.allowedMethods()).thenReturn(get);
   
    when(first.canHandle(anyString())).thenReturn(false);
    when(second.canHandle(anyString())).thenReturn(true);
   
    ResourceMethod found = router.parse("anything", HttpMethod.GET, request);
    assertThat(found, is(method2));
  }

  @Test
  public void acceptsASingleMappingRule() throws SecurityException, NoSuchMethodException {
    Route route = mock(Route.class);
   
    when(route.canHandle("/clients/add")).thenReturn(true);
    when(route.allowedMethods()).thenReturn(EnumSet.of(HttpMethod.POST));
    when(route.resourceMethod(request, "/clients/add")).thenReturn(method);

    router.add(route);
    ResourceMethod found = router.parse("/clients/add", HttpMethod.POST, request);
   
    assertThat(found, is(equalTo(method)));
    verify(route, atLeastOnce()).getPriority();
  }


  @Test
  public void passesTheWebMethod() throws SecurityException, NoSuchMethodException {
    HttpMethod delete = HttpMethod.DELETE;
    Route route = mock(Route.class);
   
    when(route.canHandle("/clients/add")).thenReturn(true);
    when(route.allowedMethods()).thenReturn(EnumSet.of(delete));
    when(route.resourceMethod(request, "/clients/add")).thenReturn(method);

    router.add(route);
    ResourceMethod found = router.parse("/clients/add", delete, request);
    assertThat(found, is(equalTo(method)));
    verify(route, atLeastOnce()).getPriority();
  }
 
  @Test
  public void usesTheFirstRegisteredRuleMatchingThePattern() throws SecurityException, NoSuchMethodException {
    Route route = mock(Route.class);
    Route second = mock(Route.class, "second");
   
    when(route.canHandle("/clients/add")).thenReturn(true);
    when(second.canHandle("/clients/add")).thenReturn(true);

    EnumSet<HttpMethod> all = EnumSet.allOf(HttpMethod.class);

    when(route.allowedMethods()).thenReturn(all);
    when(second.allowedMethods()).thenReturn(all);

    when(route.resourceMethod(request, "/clients/add")).thenReturn(method);
    when(route.getPriority()).thenReturn(Path.HIGHEST);
    when(second.getPriority()).thenReturn(Path.LOWEST);

    router.add(route);
    router.add(second);
   
    ResourceMethod found = router.parse("/clients/add", HttpMethod.POST, request);
    assertThat(found, is(equalTo(method)));
  }
  @Test
  public void throwsExceptionIfMoreThanOneUriMatchesWithSamePriority() {
    Route route = mock(Route.class);
    Route second = mock(Route.class, "second");
   
    when(route.canHandle("/clients/add")).thenReturn(true);
    when(second.canHandle("/clients/add")).thenReturn(true);

    EnumSet<HttpMethod> all = EnumSet.allOf(HttpMethod.class);

    when(route.allowedMethods()).thenReturn(all);
    when(second.allowedMethods()).thenReturn(all);

    when(route.getPriority()).thenReturn(Path.DEFAULT);
    when(second.getPriority()).thenReturn(Path.DEFAULT);
   
    router.add(route);
    router.add(second);
   
    try {
      router.parse("/clients/add", HttpMethod.POST, request);
      fail("IllegalStateException expected");
    } catch (IllegalStateException e) {
    }
  }

  @Test
  public void acceptsAnHttpMethodLimitedMappingRule() throws NoSuchMethodException {
    new Rules(router) {
      @Override
      public void routes() {
        routeFor("/clients/add").with(HttpMethod.POST).is(MyControl.class).add(null);
      }
    };
    assertThat(router.parse("/clients/add", HttpMethod.POST, request), is(VRaptorMatchers.resourceMethod(method(
        "add", Dog.class))));
  }

  private Method method(String methodName, Class<?>... params) throws SecurityException, NoSuchMethodException {
    return MyControl.class.getDeclaredMethod(methodName, params);
  }

  @Test
  public void acceptsAnHttpMethodLimitedMappingRuleWithBothMethods() throws NoSuchMethodException {
    new Rules(router) {
      @Override
      public void routes() {
        routeFor("/clients/add").with(HttpMethod.POST).with(HttpMethod.GET).is(MyControl.class).add(null);
      }
    };
   
    assertThat(router.parse("/clients/add", HttpMethod.POST, request), is(VRaptorMatchers.resourceMethod(method(
        "add", Dog.class))));
   
    assertThat(router.parse("/clients/add", HttpMethod.GET, request), is(VRaptorMatchers.resourceMethod(method(
        "add", Dog.class))));
  }


  class Dog {
    private Long id;

    public void setId(Long id) {
      this.id = id;
    }

    public Long getId() {
      return id;
    }
  }

  @br.com.caelum.vraptor.Resource
  public static class MyControl {
    public void add(Dog object) {
    }

    public void unknownMethod() {
    }

    public void list() {
    }

    public void show(Dog dog) {
    }
  }

  @Resource
  public static class MyResource {
    public void notAnnotated() {
    }

    @Path("/myPath")
    public void customizedPath() {
    }

    @Path("/*/customPath")
    public void starPath() {
    }
  }

  @br.com.caelum.vraptor.Resource
  class InheritanceExample extends MyResource {
  }

  @Test
  public void usesAsteriskBothWays() throws NoSuchMethodException {
    registerRulesFor(MyResource.class);
    final Method method = MyResource.class.getMethod("starPath");
    String url = router.urlFor(MyResource.class, method, new Object[] {});
    assertThat(router.parse(url, HttpMethod.POST, null).getMethod(), is(equalTo(method)));
  }

  private void registerRulesFor(Class<?> type) {
    RoutesParser parser = new PathAnnotationRoutesParser(router);
   
    ResourceClass resourceClass = new DefaultResourceClass(type);
    List<Route> rules = parser.rulesFor(resourceClass);
    for (Route route : rules) {
      router.add(route);
    }
  }

  @Test
  public void canTranslateAInheritedResourceBothWays() throws NoSuchMethodException {
    registerRulesFor(MyResource.class);
    registerRulesFor(InheritanceExample.class);
    final Method method = MyResource.class.getMethod("notAnnotated");
    String url = router.urlFor(InheritanceExample.class, method, new Object[] {});
    assertThat(router.parse(url, HttpMethod.POST, null).getMethod(), is(equalTo(method)));
  }

  @Test
  public void canTranslateAnnotatedMethodBothWays() throws NoSuchMethodException {
    registerRulesFor(MyResource.class);
    final Method method = MyResource.class.getMethod("customizedPath");
    String url = router.urlFor(MyResource.class, method, new Object[] {});
    assertThat(router.parse(url, HttpMethod.POST, null).getMethod(), is(equalTo(method)));
  }
}

class MyCustomResource {
  public void notAnnotated() {
  }
}
TOP

Related Classes of br.com.caelum.vraptor.http.route.MyCustomResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.