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 private I18nResolver resolver;
33 private ValidationInterceptor interceptor;
34 private MethodInvocation methodInvocation;
35 private AbstractResourceMethod method;
36 private ArgumentCaptor<Response> responseCaptor;
37 private HttpResponseContext response;
38
39 @Before
40 public void setUp() {
41 resolver = mock(I18nResolver.class);
42 interceptor = new ValidationInterceptor(resolver);
43 methodInvocation = mock(MethodInvocation.class);
44 HttpContext httpContext = mock(HttpContext.class);
45 response = mock(HttpResponseContext.class);
46 method = mock(AbstractResourceMethod.class);
47
48
49 when(httpContext.getResponse()).thenReturn(response);
50 when(methodInvocation.getHttpContext()).thenReturn(httpContext);
51 when(methodInvocation.getMethod()).thenReturn(method);
52
53 responseCaptor = ArgumentCaptor.forClass(Response.class);
54 }
55
56 @Test
57 public void testInterceptPass() throws IllegalAccessException, InvocationTargetException {
58 ValidatableObject obj = new ValidatableObject("jim");
59
60 when(methodInvocation.getParameters()).thenReturn(new Object[]{obj});
61 Parameter parameter = mock(Parameter.class);
62 when(parameter.getSource()).thenReturn(Parameter.Source.ENTITY);
63 when(method.getParameters()).thenReturn(Collections.<Parameter>singletonList(parameter));
64
65 interceptor.intercept(methodInvocation);
66 verify(methodInvocation, times(1)).invoke();
67
68 verify(response, never()).getEntity();
69 }
70
71 @Test
72 public void testInterceptPassNoAnnotations() throws IllegalAccessException, InvocationTargetException {
73 when(methodInvocation.getParameters()).thenReturn(new Object[]{new Object()});
74 Parameter parameter = mock(Parameter.class);
75 when(parameter.getSource()).thenReturn(Parameter.Source.ENTITY);
76 when(method.getParameters()).thenReturn(Collections.<Parameter>singletonList(parameter));
77
78 interceptor.intercept(methodInvocation);
79
80 verify(response, never()).getEntity();
81 }
82
83 @Test
84 public void testInterceptPassParametersButNoEntity() throws IllegalAccessException, InvocationTargetException {
85 when(methodInvocation.getParameters()).thenReturn(new Object[]{new Object()});
86 Parameter parameter = mock(Parameter.class);
87 when(parameter.getSource()).thenReturn(Parameter.Source.PATH);
88 when(method.getParameters()).thenReturn(Collections.<Parameter>singletonList(parameter));
89
90 interceptor.intercept(methodInvocation);
91
92 verify(response, never()).getEntity();
93 }
94
95 @Test
96 public void testInterceptPassNoEntityParameter() throws IllegalAccessException, InvocationTargetException {
97 when(methodInvocation.getParameters()).thenReturn(new Object[0]);
98 when(method.getParameters()).thenReturn(Collections.<Parameter>emptyList());
99
100 interceptor.intercept(methodInvocation);
101
102 verify(response, never()).getEntity();
103 }
104
105 @Test
106 public void testInterceptFail() throws IllegalAccessException, InvocationTargetException {
107 when(resolver.getText("notnull")).thenReturn("Not Null");
108 ValidatableObject obj = new ValidatableObject(null);
109
110 when(methodInvocation.getParameters()).thenReturn(new Object[]{obj});
111 Parameter parameter = mock(Parameter.class);
112 when(parameter.getSource()).thenReturn(Parameter.Source.ENTITY);
113 when(method.getParameters()).thenReturn(Collections.<Parameter>singletonList(parameter));
114
115 interceptor.intercept(methodInvocation);
116 verify(methodInvocation, never()).invoke();
117 verify(response).setResponse(responseCaptor.capture());
118
119 assertNotNull(responseCaptor.getValue());
120 assertEquals(400, responseCaptor.getValue().getStatus());
121
122 Object entity = responseCaptor.getValue().getEntity();
123 assertTrue(entity instanceof ValidationErrors);
124 ValidationErrors errors = (ValidationErrors) entity;
125 assertEquals(1, errors.getErrors().size());
126 assertEquals("Not Null", errors.getErrors().get(0).getMessage());
127 }
128
129 @Test
130 public void testInterceptFailWithCustomMessageInterpolator() throws IllegalAccessException, InvocationTargetException {
131 MessageInterpolator messageInterpolator = mock(MessageInterpolator.class);
132 when(messageInterpolator.interpolate(eq("notnull"), (MessageInterpolator.Context) anyObject())).thenReturn("Bar");
133 interceptor = new ValidationInterceptor(messageInterpolator);
134
135 ValidatableObject obj = new ValidatableObject(null);
136
137 when(methodInvocation.getParameters()).thenReturn(new Object[]{obj});
138 Parameter parameter = mock(Parameter.class);
139 when(parameter.getSource()).thenReturn(Parameter.Source.ENTITY);
140 when(method.getParameters()).thenReturn(Collections.<Parameter>singletonList(parameter));
141
142 interceptor.intercept(methodInvocation);
143 verify(methodInvocation, never()).invoke();
144 verify(response).setResponse(responseCaptor.capture());
145
146 assertNotNull(responseCaptor.getValue());
147 assertEquals(400, responseCaptor.getValue().getStatus());
148
149 Object entity = responseCaptor.getValue().getEntity();
150 assertTrue(entity instanceof ValidationErrors);
151 ValidationErrors errors = (ValidationErrors) entity;
152 assertEquals(1, errors.getErrors().size());
153 assertEquals("Bar", errors.getErrors().get(0).getMessage());
154 }
155
156 static class ValidatableObject {
157 @NotNull(message = "notnull")
158 @Size(min = 2, max = 10, message = "size")
159 private String name;
160
161 public ValidatableObject(String name) {
162 this.name = name;
163 }
164
165 public String getName() {
166 return name;
167 }
168 }
169 }