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