package org.atomhopper.abdera; import org.apache.abdera.protocol.server.CollectionAdapter; import org.apache.abdera.protocol.server.RequestContext; import org.apache.abdera.protocol.server.RequestProcessor; import org.apache.abdera.protocol.server.ResponseContext; import org.apache.abdera.protocol.server.Target; import org.apache.abdera.protocol.server.TargetType; import org.apache.abdera.protocol.server.context.ResponseContextException; import org.apache.abdera.protocol.server.impl.AbstractCollectionAdapter; import org.atomhopper.config.v1_0.HostConfiguration; import org.junit.Before; import org.junit.Test; import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import org.mockito.InOrder; import java.util.HashMap; import static junit.framework.Assert.assertEquals; import static org.mockito.Mockito.any; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @RunWith(Enclosed.class) public class WorkspaceProviderTest { private static TestableWorkspaceProvider workspaceProvider; public static class WhenProcessingRequest { @Before public void setup() { workspaceProvider = new TestableWorkspaceProvider(); } @Test public void shouldReturn404GivenNullTarget() { ResponseContext responseContext = workspaceProvider.process(REQUEST_TARGET_ISNULL); assertEquals("Should respond with 404 not found", 404, responseContext.getStatus()); } @Test public void shouldReturn404GivenUnknownTargetType() { ResponseContext responseContext = workspaceProvider.process(REQUEST_TARGET_TYPE_UNKNOWN); assertEquals("Should respond with 404 not found", 404, responseContext.getStatus()); } @Test public void shouldReturn404GivenTargetTypeWithNoMatchingRequestProcessor() { workspaceProvider.setRequestProcessors(new HashMap<TargetType, RequestProcessor>()); ResponseContext responseContext = workspaceProvider.process(REQUEST_TARGET_TYPE_CATEGORIES); assertEquals("Should respond with 404 not found", 404, responseContext.getStatus()); } @Test public void shouldReturn404GivenRequestWithNoMatchingCollectionAdapter() { final WorkspaceManager workspaceManagerMock = workspaceProvider.getWorkspaceManager(); when(workspaceManagerMock.getCollectionAdapter(REQUEST_TARGET_TYPE_CATEGORIES)).thenReturn(null); ResponseContext responseContext = workspaceProvider.process(REQUEST_TARGET_TYPE_CATEGORIES); verify(workspaceManagerMock).getCollectionAdapter(REQUEST_TARGET_TYPE_CATEGORIES); assertEquals("Should respond with 404 not found", 404, responseContext.getStatus()); } @Test public void shouldReturnServerErrorWhenProcessingExceptionOccurs() { final WorkspaceManager workspaceManagerMock = workspaceProvider.getWorkspaceManager(); final CollectionAdapter collectionAdapterMock = mock(CollectionAdapter.class); final RequestProcessor requestProcessorMock = mock(RequestProcessor.class); workspaceProvider.addRequestProcessors(new HashMap<TargetType, RequestProcessor>() { { put(TargetType.TYPE_CATEGORIES, requestProcessorMock); } }); when(workspaceManagerMock.getCollectionAdapter(REQUEST_TARGET_TYPE_CATEGORIES)).thenReturn(collectionAdapterMock); when(requestProcessorMock.process(any(RequestContext.class), any(WorkspaceManager.class), any(CollectionAdapter.class))).thenThrow(new RuntimeException()); ResponseContext responseContext = workspaceProvider.process(REQUEST_TARGET_TYPE_CATEGORIES); assertEquals("Should respond with 500 server error", 500, responseContext.getStatus()); } } public static class WhenProcessingRequestWithTransactionalCollectionAdapter { RequestContext requestContext; WorkspaceManager workspaceManagerMock; AbstractCollectionAdapter collectionAdapterMock; RequestProcessor categoriesRequestProcessorMock; @Before public void setup() { workspaceProvider = new TestableWorkspaceProvider(); requestContext = requestContext(target(TargetType.TYPE_CATEGORIES)); workspaceManagerMock = workspaceProvider.getWorkspaceManager(); collectionAdapterMock = mock(AbstractCollectionAdapter.class); categoriesRequestProcessorMock = mock(RequestProcessor.class); workspaceProvider.addRequestProcessors(new HashMap<TargetType, RequestProcessor>() { { put(TargetType.TYPE_CATEGORIES, categoriesRequestProcessorMock); } }); when(workspaceManagerMock.getCollectionAdapter(requestContext)).thenReturn(collectionAdapterMock); } @Test public void shouldStartAndEndTransaction() throws ResponseContextException { final ResponseContext processorResponse = mock(ResponseContext.class); when(categoriesRequestProcessorMock.process(any(RequestContext.class), any(WorkspaceManager.class), any(CollectionAdapter.class))).thenReturn(processorResponse); ResponseContext responseContext = workspaceProvider.process(requestContext); InOrder inOrder = inOrder(collectionAdapterMock); inOrder.verify(collectionAdapterMock).start(requestContext); inOrder.verify(collectionAdapterMock).end(requestContext, responseContext); inOrder.verify(collectionAdapterMock, never()).compensate(eq(requestContext), any(Throwable.class)); } @Test public void shouldCompensateTransactionWhenExceptionOccurs() throws ResponseContextException { when(categoriesRequestProcessorMock.process(any(RequestContext.class), any(WorkspaceManager.class), any(CollectionAdapter.class))).thenThrow(new RuntimeException()); ResponseContext responseContext = workspaceProvider.process(requestContext); InOrder inOrder = inOrder(collectionAdapterMock); inOrder.verify(collectionAdapterMock).start(requestContext); inOrder.verify(collectionAdapterMock).compensate(eq(requestContext), any(Throwable.class)); inOrder.verify(collectionAdapterMock).end(requestContext, responseContext); } } private static final RequestContext REQUEST_TARGET_ISNULL = requestContext(null); private static final RequestContext REQUEST_TARGET_TYPE_UNKNOWN = requestContext(target(TargetType.TYPE_NOT_FOUND)); private static final RequestContext REQUEST_TARGET_TYPE_CATEGORIES = requestContext(target(TargetType.TYPE_CATEGORIES)); public static class WhenRequestIsNotHandledByDefaultCollectionAdapterBehavior { @Test public void shouldProcessAsExtensionRequest() { final WorkspaceProvider workspaceProvider = new TestableWorkspaceProvider(); final RequestContext requestContext = requestContext(target(TargetType.TYPE_CATEGORIES)); final WorkspaceManager workspaceManagerMock = workspaceProvider.getWorkspaceManager(); final CollectionAdapter collectionAdapterMock = mock(CollectionAdapter.class); final RequestProcessor requestProcessorMock = mock(RequestProcessor.class); workspaceProvider.addRequestProcessors(new HashMap<TargetType, RequestProcessor>() { { put(TargetType.TYPE_CATEGORIES, requestProcessorMock); } }); when(workspaceManagerMock.getCollectionAdapter(requestContext)).thenReturn(collectionAdapterMock); when(requestProcessorMock.process(requestContext, workspaceManagerMock, collectionAdapterMock)).thenReturn(null); ResponseContext responseContext = workspaceProvider.process(requestContext); verify(collectionAdapterMock).extensionRequest(requestContext); } } public static RequestContext requestContext(Target target) { RequestContext context = mock(RequestContext.class); when(context.getTarget()).thenReturn(target); return context; } public static Target target(TargetType type) { Target target = mock(Target.class); when(target.getType()).thenReturn(type); return target; } private static class TestableWorkspaceProvider extends WorkspaceProvider { final WorkspaceManager workspaceManagerMock = mock(WorkspaceManager.class); private TestableWorkspaceProvider() { super(new HostConfiguration()); } @Override public WorkspaceManager getWorkspaceManager() { return workspaceManagerMock; } } }