/**
* Copyright (c) Codice Foundation
* <p>
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or any later version.
* <p>
* 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
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package org.codice.ddf.admin.application.rest;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.activation.DataHandler;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition;
import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
import org.codice.ddf.admin.application.service.Application;
import org.codice.ddf.admin.application.service.ApplicationService;
import org.codice.ddf.admin.application.service.ApplicationServiceException;
import org.eclipse.jetty.http.HttpStatus;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;
public class ApplicationUploadEndpointTest {
private static final String FILENAME_CONTENT_DISPOSITION_PARAMETER_NAME = "filename";
private static final String TEST_FILE_LOCATION = "target/ApplicationUploadEndpointTest/";
private static final String TEST_FILE_NAME = "/test-kar.jar";
private static final String BAD_FILE_NAME = "/test-badfile";
private static final String WRONG_FILE_TYPE = "Wrong file type.";
private static final String IOEX_STRING = "IOException";
private static final String FILE_NOT_FOUND = "No file attachment found";
private static final String USING_DEFAULT = "Filename not found, using default.";
private ApplicationService testAppService;
private MultipartBody testMultipartBody;
private UriInfo testUriInfo;
private List<Attachment> attachmentList;
private Attachment testAttach1;
private ContentDisposition testDisp;
private DataHandler testDataHandler;
private File testFile;
private InputStream testIS;
@Before
public void setUp() throws Exception {
testAppService = mock(ApplicationService.class);
testMultipartBody = mock(MultipartBody.class);
testUriInfo = mock(UriInfo.class);
attachmentList = new ArrayList<>();
testAttach1 = mock(Attachment.class);
testDisp = mock(ContentDisposition.class);
testDataHandler = mock(DataHandler.class);
attachmentList.add(testAttach1);
testFile = new File(File.class.getResource(TEST_FILE_NAME)
.getPath());
testIS = new FileInputStream(testFile);
when(testAttach1.getDataHandler()).thenReturn(testDataHandler);
when(testAttach1.getContentDisposition()).thenReturn(testDisp);
when(testMultipartBody.getAllAttachments()).thenReturn(attachmentList);
when(testDataHandler.getInputStream()).thenReturn(testIS);
when(testDisp.getParameter(FILENAME_CONTENT_DISPOSITION_PARAMETER_NAME)).thenReturn(
TEST_FILE_NAME);
}
/**
* Tests the {@link ApplicationUploadEndpoint#update(MultipartBody, UriInfo)} method
*
* @throws Exception
*/
@Test
public void testApplicationUploadEndpointUpdate() throws Exception {
ApplicationUploadEndpoint applicationUploadEndpoint = new ApplicationUploadEndpoint(
testAppService);
applicationUploadEndpoint.setDefaultFileLocation(TEST_FILE_LOCATION);
Response response = applicationUploadEndpoint.update(testMultipartBody, testUriInfo);
Response testResponse = Response.ok("{\"status\":\"success\"}")
.type("application/json")
.build();
assertThat("Returned status is success",
response.getStatus(),
is(testResponse.getStatus()));
}
/**
* Tests the {@link ApplicationUploadEndpoint#update(MultipartBody, UriInfo)} method
* for the case where the application exists and has already been started
*
* @throws Exception
*/
@Test
public void testApplicationUploadEndpointUpdateAppStarted() throws Exception {
Application testApp = mock(Application.class);
when(testAppService.getApplication(anyString())).thenReturn(testApp);
when(testAppService.isApplicationStarted(testApp)).thenReturn(true);
ApplicationUploadEndpoint applicationUploadEndpoint = new ApplicationUploadEndpoint(
testAppService);
applicationUploadEndpoint.setDefaultFileLocation(TEST_FILE_LOCATION);
Response response = applicationUploadEndpoint.update(testMultipartBody, testUriInfo);
Response testResponse = Response.ok("{\"status\":\"success\"}")
.type("application/json")
.build();
assertThat("Returned status is success",
response.getStatus(),
is(testResponse.getStatus()));
verify(testAppService).removeApplication(testApp);
verify(testAppService).startApplication(anyString());
}
/**
* Tests the {@link ApplicationUploadEndpoint#update(MultipartBody, UriInfo)} method
* for the case where the file can not be found
*
* @throws Exception
*/
@Test
public void testApplicationUploadEndpointUpdateFileNotFound() throws Exception {
when(testMultipartBody.getAllAttachments()).thenReturn(new ArrayList<Attachment>());
ApplicationUploadEndpoint applicationUploadEndpoint = new ApplicationUploadEndpoint(
testAppService);
applicationUploadEndpoint.setDefaultFileLocation(TEST_FILE_LOCATION);
Response response = applicationUploadEndpoint.update(testMultipartBody, testUriInfo);
Response expectedResponse = Response.serverError()
.build();
assertThat("Response should indicate server error.",
response.getStatus(),
is(expectedResponse.getStatus()));
}
/**
* Tests the {@link ApplicationUploadEndpoint#create(MultipartBody, UriInfo)} method
*
* @throws Exception
*/
@Test
public void testApplicationUploadEndpointCreate() throws Exception {
ApplicationUploadEndpoint applicationUploadEndpoint = new ApplicationUploadEndpoint(
testAppService);
applicationUploadEndpoint.setDefaultFileLocation(TEST_FILE_LOCATION);
Response response = applicationUploadEndpoint.create(testMultipartBody, testUriInfo);
Response expectedResponse = Response.ok()
.build();
assertThat("No errors reported by response",
response.getStatus(),
is(expectedResponse.getStatus()));
verify(testAppService).addApplication(Mockito.any(URI.class));
}
/**
* Tests the {@link ApplicationUploadEndpoint#create(MultipartBody, UriInfo)} method
* for the case where an ApplicationServiceException is thrown
*
* @throws Exception
*/
@Test
public void testApplicationUploadEndpointCreateApplicationServiceException() throws Exception {
ApplicationUploadEndpoint applicationUploadEndpoint = new ApplicationUploadEndpoint(
testAppService);
doThrow(new ApplicationServiceException()).when(testAppService)
.addApplication(Mockito.any(URI.class));
applicationUploadEndpoint.setDefaultFileLocation(TEST_FILE_LOCATION);
Response response = applicationUploadEndpoint.create(testMultipartBody, testUriInfo);
Response expectedResponse = Response.serverError()
.build();
assertThat("Response should report server error.",
response.getStatus(),
is(expectedResponse.getStatus()));
}
/**
* Tests the {@link ApplicationUploadEndpoint#create(MultipartBody, UriInfo)} method
* for the case where the source file has an invalid type
*
* @throws Exception
*/
// TODO RAP 29 Aug 16: DDF-2443 - Fix test to not depend on specific log output
@Test
public void testApplicationUploadEndpointCreateInvalidType() throws Exception {
ch.qos.logback.classic.Logger root =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
final Appender mockAppender = mock(Appender.class);
when(mockAppender.getName()).thenReturn("MOCK");
root.addAppender(mockAppender);
root.setLevel(Level.ALL);
ApplicationUploadEndpoint applicationUploadEndpoint = new ApplicationUploadEndpoint(
testAppService);
testFile = new File(File.class.getResource(BAD_FILE_NAME)
.getPath());
testIS = mock(InputStream.class);
when(testIS.available()).thenReturn(1);
when(testDataHandler.getInputStream()).thenReturn(testIS);
when(testDisp.getParameter(FILENAME_CONTENT_DISPOSITION_PARAMETER_NAME)).thenReturn(
BAD_FILE_NAME);
applicationUploadEndpoint.setDefaultFileLocation(TEST_FILE_LOCATION);
Response response = applicationUploadEndpoint.create(testMultipartBody, testUriInfo);
Response expectedResponse = Response.status(HttpStatus.UNSUPPORTED_MEDIA_TYPE_415)
.build();
verify(mockAppender).doAppend(argThat(new ArgumentMatcher() {
@Override
public boolean matches(final Object argument) {
return ((LoggingEvent) argument).getFormattedMessage()
.contains(WRONG_FILE_TYPE);
}
}));
}
/**
* Tests the {@link ApplicationUploadEndpoint#create(MultipartBody, UriInfo)} method
* for the case where the source file causes an IOException when it is read
*
* @throws Exception
*/
// TODO RAP 29 Aug 16: DDF-2443 - Fix test to not depend on specific log output
@Test
public void testApplicationUploadEndpointCreateIOException() throws Exception {
ch.qos.logback.classic.Logger root =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
final Appender mockAppender = mock(Appender.class);
when(mockAppender.getName()).thenReturn("MOCK");
root.addAppender(mockAppender);
ApplicationUploadEndpoint applicationUploadEndpoint = new ApplicationUploadEndpoint(
testAppService);
doThrow(new IOException()).when(testDataHandler)
.getInputStream();
when(testDisp.getParameter(FILENAME_CONTENT_DISPOSITION_PARAMETER_NAME)).thenReturn(
BAD_FILE_NAME);
applicationUploadEndpoint.setDefaultFileLocation(TEST_FILE_LOCATION);
applicationUploadEndpoint.create(testMultipartBody, testUriInfo);
verify(mockAppender).doAppend(argThat(new ArgumentMatcher() {
@Override
public boolean matches(final Object argument) {
return ((LoggingEvent) argument).getFormattedMessage()
.contains("ddf.home");
}
}));
}
/**
* Tests the {@link ApplicationUploadEndpoint#create(MultipartBody, UriInfo)} method
* for the case where the file cannot be found (inside of createFileAttachement(..))
*
* @throws Exception
*/
// TODO RAP 29 Aug 16: DDF-2443 - Fix test to not depend on specific log output
@Test
public void testApplicationUploadEndpointCreateFileNotFound() throws Exception {
ch.qos.logback.classic.Logger root =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
final Appender mockAppender = mock(Appender.class);
when(mockAppender.getName()).thenReturn("MOCK");
root.addAppender(mockAppender);
root.setLevel(Level.ALL);
ApplicationUploadEndpoint applicationUploadEndpoint = new ApplicationUploadEndpoint(
testAppService);
testFile = new File(File.class.getResource(TEST_FILE_NAME)
.getPath());
testIS = null;
when(testDataHandler.getInputStream()).thenReturn(testIS);
when(testDisp.getParameter(FILENAME_CONTENT_DISPOSITION_PARAMETER_NAME)).thenReturn(
TEST_FILE_NAME);
applicationUploadEndpoint.setDefaultFileLocation(TEST_FILE_LOCATION);
applicationUploadEndpoint.create(testMultipartBody, testUriInfo);
verify(mockAppender).doAppend(argThat(new ArgumentMatcher() {
@Override
public boolean matches(final Object argument) {
return ((LoggingEvent) argument).getFormattedMessage()
.contains(FILE_NOT_FOUND);
}
}));
}
/**
* Tests the {@link ApplicationUploadEndpoint#create(MultipartBody, UriInfo)} method
* for the case where the filename is empty
*
* @throws Exception
*/
// TODO RAP 29 Aug 16: DDF-2443 - Fix test to not depend on specific log output
@Test
public void testApplicationUploadEndpointCreateEmptyFilename() throws Exception {
ch.qos.logback.classic.Logger root =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
final Appender mockAppender = mock(Appender.class);
when(mockAppender.getName()).thenReturn("MOCK");
root.addAppender(mockAppender);
root.setLevel(Level.ALL);
ApplicationUploadEndpoint applicationUploadEndpoint = new ApplicationUploadEndpoint(
testAppService);
testFile = new File(File.class.getResource(TEST_FILE_NAME)
.getPath());
testIS = new FileInputStream(testFile);
when(testDataHandler.getInputStream()).thenReturn(testIS);
when(testDisp.getParameter(FILENAME_CONTENT_DISPOSITION_PARAMETER_NAME)).thenReturn(
StringUtils.EMPTY);
applicationUploadEndpoint.setDefaultFileLocation(TEST_FILE_LOCATION);
applicationUploadEndpoint.create(testMultipartBody, testUriInfo);
verify(mockAppender).doAppend(argThat(new ArgumentMatcher() {
@Override
public boolean matches(final Object argument) {
return ((LoggingEvent) argument).getFormattedMessage()
.contains(USING_DEFAULT);
}
}));
}
}