1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.webjars

File WebJarsResourceReferenceHandlerTest.java

 

Code metrics

0
65
7
1
242
157
7
0.11
9.29
7
1

Classes

Class Line # Actions
WebJarsResourceReferenceHandlerTest 69 65 0% 7 0
1.0100%
 

Contributing tests

This file is covered by 5 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.webjars;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.ByteArrayOutputStream;
24    import java.io.Reader;
25    import java.io.StringWriter;
26    import java.util.Arrays;
27    import java.util.Date;
28   
29    import javax.servlet.http.HttpServletRequest;
30    import javax.servlet.http.HttpServletResponse;
31   
32    import org.apache.velocity.exception.VelocityException;
33    import org.junit.Before;
34    import org.junit.Rule;
35    import org.junit.Test;
36    import org.mockito.ArgumentCaptor;
37    import org.mockito.invocation.InvocationOnMock;
38    import org.mockito.stubbing.Answer;
39    import org.xwiki.classloader.ClassLoaderManager;
40    import org.xwiki.classloader.NamespaceURLClassLoader;
41    import org.xwiki.container.Container;
42    import org.xwiki.container.servlet.ServletRequest;
43    import org.xwiki.container.servlet.ServletResponse;
44    import org.xwiki.resource.ResourceReferenceHandlerChain;
45    import org.xwiki.resource.ResourceReferenceHandlerException;
46    import org.xwiki.test.mockito.MockitoComponentMockingRule;
47    import org.xwiki.velocity.VelocityEngine;
48    import org.xwiki.velocity.VelocityManager;
49    import org.xwiki.webjars.internal.WebJarsResourceReference;
50    import org.xwiki.webjars.internal.WebJarsResourceReferenceHandler;
51   
52    import static org.junit.Assert.assertEquals;
53    import static org.junit.Assert.assertTrue;
54    import static org.mockito.ArgumentMatchers.any;
55    import static org.mockito.ArgumentMatchers.anyLong;
56    import static org.mockito.ArgumentMatchers.eq;
57    import static org.mockito.Mockito.doAnswer;
58    import static org.mockito.Mockito.mock;
59    import static org.mockito.Mockito.never;
60    import static org.mockito.Mockito.verify;
61    import static org.mockito.Mockito.when;
62   
63    /**
64    * Unit tests for {@link org.xwiki.webjars.internal.WebJarsResourceReferenceHandler}.
65    *
66    * @version $Id: 1cacee7c30090800b2a55f32ecb8c7f1efa1a306 $
67    * @since 6.1M2
68    */
 
69    public class WebJarsResourceReferenceHandlerTest
70    {
71    @Rule
72    public MockitoComponentMockingRule<WebJarsResourceReferenceHandler> componentManager =
73    new MockitoComponentMockingRule<>(WebJarsResourceReferenceHandler.class);
74   
75    private ServletRequest request;
76   
77    private ServletResponse response;
78   
79    private ResourceReferenceHandlerChain chain = mock(ResourceReferenceHandlerChain.class);
80   
81    private WebJarsResourceReferenceHandler handler;
82   
83    private NamespaceURLClassLoader classLoader;
84   
 
85  5 toggle @Before
86    public void configure() throws Exception
87    {
88  5 Container container = this.componentManager.getInstance(Container.class);
89   
90  5 this.response = mock(ServletResponse.class);
91  5 ByteArrayOutputStream responseOutputStream = new ByteArrayOutputStream();
92  5 when(this.response.getOutputStream()).thenReturn(responseOutputStream);
93   
94  5 HttpServletResponse httpResponse = mock(HttpServletResponse.class);
95  5 when(this.response.getHttpServletResponse()).thenReturn(httpResponse);
96  5 when(container.getResponse()).thenReturn(this.response);
97   
98  5 this.request = mock(ServletRequest.class);
99  5 HttpServletRequest httpRequest = mock(HttpServletRequest.class);
100  5 when(this.request.getHttpServletRequest()).thenReturn(httpRequest);
101  5 when(container.getRequest()).thenReturn(this.request);
102   
103  5 this.handler = this.componentManager.getComponentUnderTest();
104   
105  5 this.classLoader = mock(NamespaceURLClassLoader.class);
106  5 ClassLoaderManager clm = this.componentManager.getInstance(ClassLoaderManager.class);
107  5 when(clm.getURLClassLoader("wiki:wiki", true)).thenReturn(this.classLoader);
108    }
109   
 
110  1 toggle @Test
111    public void executeWhenResourceDoesntExist() throws Exception
112    {
113  1 WebJarsResourceReference reference =
114    new WebJarsResourceReference("wiki:wiki", Arrays.asList("angular", "2.1.11", "angular.js"));
115   
116  1 this.handler.handle(reference, this.chain);
117   
118  1 verify(this.classLoader).getResourceAsStream("META-INF/resources/webjars/angular/2.1.11/angular.js");
119  1 verify(this.response.getHttpServletResponse())
120    .sendError(404, "Resource not found [angular/2.1.11/angular.js].");
121  1 verify(this.chain).handleNext(reference);
122    }
123   
 
124  1 toggle @Test
125    public void executeWhenResourceExists() throws Exception
126    {
127  1 WebJarsResourceReference reference =
128    new WebJarsResourceReference("wiki:wiki", Arrays.asList("angular", "2.1.11", "angular.js"));
129   
130  1 ByteArrayInputStream resourceStream = new ByteArrayInputStream("content".getBytes());
131  1 when(this.classLoader.getResourceAsStream("META-INF/resources/webjars/angular/2.1.11/angular.js")).thenReturn(
132    resourceStream);
133   
134  1 Long now = new Date().getTime();
135  1 this.handler.handle(reference, this.chain);
136   
137    // Verify that the resource content has been copied to the Response output stream.
138  1 assertEquals("content", this.response.getOutputStream().toString());
139    // Verify that the correct Content Type has been set.
140  1 verify(this.response).setContentType("application/javascript");
141   
142    // Verify that the static resource is cached permanently.
143  1 verify(this.response.getHttpServletResponse()).setHeader("Cache-Control", "public");
144  1 ArgumentCaptor<Long> expireDate = ArgumentCaptor.forClass(Long.class);
145  1 verify(this.response.getHttpServletResponse()).setDateHeader(eq("Expires"), expireDate.capture());
146    // The expiration date should be in one year from now.
147  1 assertTrue(expireDate.getValue() >= (now + 365 * 24 * 3600 * 1000L));
148   
149    // Also verify that the "Last-Modified" header has been set in the response so that the browser will send
150    // an If-Modified-Since header for the next request and we can tell it to use its cache.
151  1 verify(this.response.getHttpServletResponse()).setDateHeader(eq("Last-Modified"), anyLong());
152   
153  1 verify(this.chain).handleNext(reference);
154    }
155   
 
156  1 toggle @Test
157    public void return304WhenIfModifiedSinceHeader() throws Exception
158    {
159  1 WebJarsResourceReference reference =
160    new WebJarsResourceReference("wiki:wiki", Arrays.asList("angular", "2.1.11", "angular.js"));
161   
162  1 when(this.request.getHttpServletRequest().getHeader("If-Modified-Since")).thenReturn("some value");
163   
164  1 this.handler.handle(reference, this.chain);
165   
166    // This the test: we verify that 304 is returned when the "If-Modified-Since" header is found in the request
167  1 verify(this.response.getHttpServletResponse()).setStatus(304);
168   
169  1 verify(this.chain).handleNext(reference);
170    }
171   
 
172  1 toggle @Test
173    public void evaluateResource() throws Exception
174    {
175  1 WebJarsResourceReference reference =
176    new WebJarsResourceReference("wiki:wiki", Arrays.asList("angular", "2.1.11", "angular.js"));
177  1 reference.addParameter("evaluate", true);
178   
179  1 ByteArrayInputStream resourceStream = new ByteArrayInputStream("content".getBytes());
180  1 when(this.classLoader.getResourceAsStream("META-INF/resources/webjars/angular/2.1.11/angular.js")).thenReturn(
181    resourceStream);
182   
183  1 VelocityManager velocityManager = this.componentManager.getInstance(VelocityManager.class);
184  1 VelocityEngine velocityEngine = mock(VelocityEngine.class);
185  1 when(velocityManager.getVelocityEngine()).thenReturn(velocityEngine);
186   
187  1 doAnswer(new Answer<Void>()
188    {
 
189  1 toggle @Override
190    public Void answer(InvocationOnMock invocation)
191    {
192  1 ((StringWriter) invocation.getArguments()[1]).write("evaluated content");
193  1 return null;
194    }
195    }).when(velocityEngine).evaluate(any(), any(), eq("angular/2.1.11/angular.js"), any(Reader.class));
196   
197  1 this.handler.handle(reference, this.chain);
198   
199    // Verify that the resource content has been evaluated and copied to the Response output stream.
200  1 assertEquals("evaluated content", this.response.getOutputStream().toString());
201   
202    // Verify that the correct Content Type has been set.
203  1 verify(this.response).setContentType("application/javascript");
204   
205    // Verify that the dynamic resource is not cached.
206  1 verify(this.response.getHttpServletResponse(), never()).setHeader(any(), any());
207  1 verify(this.response.getHttpServletResponse(), never()).setDateHeader(any(), anyLong());
208    }
209   
 
210  1 toggle @Test
211    public void failingResourceEvaluation() throws Exception
212    {
213  1 WebJarsResourceReference reference =
214    new WebJarsResourceReference("wiki:wiki", Arrays.asList("angular", "2.1.11", "angular.js"));
215  1 reference.addParameter("evaluate", "true");
216   
217  1 ByteArrayInputStream resourceStream = new ByteArrayInputStream("content".getBytes());
218  1 when(this.classLoader.getResourceAsStream("META-INF/resources/webjars/angular/2.1.11/angular.js")).thenReturn(
219    resourceStream);
220   
221  1 VelocityManager velocityManager = this.componentManager.getInstance(VelocityManager.class);
222  1 VelocityEngine velocityEngine = mock(VelocityEngine.class);
223  1 when(velocityManager.getVelocityEngine()).thenReturn(velocityEngine);
224   
225  1 when(velocityEngine.evaluate(any(), any(), eq("angular/2.1.11/angular.js"), any(Reader.class)))
226    .thenThrow(new VelocityException("Bad code!"));
227   
228  1 this.handler.handle(reference, this.chain);
229   
230    // Verify the exception is logged.
231  1 verify(this.componentManager.getMockedLogger()).error(
232    eq("Failed to evaluate the Velocity code from WebJar resource [angular/2.1.11/angular.js]"),
233    any(ResourceReferenceHandlerException.class));
234   
235    // Verify that the client is properly notified about the failure.
236  1 verify(this.response.getHttpServletResponse()).sendError(500,
237    "Failed to evaluate the Velocity code from WebJar resource [angular/2.1.11/angular.js]");
238   
239    // The next handlers are still called.
240  1 verify(this.chain).handleNext(reference);
241    }
242    }