1 package net.pterodactylus.sone.web.pages
3 import com.google.common.base.Optional.fromNullable
4 import com.google.common.base.Predicate
5 import net.pterodactylus.sone.data.Post
6 import net.pterodactylus.sone.data.Sone
7 import net.pterodactylus.sone.notify.PostVisibilityFilter
8 import net.pterodactylus.sone.test.getInstance
9 import net.pterodactylus.sone.test.mock
10 import net.pterodactylus.sone.test.whenever
11 import net.pterodactylus.sone.utils.Pagination
12 import net.pterodactylus.sone.web.baseInjector
13 import org.hamcrest.MatcherAssert.assertThat
14 import org.hamcrest.Matchers.contains
15 import org.hamcrest.Matchers.emptyIterable
16 import org.hamcrest.Matchers.equalTo
17 import org.hamcrest.Matchers.notNullValue
18 import org.junit.Before
20 import org.mockito.ArgumentMatchers
23 * Unit test for [IndexPage].
25 class IndexPageTest: WebPageTest({ template, webInterface -> IndexPage(template, webInterface, postVisibilityFilter) }) {
28 private val postVisibilityFilter = mock<PostVisibilityFilter>()
32 fun `page returns correct path`() {
33 assertThat(page.path, equalTo("index.html"))
37 fun `page requires login`() {
38 assertThat(page.requiresLogin(), equalTo(true))
42 fun `page returns correct title`() {
43 whenever(l10n.getString("Page.Index.Title")).thenReturn("index page title")
44 assertThat(page.getPageTitle(freenetRequest), equalTo("index page title"))
48 fun setupPostVisibilityFilter() {
49 whenever(postVisibilityFilter.isVisible(ArgumentMatchers.eq(currentSone))).thenReturn(Predicate<Post> { true })
53 fun setupCurrentSone() {
54 whenever(currentSone.id).thenReturn("current")
58 fun setupDirectedPosts() {
59 whenever(core.getDirectedPosts("current")).thenReturn(emptyList())
62 private fun createPost(time: Long, directed: Boolean = false) = mock<Post>().apply {
63 whenever(this.time).thenReturn(time)
64 whenever(recipient).thenReturn(fromNullable(if (directed) currentSone else null))
68 fun `index page shows all posts of current sone`() {
69 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
70 whenever(currentSone.posts).thenReturn(posts)
71 page.processTemplate(freenetRequest, templateContext)
72 @Suppress("UNCHECKED_CAST")
73 assertThat(templateContext["posts"] as Iterable<Post>, contains(*posts.toTypedArray()))
77 fun `index page shows posts directed at current sone from non-followed sones`() {
78 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
79 whenever(currentSone.posts).thenReturn(posts)
80 val notFollowedSone = mock<Sone>()
81 val notFollowedPosts = listOf(createPost(2500, true), createPost(1500))
82 whenever(notFollowedSone.posts).thenReturn(notFollowedPosts)
83 addSone("notfollowed1", notFollowedSone)
84 whenever(core.getDirectedPosts("current")).thenReturn(listOf(notFollowedPosts[0]))
85 page.processTemplate(freenetRequest, templateContext)
86 @Suppress("UNCHECKED_CAST")
87 assertThat(templateContext["posts"] as Iterable<Post>, contains(
88 posts[0], notFollowedPosts[0], posts[1], posts[2]
93 fun `index page does not show duplicate posts`() {
94 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
95 whenever(currentSone.posts).thenReturn(posts)
96 val followedSone = mock<Sone>()
97 val followedPosts = listOf(createPost(2500, true), createPost(1500))
98 whenever(followedSone.posts).thenReturn(followedPosts)
99 whenever(currentSone.friends).thenReturn(listOf("followed1", "followed2"))
100 addSone("followed1", followedSone)
101 page.processTemplate(freenetRequest, templateContext)
102 @Suppress("UNCHECKED_CAST")
103 assertThat(templateContext["posts"] as Iterable<Post>, contains(
104 posts[0], followedPosts[0], posts[1], followedPosts[1], posts[2]
109 fun `index page uses post visibility filter`() {
110 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
111 whenever(currentSone.posts).thenReturn(posts)
112 val followedSone = mock<Sone>()
113 val followedPosts = listOf(createPost(2500, true), createPost(1500))
114 whenever(followedSone.posts).thenReturn(followedPosts)
115 whenever(currentSone.friends).thenReturn(listOf("followed1", "followed2"))
116 whenever(postVisibilityFilter.isVisible(ArgumentMatchers.eq(currentSone))).thenReturn(Predicate<Post> { (it?.time ?: 10000) < 2500 })
117 addSone("followed1", followedSone)
118 page.processTemplate(freenetRequest, templateContext)
119 @Suppress("UNCHECKED_CAST")
120 assertThat(templateContext["posts"] as Iterable<Post>, contains(
121 posts[1], followedPosts[1], posts[2]
126 fun `index page sets pagination correctly`() {
127 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
128 whenever(currentSone.posts).thenReturn(posts)
129 page.processTemplate(freenetRequest, templateContext)
130 @Suppress("UNCHECKED_CAST")
131 assertThat((templateContext["pagination"] as Pagination<Post>).items, contains(
132 posts[0], posts[1], posts[2]
137 fun `index page sets page correctly`() {
138 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
139 whenever(currentSone.posts).thenReturn(posts)
140 core.preferences.newPostsPerPage = 1
141 addHttpRequestParameter("page", "2")
142 page.processTemplate(freenetRequest, templateContext)
143 @Suppress("UNCHECKED_CAST")
144 assertThat((templateContext["pagination"] as Pagination<Post>).page, equalTo(2))
148 fun `index page without posts sets correct pagination`() {
149 core.preferences.newPostsPerPage = 1
150 page.processTemplate(freenetRequest, templateContext)
151 @Suppress("UNCHECKED_CAST")
152 (templateContext["pagination"] as Pagination<Post>).let { pagination ->
153 assertThat(pagination.items, emptyIterable())
158 fun `page can be created by dependency injection`() {
159 assertThat(baseInjector.getInstance<IndexPage>(), notNullValue())