Add and improve tests for view Sone page
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / pages / ViewSonePageTest.kt
1 package net.pterodactylus.sone.web.pages
2
3 import net.pterodactylus.sone.data.Post
4 import net.pterodactylus.sone.data.PostReply
5 import net.pterodactylus.sone.data.Profile
6 import net.pterodactylus.sone.data.Sone
7 import net.pterodactylus.sone.test.mock
8 import net.pterodactylus.sone.test.whenever
9 import net.pterodactylus.sone.utils.asOptional
10 import org.hamcrest.MatcherAssert.assertThat
11 import org.hamcrest.Matchers.contains
12 import org.hamcrest.Matchers.equalTo
13 import org.hamcrest.Matchers.nullValue
14 import org.junit.Before
15 import org.junit.Test
16
17 /**
18  * Unit test for [ViewSonePage].
19  */
20 class ViewSonePageTest: WebPageTest() {
21
22         init {
23                 whenever(currentSone.id).thenReturn("sone-id")
24         }
25
26         private val page = ViewSonePage(template, webInterface)
27         private val post1 = createPost("post1", "First Post.", 1000, currentSone)
28         private val post2 = createPost("post2", "Second Post.", 2000, currentSone)
29         private val foreignPost1 = createPost("foreign-post1", "First Foreign Post.", 1000, mock<Sone>())
30         private val foreignPost2 = createPost("foreign-post2", "Second Foreign Post.", 2000, mock<Sone>())
31         private val directed1 = createPost("post3", "First directed.", 1500, mock<Sone>(), recipient = currentSone)
32         private val directed2 = createPost("post4", "Second directed.", 2500, mock<Sone>(), recipient = currentSone)
33
34         override fun getPage() = page
35
36         @Before
37         fun setup() {
38                 whenever(currentSone.posts).thenReturn(mutableListOf(post2, post1))
39                 whenever(core.getDirectedPosts("sone-id")).thenReturn(setOf(directed1, directed2))
40                 core.preferences.postsPerPage = 2
41         }
42
43         @Test
44         fun `page returns correct path`() {
45                 assertThat(page.path, equalTo("viewSone.html"))
46         }
47
48         @Test
49         fun `page does not require login`() {
50                 assertThat(page.requiresLogin(), equalTo(false))
51         }
52
53         @Test
54         fun `get request without sone parameter stores null in template context`() {
55                 verifyNoRedirect {
56                         assertThat(templateContext["sone"], nullValue())
57                         assertThat(templateContext["soneId"], equalTo<Any>(""))
58                 }
59         }
60
61         @Test
62         fun `get request with invalid sone parameter stores null in template context`() {
63                 addHttpRequestParameter("sone", "invalid-sone-id")
64                 verifyNoRedirect {
65                         assertThat(templateContext["sone"], nullValue())
66                         assertThat(templateContext["soneId"], equalTo<Any>("invalid-sone-id"))
67                 }
68         }
69
70         @Test
71         fun `get request with valid sone parameter stores sone in template context`() {
72                 whenever(currentSone.posts).thenReturn(mutableListOf())
73                 whenever(core.getDirectedPosts("sone-id")).thenReturn(emptyList())
74                 addHttpRequestParameter("sone", "sone-id")
75                 addSone("sone-id", currentSone)
76                 verifyNoRedirect {
77                         assertThat(templateContext["sone"], equalTo<Any>(currentSone))
78                         assertThat(templateContext["soneId"], equalTo<Any>("sone-id"))
79                 }
80         }
81
82         private fun createPost(id: String, text: String, time: Long, sender: Sone? = null, recipient: Sone? = null) = mock<Post>().apply {
83                 whenever(this.id).thenReturn(id)
84                 sender?.run { whenever(this@apply.sone).thenReturn(this) }
85                 val recipientId = recipient?.id
86                 whenever(this.recipientId).thenReturn(recipientId.asOptional())
87                 whenever(this.recipient).thenReturn(recipient.asOptional())
88                 whenever(this.time).thenReturn(time)
89                 whenever(this.text).thenReturn(text)
90         }
91
92         @Test
93         @Suppress("UNCHECKED_CAST")
94         fun `request with valid sone stores posts and directed posts in template context`() {
95                 addSone("sone-id", currentSone)
96                 addHttpRequestParameter("sone", "sone-id")
97                 verifyNoRedirect {
98                         assertThat(templateContext["posts"] as Iterable<Post>, contains(directed2, post2))
99                 }
100         }
101
102         @Test
103         @Suppress("UNCHECKED_CAST")
104         fun `second page of posts is shown correctly`() {
105                 addSone("sone-id", currentSone)
106                 addHttpRequestParameter("sone", "sone-id")
107                 addHttpRequestParameter("postPage", "1")
108                 verifyNoRedirect {
109                         assertThat(templateContext["posts"] as Iterable<Post>, contains(directed1, post1))
110                 }
111         }
112
113         private fun createReply(text: String, time: Long, post: Post?) = mock<PostReply>().apply {
114                 whenever(this.text).thenReturn(text)
115                 whenever(this.time).thenReturn(time)
116                 whenever(this.post).thenReturn(post.asOptional())
117         }
118
119         @Test
120         @Suppress("UNCHECKED_CAST")
121         fun `replies are shown correctly`() {
122             val reply1 = createReply("First Reply", 1500, foreignPost1)
123                 val reply2 = createReply("Second Reply", 2500, foreignPost2)
124                 val reply3 = createReply("Third Reply", 1750, post1)
125                 val reply4 = createReply("Fourth Reply", 2250, post2)
126             val reply5 = createReply("Fifth Reply", 1600, post1)
127             val reply6 = createReply("Sixth Reply", 2100, directed1)
128             val reply7 = createReply("Seventh Reply", 2200, null)
129             val reply8 = createReply("Eigth Reply", 2300, foreignPost1)
130                 whenever(currentSone.replies).thenReturn(setOf(reply1, reply2, reply3, reply4, reply5, reply6, reply7, reply8))
131                 whenever(core.getReplies("post1")).thenReturn(listOf(reply3, reply5))
132                 whenever(core.getReplies("post2")).thenReturn(listOf(reply4))
133                 whenever(core.getReplies("foreign-post1")).thenReturn(listOf(reply1))
134                 whenever(core.getReplies("foreign-post2")).thenReturn(listOf(reply2))
135                 whenever(core.getReplies("post3")).thenReturn(listOf(reply6))
136                 addSone("sone-id", currentSone)
137                 addHttpRequestParameter("sone", "sone-id")
138                 verifyNoRedirect {
139                         assertThat(templateContext["repliedPosts"] as Iterable<Post>, contains(foreignPost2,  foreignPost1))
140                 }
141         }
142
143         @Test
144         fun `page title is default for request without parameters`() {
145                 addTranslation("Page.ViewSone.Page.TitleWithoutSone", "view sone page without sone")
146                 assertThat(page.getPageTitle(freenetRequest), equalTo("view sone page without sone"))
147         }
148
149         @Test
150         fun `page title is default for request with invalid sone parameters`() {
151                 addHttpRequestParameter("sone", "invalid-sone-id")
152                 addTranslation("Page.ViewSone.Page.TitleWithoutSone", "view sone page without sone")
153                 assertThat(page.getPageTitle(freenetRequest), equalTo("view sone page without sone"))
154         }
155
156         @Test
157         fun `page title contains sone name for request with sone parameters`() {
158                 addHttpRequestParameter("sone", "sone-id")
159                 addSone("sone-id", currentSone)
160                 whenever(currentSone.profile).thenReturn(Profile(currentSone).apply {
161                         firstName = "First"
162                         middleName = "M."
163                         lastName = "Last"
164                 })
165                 addTranslation("Page.ViewSone.Title", "view sone page")
166                 assertThat(page.getPageTitle(freenetRequest), equalTo("First M. Last - view sone page"))
167         }
168
169         @Test
170         fun `page is link-excepted`() {
171             assertThat(page.isLinkExcepted(null), equalTo(true))
172         }
173
174 }