/**
* Copyright (C) 2011 BonitaSoft S.A.
* BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2.0 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.bonitasoft.console.common.server.servlet;
import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.bonitasoft.console.common.server.preferences.properties.ConsoleProperties;
import org.bonitasoft.engine.session.APISession;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TenantFileUploadServletTest {
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
@Spy
protected TenantFileUploadServlet fileUploadServlet;
private ConsoleProperties consoleProperties;
private HttpServletRequest request;
@Before
public void setUp() throws Exception {
request = mock(HttpServletRequest.class);
final HttpSession session = mock(HttpSession.class);
final APISession apiSession = mock(APISession.class);
consoleProperties = mock(ConsoleProperties.class);
when(request.getSession()).thenReturn(session);
when(session.getAttribute("apiSession")).thenReturn(apiSession);
doReturn(consoleProperties).when(fileUploadServlet).getConsoleProperties(123);
when(apiSession.getTenantId()).thenReturn(123L);
}
@Test
public void should_throw_fileTooBigException_when_file_is_bigger_in_than_conf_file() throws Exception {
final ServletFileUpload serviceFileUpload = mock(ServletFileUpload.class);
when(consoleProperties.getMaxSize()).thenReturn(1L); // 1Mb
fileUploadServlet.setUploadSizeMax(serviceFileUpload, request);
verify(serviceFileUpload).setFileSizeMax(FileUploadServlet.MEGABYTE);
}
@Test
public void should_set_413_status_code_with_empty_body_when_file_creates_OOMError() throws Exception {
final ServletFileUpload serviceFileUpload = mock(ServletFileUpload.class);
final HttpServletResponse response = mock(HttpServletResponse.class);
final PrintWriter printer = mock(PrintWriter.class);
//manage spy
fileUploadServlet.uploadDirectoryPath = tempFolder.getRoot().getAbsolutePath();
fileUploadServlet.checkUploadedFileSize = true;
doNothing().when(fileUploadServlet).defineUploadDirectoryPath(request);
doReturn(serviceFileUpload).when(fileUploadServlet).createServletFileUpload(any(FileItemFactory.class));
when(serviceFileUpload.parseRequest(request)).thenThrow(new OutOfMemoryError());
when(request.getMethod()).thenReturn("post");
when(request.getContentType()).thenReturn("multipart/");
when(response.getWriter()).thenReturn(printer);
fileUploadServlet.doPost(request, response);
verify(response).setStatus(HttpURLConnection.HTTP_ENTITY_TOO_LARGE);
verify(printer, never()).print(anyString());
verify(printer, never()).flush();
}
@Test
public void should_set_413_status_code_with_empty_body_when_file_is_too_big() throws Exception {
final ServletFileUpload serviceFileUpload = mock(ServletFileUpload.class);
final HttpServletResponse response = mock(HttpServletResponse.class);
final PrintWriter printer = mock(PrintWriter.class);
//manage spy
fileUploadServlet.uploadDirectoryPath = tempFolder.getRoot().getAbsolutePath();
fileUploadServlet.checkUploadedFileSize = true;
doNothing().when(fileUploadServlet).defineUploadDirectoryPath(request);
doReturn(serviceFileUpload).when(fileUploadServlet).createServletFileUpload(any(FileItemFactory.class));
final FileSizeLimitExceededException exception = new FileSizeLimitExceededException(
format("The field %s exceeds its maximum permitted size of %s bytes.",
"uploadedFile.zip", Long.valueOf(0)),
20 * FileUploadServlet.MEGABYTE, 0);
exception.setFileName("uploadedFile.zip");
when(serviceFileUpload.parseRequest(request)).thenThrow(exception);
when(request.getMethod()).thenReturn("post");
when(request.getContentType()).thenReturn("multipart/");
when(response.getWriter()).thenReturn(printer);
fileUploadServlet.doPost(request, response);
verify(response).setStatus(HttpURLConnection.HTTP_ENTITY_TOO_LARGE);
verify(printer, never()).print(anyString());
verify(printer, never()).flush();
}
@Test
public void should_set_413_status_code_with_json_body_when_file_is_too_big_and_json_is_supported() throws Exception {
final ServletFileUpload serviceFileUpload = mock(ServletFileUpload.class);
final HttpServletResponse response = mock(HttpServletResponse.class);
final PrintWriter printer = mock(PrintWriter.class);
//manage spy
fileUploadServlet.uploadDirectoryPath = tempFolder.getRoot().getAbsolutePath();
fileUploadServlet.checkUploadedFileSize = true;
fileUploadServlet.responseContentType = "json";
doNothing().when(fileUploadServlet).defineUploadDirectoryPath(request);
doReturn(serviceFileUpload).when(fileUploadServlet).createServletFileUpload(any(FileItemFactory.class));
final FileSizeLimitExceededException exception = new FileSizeLimitExceededException(
format("The field %s exceeds its maximum permitted size of %s bytes.",
"uploadedFile.zip", Long.valueOf(0)),
20 * FileUploadServlet.MEGABYTE, 0);
exception.setFileName("uploadedFile.zip");
when(serviceFileUpload.parseRequest(request)).thenThrow(exception);
when(request.getMethod()).thenReturn("post");
when(request.getContentType()).thenReturn("multipart/");
when(response.getWriter()).thenReturn(printer);
fileUploadServlet.doPost(request, response);
verify(response).setStatus(HttpURLConnection.HTTP_ENTITY_TOO_LARGE);
final ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(printer).print(captor.capture());
assertThat(captor.getValue())
.contains("\"statusCode\":413")
.contains("\"message\":\"uploadedFile.zip is 20971520 large, limit is set to 0Mb\"")
.contains("\"type\":\"EntityTooLarge\"");
verify(printer).flush();
}
}