package br.com.caelum.vraptor.view;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;
import java.lang.reflect.Method;
import javax.servlet.ServletContext;
import net.vidageek.mirror.dsl.Mirror;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import br.com.caelum.vraptor.http.route.Router;
public class LinkToHandlerTest {
private @Mock ServletContext context;
private @Mock Router router;
private LinkToHandler handler;
private Method method2params;
private Method method1param;
private Method anotherMethod;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
this.handler = new LinkToHandler(context, router);
when(context.getContextPath()).thenReturn("/path");
this.method2params = new Mirror().on(TestController.class).reflect().method("method").withArgs(String.class, int.class);
this.method1param = new Mirror().on(TestController.class).reflect().method("method").withArgs(String.class);
this.anotherMethod = new Mirror().on(TestController.class).reflect().method("anotherMethod").withArgs(String.class, int.class);
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenInvocationIsIncomplete() {
//${linkTo[TestController]}
handler.get(TestController.class).toString();
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenInvokingInexistantMethod() {
//${linkTo[TestController].nonExists}
handler.get(TestController.class).get("nonExists").toString();
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenMethodIsAmbiguous() {
//${linkTo[TestController].method}
handler.get(TestController.class).get("method").toString();
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenUsingParametersOfWrongTypes() {
//${linkTo[TestController].method[123]}
handler.get(TestController.class).get("method").get(123).toString();
}
@Test
public void shouldReturnWantedUrlWithoutArgs() {
when(router.urlFor(TestController.class, anotherMethod, new Object[2])).thenReturn("/expectedURL");
//${linkTo[TestController].anotherMethod}
String uri = handler.get(TestController.class).get("anotherMethod").toString();
assertThat(uri, is("/path/expectedURL"));
}
@Test
public void shouldReturnWantedUrlWithParamArgs() {
String a = "test";
int b = 3;
when(router.urlFor(TestController.class, method2params, new Object[]{a, b})).thenReturn("/expectedURL");
//${linkTo[TestController].method['test'][3]}
String uri = handler.get(TestController.class).get("method").get(a).get(b).toString();
assertThat(uri, is("/path/expectedURL"));
}
@Test
public void shouldReturnWantedUrlWithPartialParamArgs() {
String a = "test";
when(router.urlFor(TestController.class, anotherMethod, new Object[]{a, null})).thenReturn("/expectedUrl");
//${linkTo[TestController].anotherMethod['test']}
String uri = handler.get(TestController.class).get("anotherMethod").get(a).toString();
assertThat(uri, is("/path/expectedUrl"));
}
@Test
public void shouldReturnWantedUrlForOverrideMethodWithParamArgs() throws NoSuchMethodException, SecurityException {
String a = "test";
when(router.urlFor(SubGenericController.class, SubGenericController.class.getDeclaredMethod("method", new Class[]{String.class}), new Object[]{a})).thenReturn("/expectedURL");
//${linkTo[TestSubGenericController].method['test']}]
String uri = handler.get(SubGenericController.class).get("method").get(a).toString();
assertThat(uri, is("/path/expectedURL"));
}
@Test
public void shouldReturnWantedUrlForOverrideMethodWithParialParamArgs() throws SecurityException, NoSuchMethodException {
String a = "test";
when(router.urlFor(SubGenericController.class, SubGenericController.class.getDeclaredMethod("anotherMethod", new Class[]{String.class, String.class}), new Object[]{a, null})).thenReturn("/expectedURL");
//${linkTo[TestSubGenericController].anotherMethod['test']}]
String uri = handler.get(SubGenericController.class).get("anotherMethod").get(a).toString();
assertThat(uri, is("/path/expectedURL"));
}
@Test
public void shouldUseExactlyMatchedMethodIfTheMethodIsOverloaded() {
String a = "test";
when(router.urlFor(TestController.class, method1param, a)).thenReturn("/expectedUrl");
//${linkTo[TestController].method['test']}
String uri = handler.get(TestController.class).get("method").get(a).toString();
assertThat(uri, is("/path/expectedUrl"));
}
@Test(expected = IllegalArgumentException.class)
public void shouldThrowExceptionWhenPassingMoreArgsThanMethodSupports() {
String a = "test";
int b = 3;
String c = "anotherTest";
//${linkTo[TestController].anotherMethod['test'][3]['anotherTest']}
handler.get(TestController.class).get("anotherMethod").get(a).get(b).get(c).toString();
}
static class TestController {
void method(String a, int b) {
}
void method(String a) {
}
void anotherMethod(String a, int b) {
}
}
}