Skip to content

Commit 940680b

Browse files
committed
Popular posts
1 parent b76c985 commit 940680b

7 files changed

Lines changed: 59 additions & 1 deletion

File tree

src/main/java/alexp/blog/controller/PostsController.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ public String showPostsList(@RequestParam(value = "page", defaultValue = "0") In
5252
return "[" + posts.stream().map(this::toJsonLink).collect(Collectors.joining(", \n")) + "]";
5353
}
5454

55+
@RequestMapping(value = {"/posts/top"}, method = RequestMethod.GET, headers="Accept=application/json")
56+
public @ResponseBody String getTopPostsList() {
57+
List<Post> posts = postService.getTopPostsList();
58+
59+
return "[" + posts.stream().map(this::toJsonLink).collect(Collectors.joining(", \n")) + "]";
60+
}
61+
5562
@RequestMapping(value = "/posts", method = RequestMethod.GET, params = {"tagged"})
5663
public String searchByTag(@RequestParam("tagged") String tagsStr, @RequestParam(value = "page", defaultValue = "0") Integer pageNumber,
5764
ModelMap model, HttpServletRequest request) {

src/main/java/alexp/blog/repository/PostRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,7 @@ public interface PostRepository extends JpaRepository<Post, Long> {
2121

2222
@Query("SELECT p FROM Post p WHERE :tagCount = (SELECT COUNT(DISTINCT t.id) FROM Post p2 JOIN p2.tags t WHERE p.hidden = false and LOWER(t.name) in (:tags) and p = p2)")
2323
Page<Post> findByTagsAndNotHidden(@Param("tags") Collection<String> tags, @Param("tagCount") Long tagCount, Pageable pageable);
24+
25+
@Query("SELECT p FROM Post p JOIN p.postRatings r WHERE p.hidden = false GROUP BY p ORDER BY SUM(r.value) DESC")
26+
List<Post> findTopPosts(Pageable pageable);
2427
}

src/main/java/alexp/blog/service/PostService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public interface PostService {
1212

1313
List<Post> getPostsList(int pageNumber, int pageSize);
1414

15+
List<Post> getTopPostsList();
16+
1517
Post getPost(Long id);
1618

1719
PostEditDto getEditablePost(Long id);

src/main/java/alexp/blog/service/PostServiceImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ public List<Post> getPostsList(int pageNumber, int pageSize) {
4747
return postRepository.findByHiddenIs(false, pageRequest);
4848
}
4949

50+
// probably needs to be cached somehow
51+
@Override
52+
public List<Post> getTopPostsList() {
53+
PageRequest pageRequest = new PageRequest(0, 10);
54+
55+
return postRepository.findTopPosts(pageRequest);
56+
}
57+
5058
@Override
5159
public Post getPost(Long id) {
5260
return postRepository.findOne(id);

src/main/webapp/WEB-INF/templates/layouts/blog.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
<script th:inline="javascript">
4545
window.postsUrl = /*[[@{/posts}]]*/ '';
46+
window.popularPostsUrl = /*[[@{/posts/top}]]*/ '';
4647
</script>
4748

4849
<div class="container-fluid">
@@ -124,6 +125,14 @@ <h1>Blog</h1>
124125
<h4>Latest posts</h4>
125126

126127

128+
</div>
129+
</div>
130+
131+
<div id="popularPosts" class="panel panel-default">
132+
<div class="panel-body">
133+
<h4>Popular posts</h4>
134+
135+
127136
</div>
128137
</div>
129138
</div>

src/main/webapp/js/common.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,19 @@ $(document).ready(function() {
5757
}).appendTo('#latestPosts div');
5858
}
5959
});
60+
61+
$.ajax({
62+
dataType: "json",
63+
url: window.popularPostsUrl,
64+
success: function (data) {
65+
var items = [];
66+
$.each(data, function(key, val) {
67+
items.push('<li><a href="' + window.postsUrl + '/' + val.id + '">' + val.title + '</a></li>');
68+
});
69+
$("<ul/>", {
70+
class: 'list-no-indent',
71+
html: items.join('')
72+
}).appendTo('#popularPosts div');
73+
}
74+
});
6075
});

src/test/java/alexp/blog/controller/PostsControllerIT.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void shouldShowPostsPage() throws Exception {
3737
}
3838

3939
@Test
40-
@ExpectedDatabase("data.xml")
40+
@DatabaseSetup("data.xml")
4141
public void shouldGetPostsList() throws Exception {
4242
mockMvc.perform(get("/posts").accept(MediaType.APPLICATION_JSON))
4343
.andExpect(status().isOk())
@@ -48,6 +48,20 @@ public void shouldGetPostsList() throws Exception {
4848
.andExpect(jsonPath("$[1].title", is("hello title")));
4949
}
5050

51+
@Test
52+
@ExpectedDatabase("data-posts-voted.xml")
53+
@DatabaseSetup("data-posts-voted.xml")
54+
@DatabaseTearDown(value = "data.xml", type = DatabaseOperation.TRUNCATE_TABLE) // to reset id sequence, otherwise other tests that insert and check id will fail on ExpectedDatabase
55+
public void shouldGetTopPostsList() throws Exception {
56+
mockMvc.perform(get("/posts/top").accept(MediaType.APPLICATION_JSON))
57+
.andExpect(status().isOk())
58+
.andExpect(jsonPath("$", hasSize(2)))
59+
.andExpect(jsonPath("$[0].id", is("1")))
60+
.andExpect(jsonPath("$[0].title", is("hello title")))
61+
.andExpect(jsonPath("$[1].id", is("2")))
62+
.andExpect(jsonPath("$[1].title", is("meow title")));
63+
}
64+
5165
@Test
5266
@ExpectedDatabase("data.xml")
5367
public void shouldShowPostPage() throws Exception {

0 commit comments

Comments
 (0)