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

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

/***
* 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.contains;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;

import java.util.EnumSet;
import java.util.List;

import javax.annotation.Resource;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import br.com.caelum.vraptor.Delete;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Head;
import br.com.caelum.vraptor.Options;
import br.com.caelum.vraptor.Patch;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.core.Converters;
import br.com.caelum.vraptor.http.ParameterNameProvider;
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;

public class PathAnnotationRoutesParserTest {

  private Proxifier proxifier;
  private @Mock Converters converters;
  private NoTypeFinder typeFinder;
  private @Mock Router router;
  private @Mock ParameterNameProvider nameProvider;

  private PathAnnotationRoutesParser parser;

  @Before
  public void setup() {
    MockitoAnnotations.initMocks(this);

  this.proxifier = new JavassistProxifier(new ObjenesisInstanceCreator());
  this.typeFinder = new NoTypeFinder();

  when(router.builderFor(anyString())).thenAnswer(new Answer<DefaultRouteBuilder>() {

      public DefaultRouteBuilder answer(InvocationOnMock invocation) throws Throwable {
        return new DefaultRouteBuilder(proxifier, typeFinder, converters, nameProvider, new JavaEvaluator(), (String) invocation.getArguments()[0]);
      }
    });

  parser = new PathAnnotationRoutesParser(router);
  }

  @Resource
  @Path("/prefix")
  public static class PathAnnotatedController {
    public void withoutPath() {
    }
    @Path("/absolutePath")
    public void withAbsolutePath() {
    }
    @Path("relativePath")
    public void withRelativePath() {
    }
    @Path("")
    public void withEmptyPath() {
    }
  }

  @Resource
  @Path("/prefix")
  public static class GetAnnotatedController {
    public void withoutPath() {
    }
    @Get("/absolutePath")
    public void withAbsolutePath() {
    }
    @Get("relativePath")
    public void withRelativePath() {
    }
    @Get("")
    public void withEmptyPath() {
    }
  }

  @Resource
  public static class WrongGetAnnotatedController {
    @Path("/some") @Get("/other")
    public void withAmbiguousDeclaration() {
    }
  }

  @Resource
  @Path("/endSlash/")
  public static class EndSlashAnnotatedController {
    public void withoutPath() {
    }
    @Path("/absolutePath")
    public void withAbsolutePath() {
    }
    @Path("relativePath")
    public void withRelativePath() {
    }
    @Path("")
    public void withEmptyPath() {
    }
  }

  @Resource
  @Path("/endSlash/")
  public static class EndSlashAnnotatedGetController {
    public void withoutPath() {
    }
    @Get("/absolutePath")
    public void withAbsolutePath() {
    }
    @Get("relativePath")
    public void withRelativePath() {
    }
    @Get("")
    public void withEmptyPath() {
    }
  }

  @Resource
  @Path("prefix")
  public static class WrongPathAnnotatedController {
    public void noSlashPath() {
    }
  }

  @Resource
  @Path({"/prefix", "/prefix2"})
  public static class MoreThanOnePathAnnotatedController {
    public void noSlashPath() {
    }
  }

  @Test(expected = IllegalArgumentException.class)
  public void addsAPrefixToMethodsWhenTheControllerHasMoreThanOneAnnotatedPath() throws Exception {
    parser.rulesFor(new DefaultResourceClass(MoreThanOnePathAnnotatedController.class));
  }

  @Test
  public void addsAPrefixToMethodsWhenTheControllerAndTheMethodAreAnnotatedWithRelativePath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(PathAnnotatedController.class));
    Route route = getRouteMatching(routes, "/prefix/relativePath");

    assertThat(route, canHandle(PathAnnotatedController.class, "withRelativePath"));

  }

  @Test
  public void addsAPrefixToMethodsWhenTheControllerEndsWithSlashAndTheMethodAreAnnotatedWithRelativePath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(EndSlashAnnotatedController.class));
    Route route = getRouteMatching(routes, "/endSlash/relativePath");

    assertThat(route, canHandle(EndSlashAnnotatedController.class, "withRelativePath"));

  }
  @Test
  public void addsAPrefixToMethodsWhenTheControllerEndsWithSlashAndTheMethodAreAnnotatedWithAbsolutePath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(EndSlashAnnotatedController.class));
    Route route = getRouteMatching(routes, "/endSlash/absolutePath");

    assertThat(route, canHandle(EndSlashAnnotatedController.class, "withAbsolutePath"));

  }
  @Test
  public void addsAPrefixToMethodsWhenTheControllerEndsWithSlashAndTheMethodAreAnnotatedWithEmptyPath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(EndSlashAnnotatedController.class));
    Route route = getRouteMatching(routes, "/endSlash/");

    assertThat(route, canHandle(EndSlashAnnotatedController.class, "withEmptyPath"));

  }
  public void addsAPrefixToMethodsWhenTheControllerEndsWithSlashAndTheMethodAreNotAnnotated() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(EndSlashAnnotatedController.class));
    Route route = getRouteMatching(routes, "/endSlash/withoutPath");

    assertThat(route, canHandle(EndSlashAnnotatedController.class, "withoutPath"));

  }
  @Test
  public void addsAPrefixToMethodsWhenTheControllerAndTheMethodAreAnnotatedWithAbsolutePath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(PathAnnotatedController.class));
    Route route = getRouteMatching(routes, "/prefix/absolutePath");

    assertThat(route, canHandle(PathAnnotatedController.class, "withAbsolutePath"));


  }
  @Test
  public void addsAPrefixToMethodsWhenTheControllerAndTheMethodAreAnnotatedWithEmptyPath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(PathAnnotatedController.class));
    Route route = getRouteMatching(routes, "/prefix");

    assertThat(route, canHandle(PathAnnotatedController.class, "withEmptyPath"));


  }
  @Test
  public void addsAPrefixToMethodsWhenTheControllerIsAnnotatedWithPath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(PathAnnotatedController.class));
    Route route = getRouteMatching(routes, "/prefix/withoutPath");

    assertThat(route, canHandle(PathAnnotatedController.class, "withoutPath"));

  }
  @Test
  public void findsTheCorrectAnnotatedMethodIfThereIsNoWebMethodAnnotationPresent() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/clients");

    assertThat(route, canHandle(ClientsController.class, "list"));


  }


  @Test
  public void suportsTheDefaultNameForANonAnnotatedMethod() throws SecurityException,
    NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/clients/add");

    assertThat(route, canHandle(ClientsController.class, "add"));


  }

  @Test
  public void ignoresTheControllerSuffixForANonAnnotatedMethod() throws SecurityException,
    NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/clients/add");

    assertThat(route, canHandle(ClientsController.class, "add"));


  }
  @Test
  public void addsASlashWhenUserForgotIt() throws SecurityException,  NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/noSlash");

    assertThat(route, canHandle(ClientsController.class, "noSlash"));


  }

  @Test
  public void matchesWhenUsingAWildcard() throws SecurityException, NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/move/second/child");

    assertThat(route, canHandle(ClientsController.class, "move"));

  }

  @Test
  public void dontRegisterRouteIfMethodIsNotPublic() {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/protectMe");
    assertNull(route);

  }

  @Test
  public void dontRegisterRouteIfMethodIsStatic() {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/staticMe");
    assertNull(route);

  }

  @br.com.caelum.vraptor.Resource
  public static class ClientsController {
  @Path("/move/*/child")
  public void move() {
  }

  @Path("noSlash")
  public void noSlash() {
  }


  @Path("/clients")
  public void list() {
  }

  @Path("/clients/remove")
  @Delete
  public void remove() {
  }

  @Path("/clients/head")
  @Head
  public void head() {
  }

  @Options("/clients/options")
  public void options() {
  }
 
  @Patch("/clients/update")
  public void update() {
  }
 
  public void add() {
  }

  @Path("/protectMe")
  protected void protectMe() {
  }

  @Path({"/path1", "/path2"})
  public void manyPaths() {
  }


  @Path("/staticMe")
  public static void staticMe() {
  }

  public void toInherit() {
  }
  }



  @br.com.caelum.vraptor.Resource
  public static class NoPath {

  @Path( {})
  public void noPaths() {
  }

  }
  @Test(expected=IllegalArgumentException.class)
  public void shouldThrowExceptionIfPathAnnotationHasEmptyArray()
    throws Exception {
  parser.rulesFor(new DefaultResourceClass(NoPath.class));
  }


  @Test
  public void shouldFindNonAnnotatedNonStaticPublicMethodWithComponentNameInVariableCamelCaseConventionAsURI()
    throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/clients/add");

    assertThat(route, canHandle(ClientsController.class, "add"));


  }

  @Test
  public void shouldFindSeveralPathsForMethodWithManyValue()
    throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));

    Route route = getRouteMatching(routes, "/path1");
    assertThat(route, canHandle(ClientsController.class, "manyPaths"));
    Route route2 = getRouteMatching(routes, "/path2");
    assertThat(route2, canHandle(ClientsController.class, "manyPaths"));


  }




  @Test
  public void shouldNotMatchIfAResourceHasTheWrongWebMethod() throws SecurityException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/clients/remove");

    assertThat(route.allowedMethods(), not(contains(HttpMethod.POST)));

  }

  @Test
  public void shouldAcceptAResultWithASpecificWebMethod() throws SecurityException, NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/clients/head");

    assertThat(route.allowedMethods(), is(EnumSet.of(HttpMethod.HEAD)));

  }


  @Test
  public void shouldAcceptAResultWithOptionsWebMethod() throws SecurityException, NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/clients/options");

    assertThat(route.allowedMethods(), is(EnumSet.of(HttpMethod.OPTIONS)));
  }
 
  @Test
  public void shouldAcceptAResultWithPatchWebMethod() throws SecurityException, NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(ClientsController.class));
    Route route = getRouteMatching(routes, "/clients/update");

    assertThat(route.allowedMethods(), is(EnumSet.of(HttpMethod.PATCH)));
  }
 
  static class NiceClients extends ClientsController {

    @Override
    public void add() {
      super.add();
    }
  }

  @Test
  public void findsInheritedMethodsWithDefaultNames() throws SecurityException, NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(NiceClients.class));
    Route route = getRouteMatching(routes, "/niceClients/toInherit");

    assertTrue(route.canHandle(NiceClients.class, ClientsController.class.getDeclaredMethod("toInherit")));
  }
  @Test
  public void supportMethodOverriding() throws SecurityException, NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(NiceClients.class));
    Route route = getRouteMatching(routes, "/niceClients/add");

    assertThat(route, canHandle(NiceClients.class, "add"));
  }

  @Post
  static class AnnotatedController {

    public void test() {}
    @Get
    public void overridden() {}
  }

  @Test
  public void supportTypeHttpMethodAnnotation() throws SecurityException, NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(AnnotatedController.class));
    Route route = getRouteMatching(routes, "/annotated/test");
    assertThat(route.allowedMethods(), is(EnumSet.of(HttpMethod.POST)));
  }

  @Test
  public void supportOverrideTypeHttpMethodAnnotation() throws SecurityException, NoSuchMethodException {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(AnnotatedController.class));
    Route route = getRouteMatching(routes, "/annotated/overridden");
    assertThat(route.allowedMethods(), is(EnumSet.of(HttpMethod.GET)));
  }

  private Route getRouteMatching(List<Route> routes, String uri) {
    for (Route route : routes) {
      if (route.canHandle(uri)) {
        return route;
      }
    }
    return null;
  }

  private Matcher<Route> canHandle(final Class<?> type, final String method) {
    return new TypeSafeMatcher<Route>() {

      @Override
      protected void describeMismatchSafely(Route item, Description mismatchDescription) {
      }

      @Override
      protected boolean matchesSafely(Route item) {
        try {
          return item.canHandle(type, type.getDeclaredMethod(method));
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }

      public void describeTo(Description description) {
        description.appendText("a route which can handle ").appendValue(type).appendText(".").appendValue(method);
      }
    };
  }

  @Test
  public void addsAPrefixToMethodsWhenTheGetControllerAndTheMethodAreAnnotatedWithRelativePath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(GetAnnotatedController.class));
    Route route = getRouteMatching(routes, "/prefix/relativePath");

    assertThat(route, canHandle(GetAnnotatedController.class, "withRelativePath"));
  }

  @Test
  public void priorityForGetAnnotationShouldBeDefault() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(GetAnnotatedController.class));
    Route route = getRouteMatching(routes, "/prefix/relativePath");

    assertThat(route.getPriority(), is(Path.DEFAULT));
  }

  @Test
  public void addsAPrefixToMethodsWhenTheGetControllerEndsWithSlashAndTheMethodAreAnnotatedWithRelativePath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(EndSlashAnnotatedGetController.class));
    Route route = getRouteMatching(routes, "/endSlash/relativePath");

    assertThat(route, canHandle(EndSlashAnnotatedGetController.class, "withRelativePath"));
  }


  @Test
  public void addsAPrefixToMethodsWhenTheGetControllerEndsWithSlashAndTheMethodAreAnnotatedWithAbsolutePath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(EndSlashAnnotatedGetController.class));
    Route route = getRouteMatching(routes, "/endSlash/absolutePath");

    assertThat(route, canHandle(EndSlashAnnotatedGetController.class, "withAbsolutePath"));
  }


  @Test
  public void addsAPrefixToMethodsWhenTheGetControllerAndTheMethodAreAnnotatedWithAbsolutePath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(GetAnnotatedController.class));
    Route route = getRouteMatching(routes, "/prefix/absolutePath");

    assertThat(route, canHandle(GetAnnotatedController.class, "withAbsolutePath"));
  }

  @Test
  public void addsAPrefixToMethodsWhenTheGetControllerIsAnnotatedWithPath() throws Exception {
    List<Route> routes = parser.rulesFor(new DefaultResourceClass(GetAnnotatedController.class));
    Route route = getRouteMatching(routes, "/prefix/withoutPath");

    assertThat(route, canHandle(GetAnnotatedController.class, "withoutPath"));
  }

  @Test(expected=IllegalArgumentException.class)
  public void throwsExceptionWhenTheGetControllerHasAmbiguousDeclaration() throws Exception {
    parser.rulesFor(new DefaultResourceClass(WrongGetAnnotatedController.class));
  }

}
TOP

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

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.