1 package com.atlassian.plugins.rest.module.filter;
2
3 import com.sun.jersey.core.util.MultivaluedMapImpl;
4 import com.sun.jersey.spi.container.ContainerRequest;
5 import static org.junit.Assert.*;
6 import org.junit.Before;
7 import org.junit.Test;
8 import org.mockito.ArgumentMatcher;
9 import org.mockito.Matchers;
10 import org.mockito.Mock;
11 import static org.mockito.Mockito.*;
12 import org.mockito.MockitoAnnotations;
13
14 import javax.ws.rs.core.MediaType;
15 import javax.ws.rs.core.MultivaluedMap;
16 import java.net.URI;
17 import java.util.Collections;
18 import java.util.List;
19 import java.util.Map;
20
21
22 public class ExtensionJerseyFilterTest
23 {
24 private static final String ACCEPT_HEADER = "Accept";
25
26 @Mock
27 private ContainerRequest containerRequest;
28
29 private ExtensionJerseyFilter jerseyFilter;
30
31 @Before
32 public void setUp()
33 {
34 MockitoAnnotations.initMocks(this);
35 jerseyFilter = new ExtensionJerseyFilter(Collections.singletonList("/excluded.*"));
36 }
37
38 @Test
39 public void testFilterWithoutQueryParameters() throws Exception
40 {
41 testFilter(new MultivaluedMapImpl());
42 }
43
44 @Test
45 public void testFilterWithQueryParameters() throws Exception
46 {
47 final MultivaluedMap<String, String> parameters = new MultivaluedMapImpl();
48 parameters.add("param1", "value1");
49 parameters.add("param2", "value2.1");
50 parameters.add("param2", "value2.2");
51 testFilter(parameters);
52 }
53
54 @Test
55 public void testDoNotFilterWhenExtensionNotMatched() throws Exception
56 {
57 testDoNotFilter("resource.myextension");
58 }
59
60 @Test
61 public void testDoNotFilterWhenNoExtension() throws Exception
62 {
63 testDoNotFilter("resource");
64 }
65
66 @Test
67 public void testDoNotFilterWhenExcluded() throws Exception
68 {
69 testDoNotFilter("excluded/resource.json");
70 }
71
72 private void testFilter(MultivaluedMap<String, String> queryParameters) throws Exception
73 {
74 final MultivaluedMapImpl headers = new MultivaluedMapImpl();
75 final URI baseUri = new URI("http://localhost:8080/rest");
76
77 when(containerRequest.getAbsolutePath()).thenReturn(new URI("http://localhost:8080/rest/application.json"));
78 when(containerRequest.getBaseUri()).thenReturn(baseUri);
79 when(containerRequest.getRequestHeaders()).thenReturn(headers);
80 when(containerRequest.getQueryParameters()).thenReturn(queryParameters);
81
82 jerseyFilter.filter(containerRequest);
83
84 final List<String> acceptHeader = headers.get(ACCEPT_HEADER);
85 assertEquals(1, acceptHeader.size());
86 assertEquals(MediaType.APPLICATION_JSON, acceptHeader.get(0));
87
88 verify(containerRequest).setUris(eq(baseUri), argThat(new UriMatcher(new URI("http://localhost:8080/rest/application"), queryParameters)));
89 }
90
91 private void testDoNotFilter(String resourceName) throws Exception
92 {
93 final String baseUri = "http://localhost:8080/rest/";
94
95 when(containerRequest.getBaseUri()).thenReturn(new URI(baseUri));
96 when(containerRequest.getAbsolutePath()).thenReturn(new URI(baseUri + resourceName));
97
98 jerseyFilter.filter(containerRequest);
99
100 verify(containerRequest, never()).getRequestHeaders();
101 verify(containerRequest, never()).setUris(Matchers.<URI>anyObject(), Matchers.<URI>anyObject());
102 }
103
104 private static class UriMatcher extends ArgumentMatcher<URI>
105 {
106 private final URI requestUri;
107 private final MultivaluedMap<String, String> parameters;
108
109 UriMatcher(URI requestUri, MultivaluedMap<String, String> parameters)
110 {
111 this.requestUri = requestUri;
112 this.parameters = parameters;
113 }
114
115 public boolean matches(Object actual)
116 {
117 final URI uri = (URI) actual;
118
119 if (!actual.toString().startsWith(requestUri.toString()))
120 {
121 return false;
122 }
123
124
125 final String queryParametersString = '&' + uri.getQuery() + '&';
126 for (Map.Entry<String, List<String>> queryParameter : parameters.entrySet())
127 {
128 for (String value : queryParameter.getValue())
129 {
130 if (!queryParametersString.contains('&' + queryParameter.getKey() + '=' + value + '&'))
131 {
132 return false;
133 }
134 }
135 }
136 return true;
137 }
138 }
139 }