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