package sagan.blog.support;
import sagan.blog.Post;
import sagan.blog.PostBuilder;
import sagan.blog.PostCategory;
import sagan.support.DateFactory;
import saganx.AbstractIntegrationTests;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
public class BlogAtomFeedsTests extends AbstractIntegrationTests {
@Autowired
SiteUrl siteUrl;
@Autowired
private PostRepository postRepository;
private XPath xpath = XPathFactory.newInstance().newXPath();
private Document getAtomFeedDocument(MvcResult mvcResult) throws ParserConfigurationException, SAXException,
IOException {
String atomFeed = mvcResult.getResponse().getContentAsString();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new ByteArrayInputStream(atomFeed.getBytes()));
}
private Document doGetForDocument(String path) throws Exception {
ResultActions resultActions = mockMvc.perform(get(path));
MvcResult mvcResult = resultActions.andReturn();
return getAtomFeedDocument(mvcResult);
}
@Test
public void feedHasCorrectMetadata() throws Exception {
Document doc = doGetForDocument("/blog.atom");
assertThat(xpath.evaluate("/feed/title", doc), is("Spring"));
assertThat(xpath.evaluate("/feed/icon", doc), is(siteUrl.getAbsoluteUrl("/favicon.ico")));
assertThat(xpath.evaluate("/feed/link/@href", doc), is(siteUrl.getAbsoluteUrl("/blog")));
}
@Test
public void rendersBroadcastsFeed() throws Exception {
Document doc = doGetForDocument("/blog/broadcasts.atom");
assertThat(xpath.evaluate("/feed/title", doc), is("Spring Broadcasts"));
assertThat(xpath.evaluate("/feed/link/@href", doc), is(siteUrl.getAbsoluteUrl("/blog/broadcasts")));
}
@Test
public void rendersCategoryFeed() throws Exception {
Document doc = doGetForDocument("/blog/category/news.atom");
assertThat(xpath.evaluate("/feed/title", doc), is("Spring News and Events"));
assertThat(xpath.evaluate("/feed/link/@href", doc), is(siteUrl.getAbsoluteUrl("/blog/category/news")));
}
@Test
public void containsBlogPostFields() throws Exception {
Post post = PostBuilder.post().category(PostCategory.ENGINEERING).isBroadcast().build();
postRepository.save(post);
ResultActions resultActions = mockMvc.perform(get("/blog.atom"));
MvcResult mvcResult = resultActions
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith("application/atom+xml"))
.andReturn();
assertThat(mvcResult.getResponse().getCharacterEncoding(), equalTo("utf-8"));
String atomFeed = mvcResult.getResponse().getContentAsString();
assertThat(atomFeed, containsString(post.getTitle()));
assertThat(atomFeed, containsString(post.getRenderedContent()));
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setTimeZone(DateFactory.DEFAULT_TIME_ZONE);
String postDate = dateFormat.format(post.getCreatedAt());
assertThat(atomFeed, containsString(postDate));
assertThat(atomFeed, containsString("/blog/" + post.getPublicSlug()));
assertThat(atomFeed, containsString(PostCategory.ENGINEERING.getDisplayName()));
assertThat(atomFeed, containsString("Broadcast"));
}
@Test
public void containsAMaximumOf20Posts() throws Exception {
createPosts(21);
Document doc = doGetForDocument("/blog.atom");
XPathExpression expression = xpath.compile("//entry");
NodeList evaluate = (NodeList) expression.evaluate(doc, XPathConstants.NODESET);
assertThat(evaluate.getLength(), is(20));
}
private void createPosts(int numPostsToCreate) {
Calendar calendar = Calendar.getInstance();
List<Post> posts = new ArrayList<>();
for (int postNumber = 1; postNumber <= numPostsToCreate; postNumber++) {
calendar.set(2013, 10, postNumber);
Post post = new PostBuilder().title("This week in Spring - November " + postNumber + ", 2013")
.rawContent("Raw content")
.renderedContent("Html content")
.renderedSummary("Html summary")
.createdAt(calendar.getTime())
.build();
posts.add(post);
}
postRepository.save(posts);
}
}