6d87f3a5dff33ba61d484d2db26d743369817725
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / pages / IndexPageTest.kt
1 package net.pterodactylus.sone.web.pages
2
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.mock
9 import net.pterodactylus.sone.test.whenever
10 import net.pterodactylus.sone.utils.Pagination
11 import net.pterodactylus.util.web.Method.GET
12 import org.hamcrest.MatcherAssert.assertThat
13 import org.hamcrest.Matchers.contains
14 import org.hamcrest.Matchers.emptyIterable
15 import org.hamcrest.Matchers.equalTo
16 import org.junit.Before
17 import org.junit.Test
18 import org.mockito.ArgumentMatchers
19
20 /**
21  * Unit test for [IndexPage].
22  */
23 class IndexPageTest : WebPageTest() {
24
25         private val postVisibilityFilter = mock<PostVisibilityFilter>()
26         private val page = IndexPage(template, webInterface, postVisibilityFilter)
27
28         @Test
29         fun `page returns correct path`() {
30             assertThat(page.path, equalTo("index.html"))
31         }
32
33         @Test
34         fun `page requires login`() {
35             assertThat(page.requiresLogin(), equalTo(true))
36         }
37
38         @Test
39         fun `page returns correct title`() {
40                 whenever(l10n.getString("Page.Index.Title")).thenReturn("index page title")
41             assertThat(page.getPageTitle(freenetRequest), equalTo("index page title"))
42         }
43
44         @Before
45         fun setupPostVisibilityFilter() {
46                 whenever(postVisibilityFilter.isVisible(ArgumentMatchers.eq(currentSone))).thenReturn(Predicate<Post> { true })
47         }
48
49         @Before
50         fun setupCurrentSone() {
51                 whenever(currentSone.id).thenReturn("current")
52         }
53
54         @Before
55         fun setupDirectedPosts() {
56                 whenever(core.getDirectedPosts("current")).thenReturn(emptyList())
57         }
58
59         private fun createPost(time: Long, directed: Boolean = false) = mock<Post>().apply {
60                 whenever(this.time).thenReturn(time)
61                 whenever(recipient).thenReturn(fromNullable(if (directed) currentSone else null))
62         }
63
64         @Test
65         fun `index page shows all posts of current sone`() {
66                 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
67                 whenever(currentSone.posts).thenReturn(posts)
68                 request("", GET)
69                 page.processTemplate(freenetRequest, templateContext)
70                 @Suppress("UNCHECKED_CAST")
71                 assertThat(templateContext["posts"] as Iterable<Post>, contains(*posts.toTypedArray()))
72         }
73
74         @Test
75         fun `index page shows posts directed at current sone from non-followed sones`() {
76                 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
77                 whenever(currentSone.posts).thenReturn(posts)
78                 val notFollowedSone = mock<Sone>()
79                 val notFollowedPosts = listOf(createPost(2500, true), createPost(1500))
80                 whenever(notFollowedSone.posts).thenReturn(notFollowedPosts)
81                 addSone("notfollowed1", notFollowedSone)
82                 request("", GET)
83                 whenever(core.getDirectedPosts("current")).thenReturn(listOf(notFollowedPosts[0]))
84                 page.processTemplate(freenetRequest, templateContext)
85                 @Suppress("UNCHECKED_CAST")
86                 assertThat(templateContext["posts"] as Iterable<Post>, contains(
87                                 posts[0], notFollowedPosts[0], posts[1], posts[2]
88                 ))
89         }
90
91         @Test
92         fun `index page does not show duplicate posts`() {
93                 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
94                 whenever(currentSone.posts).thenReturn(posts)
95                 val followedSone = mock<Sone>()
96                 val followedPosts = listOf(createPost(2500, true), createPost(1500))
97                 whenever(followedSone.posts).thenReturn(followedPosts)
98                 whenever(currentSone.friends).thenReturn(listOf("followed1", "followed2"))
99                 addSone("followed1", followedSone)
100                 request("", GET)
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]
105                 ))
106         }
107
108         @Test
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                 request("", GET)
119                 page.processTemplate(freenetRequest, templateContext)
120                 @Suppress("UNCHECKED_CAST")
121                 assertThat(templateContext["posts"] as Iterable<Post>, contains(
122                                 posts[1], followedPosts[1], posts[2]
123                 ))
124         }
125
126         @Test
127         fun `index page sets pagination correctly`() {
128                 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
129                 whenever(currentSone.posts).thenReturn(posts)
130                 request("", GET)
131                 page.processTemplate(freenetRequest, templateContext)
132                 @Suppress("UNCHECKED_CAST")
133                 assertThat((templateContext["pagination"] as Pagination<Post>).items, contains(
134                                 posts[0], posts[1], posts[2]
135                 ))
136         }
137
138         @Test
139         fun `index page sets page correctly`() {
140                 val posts = listOf(createPost(3000), createPost(2000), createPost(1000))
141                 whenever(currentSone.posts).thenReturn(posts)
142                 request("", GET)
143                 core.preferences.postsPerPage = 1
144                 addHttpRequestParameter("page", "2")
145                 page.processTemplate(freenetRequest, templateContext)
146                 @Suppress("UNCHECKED_CAST")
147                 assertThat((templateContext["pagination"] as Pagination<Post>).page, equalTo(2))
148         }
149
150         @Test
151         fun `index page without posts sets correct pagination`() {
152                 request("", GET)
153                 core.preferences.postsPerPage = 1
154                 page.processTemplate(freenetRequest, templateContext)
155                 @Suppress("UNCHECKED_CAST")
156                 (templateContext["pagination"] as Pagination<Post>).let { pagination ->
157                         assertThat(pagination.items, emptyIterable())
158                 }
159         }
160
161 }