1 package com.atlassian.plugins.rest.common.validation;
2
3 import com.atlassian.plugins.rest.common.interceptor.MethodInvocation;
4 import com.atlassian.sal.api.message.I18nResolver;
5 import com.sun.jersey.api.core.HttpContext;
6 import com.sun.jersey.api.core.HttpResponseContext;
7 import com.sun.jersey.api.model.AbstractResourceMethod;
8 import com.sun.jersey.api.model.Parameter;
9 import org.junit.Before;
10 import org.junit.Test;
11 import org.mockito.ArgumentCaptor;
12
13 import javax.validation.MessageInterpolator;
14 import javax.validation.constraints.NotNull;
15 import javax.validation.constraints.Size;
16 import javax.ws.rs.core.Response;
17 import java.lang.reflect.InvocationTargetException;
18 import java.util.Collections;
19
20 import static junit.framework.Assert.assertTrue;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertNotNull;
23 import static org.mockito.Matchers.anyObject;
24 import static org.mockito.Matchers.eq;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.times;
28 import static org.mockito.Mockito.verify;
29 import static org.mockito.Mockito.when;
30
31 public class ValidationInterceptorTest
32 {
33 private I18nResolver resolver;
34 private ValidationInterceptor interceptor;
35 private MethodInvocation methodInvocation;
36 private AbstractResourceMethod method;
37 private ArgumentCaptor<Response> responseCaptor;
38 private HttpResponseContext response;
39
40 @Before
41 public void setUp()
42 {
43 resolver = mock(I18nResolver.class);
44 interceptor = new ValidationInterceptor(resolver);
45 methodInvocation = mock(MethodInvocation.class);
46 HttpContext httpContext = mock(HttpContext.class);
47 response = mock(HttpResponseContext.class);
48 method = mock(AbstractResourceMethod.class);
49
50
51 when(httpContext.getResponse()).thenReturn(response);
52 when(methodInvocation.getHttpContext()).thenReturn(httpContext);
53 when(methodInvocation.getMethod()).thenReturn(method);
54
55 responseCaptor = ArgumentCaptor.forClass(Response.class);
56 }
57
58 @Test
59 public void testInterceptPass() throws IllegalAccessException, InvocationTargetException
60 {
61 ValidatableObject obj = new ValidatableObject("jim");
62
63 when(methodInvocation.getParameters()).thenReturn(new Object[] {obj});
64 Parameter parameter = mock(Parameter.class);
65 when(parameter.getSource()).thenReturn(Parameter.Source.ENTITY);
66 when(method.getParameters()).thenReturn(Collections.<Parameter>singletonList(parameter));
67
68 interceptor.intercept(methodInvocation);
69 verify(methodInvocation, times(1)).invoke();
70
71 verify(response, never()).getEntity();
72 }
73
74 @Test
75 public void testInterceptPassNoAnnotations() throws IllegalAccessException, InvocationTargetException
76 {
77 when(methodInvocation.getParameters()).thenReturn(new Object[] {new Object()});
78 Parameter parameter = mock(Parameter.class);
79 when(parameter.getSource()).thenReturn(Parameter.Source.ENTITY);
80 when(method.getParameters()).thenReturn(Collections.<Parameter>singletonList(parameter));
81
82 interceptor.intercept(methodInvocation);
83
84 verify(response, never()).getEntity();
85 }
86
87 @Test
88 public void testInterceptPassParametersButNoEntity() throws IllegalAccessException, InvocationTargetException
89 {
90 when(methodInvocation.getParameters()).thenReturn(new Object[] {new Object()});
91 Parameter parameter = mock(Parameter.class);
92 when(parameter.getSource()).thenReturn(Parameter.Source.PATH);
93 when(method.getParameters()).thenReturn(Collections.<Parameter>singletonList(parameter));
94
95 interceptor.intercept(methodInvocation);
96
97 verify(response, never()).getEntity();
98 }
99
100 @Test
101 public void testInterceptPassNoEntityParameter() throws IllegalAccessException, InvocationTargetException
102 {
103 when(methodInvocation.getParameters()).thenReturn(new Object[0]);
104 when(method.getParameters()).thenReturn(Collections.<Parameter>emptyList());
105
106 interceptor.intercept(methodInvocation);
107
108 verify(response, never()).getEntity();
109 }
110
111 @Test
112 public void testInterceptFail() throws IllegalAccessException, InvocationTargetException
113 {
114 when(resolver.getText("notnull")).thenReturn("Not Null");
115 ValidatableObject obj = new ValidatableObject(null);
116
117 when(methodInvocation.getParameters()).thenReturn(new Object[] {obj});
118 Parameter parameter = mock(Parameter.class);
119 when(parameter.getSource()).thenReturn(Parameter.Source.ENTITY);
120 when(method.getParameters()).thenReturn(Collections.<Parameter>singletonList(parameter));
121
122 interceptor.intercept(methodInvocation);
123 verify(methodInvocation, never()).invoke();
124 verify(response).setResponse(responseCaptor.capture());
125
126 assertNotNull(responseCaptor.getValue());
127 assertEquals(400, responseCaptor.getValue().getStatus());
128
129 Object entity = responseCaptor.getValue().getEntity();
130 assertTrue(entity instanceof ValidationErrors);
131 ValidationErrors errors = (ValidationErrors) entity;
132 assertEquals(1, errors.getErrors().size());
133 assertEquals("Not Null", errors.getErrors().get(0).getMessage());
134 }
135
136 @Test
137 public void testInterceptFailWithCustomMessageInterpolator() throws IllegalAccessException, InvocationTargetException
138 {
139 MessageInterpolator messageInterpolator = mock(MessageInterpolator.class);
140 when(messageInterpolator.interpolate(eq("notnull"), (MessageInterpolator.Context) anyObject())).thenReturn("Bar");
141 interceptor = new ValidationInterceptor(messageInterpolator);
142
143 ValidatableObject obj = new ValidatableObject(null);
144
145 when(methodInvocation.getParameters()).thenReturn(new Object[] {obj});
146 Parameter parameter = mock(Parameter.class);
147 when(parameter.getSource()).thenReturn(Parameter.Source.ENTITY);
148 when(method.getParameters()).thenReturn(Collections.<Parameter>singletonList(parameter));
149
150 interceptor.intercept(methodInvocation);
151 verify(methodInvocation, never()).invoke();
152 verify(response).setResponse(responseCaptor.capture());
153
154 assertNotNull(responseCaptor.getValue());
155 assertEquals(400, responseCaptor.getValue().getStatus());
156
157 Object entity = responseCaptor.getValue().getEntity();
158 assertTrue(entity instanceof ValidationErrors);
159 ValidationErrors errors = (ValidationErrors) entity;
160 assertEquals(1, errors.getErrors().size());
161 assertEquals("Bar", errors.getErrors().get(0).getMessage());
162 }
163
164 static class ValidatableObject
165 {
166 @NotNull(message = "notnull")
167 @Size(min = 2, max = 10, message = "size")
168 private String name;
169
170 public ValidatableObject(String name)
171 {
172 this.name = name;
173 }
174
175 public String getName()
176 {
177 return name;
178 }
179 }
180 }