View Javadoc
1   /*
2    * Copyright (c) 2002-2022, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.portal.web.upload;
35  
36  import java.io.ByteArrayOutputStream;
37  import java.util.HashMap;
38  import java.util.List;
39  import java.util.Map;
40  
41  import javax.servlet.http.HttpServletRequest;
42  import javax.servlet.http.HttpServletResponse;
43  
44  import org.apache.commons.fileupload.FileItem;
45  import org.apache.commons.httpclient.methods.PostMethod;
46  import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
47  import org.apache.commons.httpclient.methods.multipart.FilePart;
48  import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
49  import org.apache.commons.httpclient.methods.multipart.Part;
50  import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
51  import org.springframework.beans.factory.support.DefaultListableBeanFactory;
52  import org.springframework.context.ConfigurableApplicationContext;
53  import org.springframework.mock.web.MockHttpServletRequest;
54  import org.springframework.mock.web.MockHttpServletResponse;
55  
56  import com.fasterxml.jackson.databind.JsonNode;
57  import com.fasterxml.jackson.databind.ObjectMapper;
58  
59  import fr.paris.lutece.portal.service.plugin.Plugin;
60  import fr.paris.lutece.portal.service.plugin.PluginDefaultImplementation;
61  import fr.paris.lutece.portal.service.plugin.PluginEvent;
62  import fr.paris.lutece.portal.service.plugin.PluginService;
63  import fr.paris.lutece.portal.service.spring.SpringContextService;
64  import fr.paris.lutece.test.LuteceTestCase;
65  import fr.paris.lutece.util.http.MultipartUtil;
66  
67  public class UploadServletTest extends LuteceTestCase
68  {
69  
70      /**
71       * Test of doPost method, of class fr.paris.lutece.portal.web.upload.UploadServlet.
72       */
73      public void testDoPost_NoFiles_NoHandler( ) throws Exception
74      {
75          MockHttpServletRequest request = new MockHttpServletRequest( );
76          MockHttpServletResponse response = new MockHttpServletResponse( );
77          MultipartHttpServletRequest multipartRequest = new MultipartHttpServletRequest( request, new HashMap<>( ), new HashMap<>( ) );
78  
79          new UploadServlet( ).doPost( multipartRequest, response );
80  
81          String strResponseJson = response.getContentAsString( );
82          System.out.println( strResponseJson );
83  
84          String strRefJson = "{\"files\":[]}";
85          ObjectMapper objectMapper = new ObjectMapper( );
86          JsonNode objectNodeRef = objectMapper.readTree( strRefJson );
87          JsonNode objectNodeJson = objectMapper.readTree( strResponseJson );
88  
89          assertEquals( objectNodeRef, objectNodeJson );
90      }
91  
92      public void testDoPost_Files_NoHandler( ) throws Exception
93      {
94          MockHttpServletRequest request = getMultipartRequest( );
95          MockHttpServletResponse response = new MockHttpServletResponse( );
96          MultipartHttpServletRequest multipartRequest = MultipartUtil.convert( 10000, 10000, false, request );
97  
98          new UploadServlet( ).doPost( multipartRequest, response );
99  
100         String strResponseJson = response.getContentAsString( );
101         System.out.println( strResponseJson );
102 
103         String strRefJson = "{\"files\":[{\"fileName\":\"file1\",\"fileSize\":3}]}";
104         ObjectMapper objectMapper = new ObjectMapper( );
105         JsonNode objectNodeRef = objectMapper.readTree( strRefJson );
106         JsonNode objectNodeJson = objectMapper.readTree( strResponseJson );
107 
108         assertEquals( objectNodeRef, objectNodeJson );
109     }
110 
111     public void testDoPost_NoFiles_Handler( ) throws Exception
112     {
113         final String BEAN_NAME = "testAsyncUpNetSf";
114         MockHttpServletRequest request = new MockHttpServletRequest( );
115         MockHttpServletResponse response = new MockHttpServletResponse( );
116         Map<String, List<FileItem>> mapFiles = new HashMap<>( );
117         Map<String, String [ ]> mapParameters = new HashMap<>( );
118         mapParameters.put( "handler", new String [ ] {
119                 BEAN_NAME
120         } );
121         MultipartHttpServletRequest multipartRequest = new MultipartHttpServletRequest( request, mapFiles, mapParameters );
122 
123         clearLuteceSpringCache( );
124         ConfigurableListableBeanFactory beanFactory = ( (ConfigurableApplicationContext) SpringContextService.getContext( ) ).getBeanFactory( );
125         beanFactory.registerSingleton( BEAN_NAME, new IAsynchronousUploadHandler2( )
126         {
127             @Override
128             public void process( HttpServletRequest request, HttpServletResponse response, Map<String, Object> mainObject, List<FileItem> fileItems )
129             {
130                 mainObject.clear( );
131                 mainObject.put( "testnetsf", "valuetestnetsf" );
132             }
133 
134             @Override
135             public boolean isInvoked( HttpServletRequest request )
136             {
137                 return BEAN_NAME.equals( request.getParameter( "handler" ) );
138             }
139         } );
140 
141         try
142         {
143             new UploadServlet( ).doPost( multipartRequest, response );
144         }
145         catch( Exception e )
146         {
147             throw new RuntimeException( e );
148         }
149         finally
150         {
151             ( (DefaultListableBeanFactory) beanFactory ).destroySingleton( BEAN_NAME );
152             clearLuteceSpringCache( );
153         }
154 
155         String strResponseJson = response.getContentAsString( );
156         System.out.println( strResponseJson );
157 
158         String strRefJson = "{\"testnetsf\":\"valuetestnetsf\"}";
159         ObjectMapper objectMapper = new ObjectMapper( );
160         JsonNode objectNodeRef = objectMapper.readTree( strRefJson );
161         JsonNode objectNodeJson = objectMapper.readTree( strResponseJson );
162 
163         assertEquals( objectNodeRef, objectNodeJson );
164     }
165 
166     public void testDoPost_NoFiles_Handler2( ) throws Exception
167     {
168         final String BEAN_NAME = "testAsyncUpMap";
169         MockHttpServletRequest request = new MockHttpServletRequest( );
170         MockHttpServletResponse response = new MockHttpServletResponse( );
171         Map<String, List<FileItem>> mapFiles = new HashMap<>( );
172         Map<String, String [ ]> mapParameters = new HashMap<>( );
173         mapParameters.put( "handler", new String [ ] {
174                 BEAN_NAME
175         } );
176         MultipartHttpServletRequest multipartRequest = new MultipartHttpServletRequest( request, mapFiles, mapParameters );
177 
178         clearLuteceSpringCache( );
179         ConfigurableListableBeanFactory beanFactory = ( (ConfigurableApplicationContext) SpringContextService.getContext( ) ).getBeanFactory( );
180         beanFactory.registerSingleton( BEAN_NAME, new IAsynchronousUploadHandler2( )
181         {
182             @Override
183             public void process( HttpServletRequest request, HttpServletResponse response, Map<String, Object> mainObject, List<FileItem> fileItems )
184             {
185                 mainObject.clear( );
186                 mainObject.put( "testmap", "valuetestmap" );
187             }
188 
189             @Override
190             public boolean isInvoked( HttpServletRequest request )
191             {
192                 return BEAN_NAME.equals( request.getParameter( "handler" ) );
193             }
194         } );
195 
196         try
197         {
198             new UploadServlet( ).doPost( multipartRequest, response );
199         }
200         catch( Exception e )
201         {
202             throw new RuntimeException( e );
203         }
204         finally
205         {
206             ( (DefaultListableBeanFactory) beanFactory ).destroySingleton( BEAN_NAME );
207             clearLuteceSpringCache( );
208         }
209 
210         String strResponseJson = response.getContentAsString( );
211         System.out.println( strResponseJson );
212 
213         String strRefJson = "{\"testmap\":\"valuetestmap\"}";
214         ObjectMapper objectMapper = new ObjectMapper( );
215         JsonNode objectNodeRef = objectMapper.readTree( strRefJson );
216         JsonNode objectNodeJson = objectMapper.readTree( strResponseJson );
217 
218         assertEquals( objectNodeRef, objectNodeJson );
219     }
220 
221     private void clearLuteceSpringCache( )
222     {
223         // hack plugin installed event to clear the SpringContextService cache
224         // TODO have a better way to do this ???
225         Plugin p = new PluginDefaultImplementation( );
226         p.setName( "FakePluginSpringCacheClearer" );
227         PluginService.notifyListeners( new PluginEvent( p, PluginEvent.PLUGIN_INSTALLED ) );
228     }
229 
230     private MockHttpServletRequest getMultipartRequest( ) throws Exception
231     {
232         MockHttpServletRequest request = new MockHttpServletRequest( );
233         byte [ ] fileContent = new byte [ ] {
234                 1, 2, 3
235         };
236         Part [ ] parts = new Part [ ] {
237                 new FilePart( "file1", new ByteArrayPartSource( "file1", fileContent ) )
238         };
239         MultipartRequestEntity multipartRequestEntity = new MultipartRequestEntity( parts, new PostMethod( ).getParams( ) );
240         // Serialize request body
241         ByteArrayOutputStream requestContent = new ByteArrayOutputStream( );
242         multipartRequestEntity.writeRequest( requestContent );
243         // Set request body to HTTP servlet request
244         request.setContent( requestContent.toByteArray( ) );
245         // Set content type to HTTP servlet request (important, includes Mime boundary string)
246         request.setContentType( multipartRequestEntity.getContentType( ) );
247         request.setMethod( "POST" );
248         return request;
249     }
250 }