package org.atomhopper.abdera;
import org.apache.abdera.i18n.iri.IRI;
import org.apache.abdera.model.Document;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;
import org.apache.abdera.parser.ParseException;
import org.apache.abdera.parser.stax.FOMEntry;
import org.apache.abdera.parser.stax.FOMFeed;
import org.apache.abdera.protocol.server.RequestContext;
import org.apache.abdera.protocol.server.ResponseContext;
import org.apache.abdera.protocol.server.Target;
import org.atomhopper.adapter.FeedPublisher;
import org.atomhopper.adapter.FeedSource;
import org.atomhopper.adapter.request.adapter.DeleteEntryRequest;
import org.atomhopper.adapter.request.adapter.GetEntryRequest;
import org.atomhopper.adapter.request.adapter.GetFeedRequest;
import org.atomhopper.adapter.request.adapter.PostEntryRequest;
import org.atomhopper.adapter.request.adapter.PutEntryRequest;
import org.atomhopper.config.v1_0.FeedConfiguration;
import org.atomhopper.response.AdapterResponse;
import org.atomhopper.response.EmptyBody;
import org.atomhopper.response.FeedSourceAdapterResponse;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.springframework.http.HttpStatus;
import java.io.IOException;
import java.util.UUID;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.fail;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(Enclosed.class)
public class FeedAdapterTest {
public static class WhenPostingEntryToFeed extends TestParent {
@Test
public void shouldReturnUnsupportedMethodGivenNoFeedPublisher() {
FeedAdapter feedAdapter = feedAdapter(false);
ResponseContext responseContext = feedAdapter.postEntry(REQUEST_CONTEXT);
assertEquals("Should respond with " + STATUS_CODE_UNSUPPORTED_METHOD, STATUS_CODE_UNSUPPORTED_METHOD, responseContext.getStatus());
}
@Test
public void shouldReturnBadContentWhenParseException() throws Exception {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedPublisher.postEntry(any(PostEntryRequest.class))).thenThrow(new ParseException());
ResponseContext responseContext = feedAdapter.postEntry(REQUEST_CONTEXT);
assertEquals("Should respond with 422", 422, responseContext.getStatus());
}
@Test
public void shouldReturnEntryResponse() throws IOException {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedPublisher.postEntry(any(PostEntryRequest.class))).thenReturn(adapterResponseForEntry());
ResponseContext responseContext = feedAdapter.postEntry(REQUEST_CONTEXT);
assertEquals("Should respond with 200", 200, responseContext.getStatus());
}
@Test
public void shouldReturnServerErrorOnFeedPublisherException() throws IOException {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedPublisher.postEntry(any(PostEntryRequest.class))).thenThrow(new RuntimeException());
ResponseContext responseContext = feedAdapter.postEntry(REQUEST_CONTEXT);
assertEquals("Should respond with 500", 500, responseContext.getStatus());
}
}
public static class WhenPuttingEntryToFeed extends TestParent {
@Test
public void shouldReturnUnsupportedMethodGivenNoFeedPublisher() {
FeedAdapter feedAdapter = feedAdapter(false);
ResponseContext responseContext = feedAdapter.putEntry(REQUEST_CONTEXT);
assertEquals("Should respond with " + STATUS_CODE_UNSUPPORTED_METHOD, STATUS_CODE_UNSUPPORTED_METHOD, responseContext.getStatus());
}
@Test
public void shouldReturnEntryResponse() throws IOException {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedPublisher.putEntry(any(PutEntryRequest.class))).thenReturn(adapterResponseForEntry());
ResponseContext responseContext = feedAdapter.putEntry(REQUEST_CONTEXT);
assertEquals("Should respond with 200", 200, responseContext.getStatus());
}
@Test
public void shouldReturnServerErrorOnFeedPublisherException() throws IOException {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedPublisher.putEntry(any(PutEntryRequest.class))).thenThrow(new RuntimeException());
ResponseContext responseContext = feedAdapter.putEntry(REQUEST_CONTEXT);
assertEquals("Should respond with 500", 500, responseContext.getStatus());
}
}
public static class WhenDeletingEntryFromFeed extends TestParent {
@Test
public void shouldReturnUnsupportedMethodGivenNoFeedPublisher() {
FeedAdapter feedAdapter = feedAdapter(false);
ResponseContext responseContext = feedAdapter.deleteEntry(REQUEST_CONTEXT);
assertEquals("Should respond with " + STATUS_CODE_UNSUPPORTED_METHOD, STATUS_CODE_UNSUPPORTED_METHOD, responseContext.getStatus());
}
@Test
public void shouldReturnEntryResponse() throws IOException {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedPublisher.deleteEntry(any(DeleteEntryRequest.class))).thenReturn(adapterResponseForEmptyBody());
ResponseContext responseContext = feedAdapter.deleteEntry(REQUEST_CONTEXT);
assertEquals("Should respond with 204", 204, responseContext.getStatus());
}
@Test
public void shouldReturnServerErrorOnFeedPublisherException() throws IOException {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedPublisher.deleteEntry(any(DeleteEntryRequest.class))).thenThrow(new RuntimeException());
ResponseContext responseContext = feedAdapter.deleteEntry(REQUEST_CONTEXT);
assertEquals("Should respond with 500", 500, responseContext.getStatus());
}
}
public static class WhenGettingEntryFromFeed extends TestParent {
@Test
public void shouldReturnEntryResponse() throws IOException {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedSource.getEntry(any(GetEntryRequest.class))).thenReturn(adapterResponseForEntry());
ResponseContext responseContext = feedAdapter.getEntry(REQUEST_CONTEXT);
assertEquals("Should respond with 200", 200, responseContext.getStatus());
}
@Test
public void shouldReturnServerErrorOnFeedSourceException() throws IOException {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedSource.getEntry(any(GetEntryRequest.class))).thenThrow(new RuntimeException());
ResponseContext responseContext = feedAdapter.getEntry(REQUEST_CONTEXT);
assertEquals("Should respond with 500", 500, responseContext.getStatus());
}
}
public static class WhenGettingFeed extends TestParent {
@Test
public void shouldReturn200Response() {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedSource.getFeed(any(GetFeedRequest.class))).thenReturn(adapterResponseForFeed());
ResponseContext responseContext = feedAdapter.getFeed(REQUEST_CONTEXT);
assertEquals("Should respond with 200", 200, responseContext.getStatus());
}
@Test
public void shouldReturnServerErrorOnFeedSourceException() throws IOException {
FeedAdapter feedAdapter = feedAdapter(true);
when(feedSource.getFeed(any(GetFeedRequest.class))).thenThrow(new RuntimeException());
ResponseContext responseContext = feedAdapter.getFeed(REQUEST_CONTEXT);
}
}
@Ignore
public static class TestParent {
static final int STATUS_CODE_UNSUPPORTED_METHOD = 405;
static final String BASE_URI = "http://localhost:8080/atom/";
static final String TARGET_PATH = "/foo/bar";
static final String SELF = "http://localhost:8080/atom/foo/bar";
final RequestContext REQUEST_CONTEXT = requestContext();
FeedConfiguration feedConfiguration;
FeedSource feedSource;
FeedPublisher feedPublisher;
public FeedAdapter feedAdapter(boolean supportsPublishing) {
feedConfiguration = mock(FeedConfiguration.class);
feedSource = mock(FeedSource.class);
if (supportsPublishing) {
feedPublisher = mock(FeedPublisher.class);
} else {
feedPublisher = null;
}
return new FeedAdapter("foo", feedConfiguration, feedSource, feedPublisher);
}
public Entry entry() {
final FOMEntry entry = new FOMEntry();
entry.setId(UUID.randomUUID().toString());
entry.setContent("testing");
return entry;
}
public Feed feed() {
final FOMFeed feed = new FOMFeed();
for (int i = 0; i < 5; i++) {
feed.addEntry(entry());
}
return feed;
}
public AdapterResponse<Entry> adapterResponseForEntry() {
return new FeedSourceAdapterResponse<Entry>(entry());
}
public AdapterResponse<Feed> adapterResponseForFeed() {
return new FeedSourceAdapterResponse<Feed>(feed());
}
public AdapterResponse<EmptyBody> adapterResponseForEmptyBody() {
return new FeedSourceAdapterResponse<EmptyBody>(EmptyBody.getInstance(), HttpStatus.OK, null);
}
public RequestContext requestContext() {
final RequestContext context = mock(RequestContext.class);
final Target targetMock = mock(Target.class);
when(targetMock.getParameter(anyString())).thenReturn("");
when(context.getResolvedUri()).thenReturn(new IRI(SELF));
when(context.getBaseUri()).thenReturn(new IRI(BASE_URI));
when(context.getTarget()).thenReturn(targetMock);
when(context.getTargetPath()).thenReturn(TARGET_PATH);
when(context.getParameterNames()).thenReturn(new String[]{});
Document document = mock(Document.class);
try {
when(context.getDocument()).thenReturn(document);
} catch (IOException e) {
fail("Unexpected exception in test");
}
when(document.getRoot()).thenReturn(entry());
return context;
}
}
}