package sagan.blog.support;
import sagan.blog.Post;
import sagan.blog.PostBuilder;
import sagan.blog.PostNotFoundException;
import sagan.search.support.SearchService;
import sagan.support.DateFactory;
import sagan.support.nav.PageableFactory;
import sagan.team.MemberProfile;
import saganx.AbstractIntegrationTests;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.collection.IsIn.isIn;
import static org.hamcrest.core.IsNot.not;
import static org.mockito.BDDMockito.given;
import static org.mockito.MockitoAnnotations.initMocks;
import static sagan.blog.PostCategory.*;
public class BlogService_QueryTests extends AbstractIntegrationTests {
private static final Pageable FIRST_TEN_POSTS = PageableFactory.forLists(1);
@Mock
private DateFactory dateFactory;
@Mock
private SearchService searchService;
@Mock
private PostFormAdapter postFormAdapter;
@Rule
public ExpectedException expected = ExpectedException.none();
@Autowired
private PostRepository postRepository;
private BlogService service;
private Date yesterday;
private Date today;
private Date tomorrow;
private Post published;
private Post scheduled;
private Post draft;
private int px = 0;
@Before
public void setup() throws Exception {
initMocks(this);
service = new BlogService(postRepository, postFormAdapter, dateFactory, searchService);
setupDates();
setupFixtureData();
}
private void setupDates() throws Exception {
yesterday = new SimpleDateFormat("yyyy-MM-dd").parse("2013-06-13");
today = new SimpleDateFormat("yyyy-MM-dd").parse("2013-06-14");
tomorrow = new SimpleDateFormat("yyyy-MM-dd").parse("2013-06-15");
given(dateFactory.now()).willReturn(today);
}
private void setupFixtureData() throws Exception {
assertThat(postRepository.findAll().size(), equalTo(0));
scheduled = PostBuilder.post().category(ENGINEERING).title("scheduled").publishAt(tomorrow).build();
postRepository.save(scheduled);
published = PostBuilder.post().category(ENGINEERING).title("published").publishAt(yesterday).build();
postRepository.save(published);
draft = PostBuilder.post().title("draft").draft().build();
postRepository.save(draft);
}
@Test
public void postIsRetrievableById() {
assertThat(service.getPost(published.getId()), equalTo(published));
}
@Test
public void postIsRetrievableByTitleAndCreatedDate() {
assertThat(service.getPost(published.getTitle(), published.getCreatedAt()), equalTo(published));
}
@Test
public void publishedPostIsRetrievable() {
assertThat(service.getPublishedPost(published.getPublicSlug()), equalTo(published));
}
@Test
public void getPublishedDoesNotFindDrafts() {
Post draft = PostBuilder.post().title(uniqueTitle()).draft().build();
postRepository.save(draft);
expected.expect(PostNotFoundException.class);
service.getPublishedPost(draft.getPublicSlug());
}
@Test
public void getPublishedDoesNotFindScheduledPost() throws ParseException {
expected.expect(PostNotFoundException.class);
service.getPublishedPost(scheduled.getPublicSlug());
}
@Test
public void nonExistentPostThrowsException() {
expected.expect(PostNotFoundException.class);
service.getPost(999L);
}
@Test
public void getPublishedPostsWithPagination() {
Page<Post> publishedPosts = service.getPublishedPosts(FIRST_TEN_POSTS);
assertThat(publishedPosts.getContent(), contains(published));
}
@Test
public void getAllPublishedPosts() {
Post anotherPost = PostBuilder.post().publishAt(yesterday).title("another post").build();
postRepository.save(anotherPost);
List<Post> publishedPosts = service.getAllPublishedPosts();
assertThat(publishedPosts, containsInAnyOrder(published, anotherPost));
}
@Test
public void getPublishedPostsExcludesDrafts() throws ParseException {
List<Post> publishedPosts = service.getPublishedPosts(FIRST_TEN_POSTS).getContent();
assertThat(draft, not(isIn(publishedPosts)));
}
@Test
public void getPublishedPostsExcludesScheduledPosts() throws ParseException {
List<Post> publishedPosts = service.getPublishedPosts(FIRST_TEN_POSTS).getContent();
assertThat(scheduled, not(isIn(publishedPosts)));
}
@Test
public void getScheduledPosts() throws ParseException {
List<Post> scheduledPosts = service.getScheduledPosts(FIRST_TEN_POSTS).getContent();
assertThat(scheduledPosts, contains(scheduled));
}
@Test
public void getScheduledPostsExcludesScheduledDrafts() throws ParseException {
Post scheduledDraft = PostBuilder.post().title(uniqueTitle()).draft().publishAt(tomorrow).build();
postRepository.save(scheduledDraft);
List<Post> scheduledPosts = service.getScheduledPosts(FIRST_TEN_POSTS).getContent();
assertThat(scheduledDraft, not(isIn(scheduledPosts)));
}
@Test
public void getScheduledPostsExcludesPublishedPosts() throws ParseException {
List<Post> scheduledPosts = service.getScheduledPosts(FIRST_TEN_POSTS).getContent();
assertThat(published, not(isIn(scheduledPosts)));
}
@Test
public void listPostsForCategory() {
Post newsPost = PostBuilder.post().title(uniqueTitle()).publishAt(yesterday).category(NEWS_AND_EVENTS).build();
postRepository.save(newsPost);
Page<Post> publishedPosts = service.getPublishedPosts(NEWS_AND_EVENTS, FIRST_TEN_POSTS);
assertThat(publishedPosts.getContent(), contains(newsPost));
}
@Test
public void listPostsForCategoryExcludesScheduledPosts() throws ParseException {
Post publishedRelease = PostBuilder.post().title(uniqueTitle()).publishAt(yesterday).category(RELEASES).build();
postRepository.save(publishedRelease);
Post scheduledRelease = PostBuilder.post().title(uniqueTitle()).publishAt(tomorrow).category(RELEASES).build();
postRepository.save(scheduledRelease);
List<Post> releases = service.getPublishedPosts(RELEASES, FIRST_TEN_POSTS).getContent();
assertThat(scheduledRelease, not(isIn(releases)));
}
@Test
public void paginationInfoBasedOnCurrentPageAndTotalPosts() {
postRepository.deleteAll();
List<Post> posts = new ArrayList<>();
long itemCount = 11;
for (int i = 0; i < itemCount; ++i) {
posts.add(PostBuilder.post().title(uniqueTitle()).build());
}
postRepository.save(posts);
PageRequest pageRequest = new PageRequest(0, 10);
Page<Post> result = service.getAllPosts(pageRequest);
assertThat(result.getTotalElements(), is(itemCount));
}
@Test
public void listBroadcasts() {
Post broadcast = PostBuilder.post().isBroadcast().title(uniqueTitle()).publishAt(yesterday).build();
postRepository.save(broadcast);
List<Post> broadcasts = service.getPublishedBroadcastPosts(FIRST_TEN_POSTS).getContent();
assertThat(broadcasts, contains(broadcast));
}
@Test
public void listBroadcastsExcludesScheduledPosts() throws ParseException {
Post publishedBroadcast = PostBuilder.post().title(uniqueTitle()).isBroadcast().publishAt(yesterday).build();
postRepository.save(publishedBroadcast);
Post scheduledBroadcast = PostBuilder.post().title(uniqueTitle()).isBroadcast().publishAt(tomorrow).build();
postRepository.save(scheduledBroadcast);
List<Post> broadcasts = service.getPublishedBroadcastPosts(FIRST_TEN_POSTS).getContent();
assertThat(scheduledBroadcast, not(isIn(broadcasts)));
}
@Test
public void allPosts() {
Page<Post> allPosts = service.getAllPosts(FIRST_TEN_POSTS);
assertThat(allPosts.getContent(), containsInAnyOrder(published, scheduled, draft));
}
@Test
public void getPublishedPostsForAuthorOnlyShowsAuthorsPosts() {
MemberProfile profile = new MemberProfile();
profile.setUsername("myauthor");
Post post = PostBuilder.post().author(profile).title(uniqueTitle()).publishAt(yesterday).build();
postRepository.save(post);
postRepository.save(PostBuilder.post().title(uniqueTitle()).build());
Page<Post> publishedPosts = service.getPublishedPostsForMember(profile, FIRST_TEN_POSTS);
assertThat(publishedPosts.getContent(), contains(post));
}
@Test
public void getPublishedPostsForAuthorOnlyShowsPublishedPosts() {
MemberProfile profile = new MemberProfile();
profile.setUsername("myauthor");
Post post = PostBuilder.post().author(profile).title(uniqueTitle()).publishAt(yesterday).build();
postRepository.save(post);
postRepository.save(PostBuilder.post().title(uniqueTitle()).author(profile).draft().build());
Page<Post> publishedPosts = service.getPublishedPostsForMember(profile, FIRST_TEN_POSTS);
assertThat(publishedPosts.getContent(), contains(post));
}
private String uniqueTitle() {
return "post" + ++px;
}
}