package ca.uhn.fhir.jaxrs.server.interceptor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import javax.interceptor.InvocationContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.junit.Before;
import org.junit.Test;
import ca.uhn.fhir.jaxrs.server.AbstractJaxRsProvider;
import ca.uhn.fhir.jaxrs.server.test.TestJaxRsDummyPatientProvider;
import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
import ca.uhn.fhir.rest.server.interceptor.ExceptionHandlingInterceptor;
public class JaxRsExceptionInterceptorTest {
JaxRsExceptionInterceptor interceptor = new JaxRsExceptionInterceptor();
private InvocationContext context;
@Before
public void setUp() throws Exception {
interceptor = new JaxRsExceptionInterceptor();
context = mock(InvocationContext.class);
TestJaxRsDummyPatientProvider provider = spy(TestJaxRsDummyPatientProvider.class);
when(context.getTarget()).thenReturn(provider);
doReturn("http://baseUri").when(provider).getBaseForServer();
doReturn(new HashMap<String, String[]>()).when(provider).getParameters();
doReturn(mock(HttpHeaders.class)).when(provider).getHeaders();
UriInfo uriInfo = mock(UriInfo.class);
when(uriInfo.getRequestUri()).thenReturn(new URI("http://base/foo"));
provider.setUriInfo(uriInfo);
}
@Test
public void testInterceptWithBaseServerError() throws Throwable {
NotImplementedOperationException thrownException = new NotImplementedOperationException("not implemented");
when(context.proceed()).thenThrow(thrownException);
try {
interceptor.intercept(context);
fail();
} catch (BaseServerResponseException e) {
assertEquals(e.getMessage(), thrownException.getMessage());
}
}
@Test
public void testIntercepWithServletError() throws Throwable {
ExceptionHandlingInterceptor exceptionHandler = mock(ExceptionHandlingInterceptor.class);
when(exceptionHandler.preProcessOutgoingException(any(RequestDetails.class), any(Throwable.class),
isNull(HttpServletRequest.class))).thenThrow(new ServletException("someMessage"));
interceptor = new JaxRsExceptionInterceptor(exceptionHandler);
when(context.proceed()).thenThrow(new ServletException());
try {
interceptor.intercept(context);
fail();
} catch (BaseServerResponseException e) {
assertTrue(e.getMessage().contains("someMessage"));
}
}
@Test
public void testInterceptServletWithoutError() throws Throwable {
Object expected = new Object();
when(context.proceed()).thenReturn(expected);
Object result = interceptor.intercept(context);
assertSame(expected, result);
}
@Test
public void testHandleExceptionWithServletError() throws Throwable {
JaxRsRequest request = ((AbstractJaxRsProvider) context.getTarget()).getRequest(null, null).build();
ExceptionHandlingInterceptor exceptionHandler = spy(ExceptionHandlingInterceptor.class);
interceptor = new JaxRsExceptionInterceptor(exceptionHandler);
when(context.proceed()).thenThrow(new ServletException());
JaxRsResponseException thrownException = new JaxRsResponseException(new NotImplementedOperationException("not implemented"));
doThrow(new javax.servlet.ServletException("someMessage")).when(exceptionHandler).handleException(request, thrownException);
Response result = interceptor.convertExceptionIntoResponse(request, thrownException);
assertEquals(InternalErrorException.STATUS_CODE, result.getStatus());
}
}