1 package net.pterodactylus.sone.web.pages
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.getInstance
8 import net.pterodactylus.sone.test.isOnPage
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.utils.asOptional
13 import net.pterodactylus.sone.web.baseInjector
14 import org.hamcrest.MatcherAssert.assertThat
15 import org.hamcrest.Matchers.contains
16 import org.hamcrest.Matchers.equalTo
17 import org.hamcrest.Matchers.notNullValue
18 import org.hamcrest.Matchers.nullValue
19 import org.junit.Before
24 * Unit test for [ViewSonePage].
26 class ViewSonePageTest: WebPageTest(::ViewSonePage) {
29 whenever(currentSone.id).thenReturn("sone-id")
32 private val post1 = createPost("post1", "First Post.", 1000, currentSone)
33 private val post2 = createPost("post2", "Second Post.", 2000, currentSone)
34 private val foreignPost1 = createPost("foreign-post1", "First Foreign Post.", 1000, mock())
35 private val foreignPost2 = createPost("foreign-post2", "Second Foreign Post.", 2000, mock())
36 private val foreignPost3 = createPost("foreign-post3", "Third Foreign Post.", 3000, mock())
37 private val directed1 = createPost("post3", "First directed.", 1500, mock(), recipient = currentSone)
38 private val directed2 = createPost("post4", "Second directed.", 2500, mock(), recipient = currentSone)
42 whenever(currentSone.posts).thenReturn(mutableListOf(post2, post1))
43 whenever(core.getDirectedPosts("sone-id")).thenReturn(setOf(directed1, directed2))
44 core.preferences.newPostsPerPage = 2
48 fun `page returns correct path`() {
49 assertThat(page.path, equalTo("viewSone.html"))
53 fun `page does not require login`() {
54 assertThat(page.requiresLogin(), equalTo(false))
58 fun `get request without sone parameter stores null in template context`() {
60 assertThat(templateContext["sone"], nullValue())
61 assertThat(templateContext["soneId"], equalTo<Any>(""))
66 fun `get request with invalid sone parameter stores null in template context`() {
67 addHttpRequestParameter("sone", "invalid-sone-id")
69 assertThat(templateContext["sone"], nullValue())
70 assertThat(templateContext["soneId"], equalTo<Any>("invalid-sone-id"))
75 fun `get request with valid sone parameter stores sone in template context`() {
76 whenever(currentSone.posts).thenReturn(mutableListOf())
77 whenever(core.getDirectedPosts("sone-id")).thenReturn(emptyList())
78 addHttpRequestParameter("sone", "sone-id")
79 addSone("sone-id", currentSone)
81 assertThat(templateContext["sone"], equalTo<Any>(currentSone))
82 assertThat(templateContext["soneId"], equalTo<Any>("sone-id"))
86 private fun createPost(id: String, text: String, time: Long, sender: Sone? = null, recipient: Sone? = null) = mock<Post>().apply {
87 whenever(this.id).thenReturn(id)
88 sender?.run { whenever(this@apply.sone).thenReturn(this) }
89 val recipientId = recipient?.id
90 whenever(this.recipientId).thenReturn(recipientId.asOptional())
91 whenever(this.recipient).thenReturn(recipient.asOptional())
92 whenever(this.time).thenReturn(time)
93 whenever(this.text).thenReturn(text)
97 @Suppress("UNCHECKED_CAST")
98 fun `request with valid sone stores posts and directed posts in template context`() {
99 addSone("sone-id", currentSone)
100 addHttpRequestParameter("sone", "sone-id")
102 assertThat(templateContext["posts"] as Iterable<Post>, contains(directed2, post2))
103 assertThat(templateContext["postPagination"] as Pagination<Post>, isOnPage(0).hasPages(2))
108 @Suppress("UNCHECKED_CAST")
109 fun `second page of posts is shown correctly`() {
110 addSone("sone-id", currentSone)
111 addHttpRequestParameter("sone", "sone-id")
112 addHttpRequestParameter("postPage", "1")
114 assertThat(templateContext["posts"] as Iterable<Post>, contains(directed1, post1))
115 assertThat(templateContext["postPagination"] as Pagination<Post>, isOnPage(1).hasPages(2))
119 private fun createReply(text: String, time: Long, post: Post?) = mock<PostReply>().apply {
120 whenever(this.text).thenReturn(text)
121 whenever(this.time).thenReturn(time)
122 whenever(this.post).thenReturn(post.asOptional())
126 @Suppress("UNCHECKED_CAST")
127 fun `replies are shown correctly`() {
128 val reply1 = createReply("First Reply", 1500, foreignPost1)
129 val reply2 = createReply("Second Reply", 2500, foreignPost2)
130 val reply3 = createReply("Third Reply", 1750, post1)
131 val reply4 = createReply("Fourth Reply", 2250, post2)
132 val reply5 = createReply("Fifth Reply", 1600, post1)
133 val reply6 = createReply("Sixth Reply", 2100, directed1)
134 val reply7 = createReply("Seventh Reply", 2200, null)
135 val reply8 = createReply("Eigth Reply", 2300, foreignPost1)
136 val reply9 = createReply("Ninth Reply", 2050, foreignPost3)
137 whenever(currentSone.replies).thenReturn(setOf(reply1, reply2, reply3, reply4, reply5, reply6, reply7, reply8, reply9))
138 whenever(core.getReplies("post1")).thenReturn(listOf(reply3, reply5))
139 whenever(core.getReplies("post2")).thenReturn(listOf(reply4))
140 whenever(core.getReplies("foreign-post1")).thenReturn(listOf(reply8, reply1))
141 whenever(core.getReplies("foreign-post2")).thenReturn(listOf(reply2))
142 whenever(core.getReplies("post3")).thenReturn(listOf(reply6))
143 whenever(core.getReplies("foreign-post3")).thenReturn(listOf(reply9))
144 addSone("sone-id", currentSone)
145 addHttpRequestParameter("sone", "sone-id")
147 assertThat(templateContext["repliedPosts"] as Iterable<Post>, contains(foreignPost2, foreignPost1))
148 assertThat(templateContext["repliedPostPagination"] as Pagination<Post>, isOnPage(0).hasPages(2))
153 @Suppress("UNCHECKED_CAST")
154 fun `second page of replies is shown correctly`() {
155 val reply1 = createReply("First Reply", 1500, foreignPost1)
156 val reply2 = createReply("Second Reply", 2500, foreignPost2)
157 val reply3 = createReply("Third Reply", 1750, post1)
158 val reply4 = createReply("Fourth Reply", 2250, post2)
159 val reply5 = createReply("Fifth Reply", 1600, post1)
160 val reply6 = createReply("Sixth Reply", 2100, directed1)
161 val reply7 = createReply("Seventh Reply", 2200, null)
162 val reply8 = createReply("Eigth Reply", 2300, foreignPost1)
163 val reply9 = createReply("Ninth Reply", 2050, foreignPost3)
164 whenever(currentSone.replies).thenReturn(setOf(reply1, reply2, reply3, reply4, reply5, reply6, reply7, reply8, reply9))
165 whenever(core.getReplies("post1")).thenReturn(listOf(reply3, reply5))
166 whenever(core.getReplies("post2")).thenReturn(listOf(reply4))
167 whenever(core.getReplies("foreign-post1")).thenReturn(listOf(reply8, reply1))
168 whenever(core.getReplies("foreign-post2")).thenReturn(listOf(reply2))
169 whenever(core.getReplies("post3")).thenReturn(listOf(reply6))
170 whenever(core.getReplies("foreign-post3")).thenReturn(listOf(reply9))
171 addSone("sone-id", currentSone)
172 addHttpRequestParameter("sone", "sone-id")
173 addHttpRequestParameter("repliedPostPage", "1")
175 assertThat(templateContext["repliedPosts"] as Iterable<Post>, contains(foreignPost3))
176 assertThat(templateContext["repliedPostPagination"] as Pagination<Post>, isOnPage(1).hasPages(2))
181 fun `page title is default for request without parameters`() {
182 addTranslation("Page.ViewSone.Page.TitleWithoutSone", "view sone page without sone")
183 assertThat(page.getPageTitle(soneRequest), equalTo("view sone page without sone"))
187 fun `page title is default for request with invalid sone parameters`() {
188 addHttpRequestParameter("sone", "invalid-sone-id")
189 addTranslation("Page.ViewSone.Page.TitleWithoutSone", "view sone page without sone")
190 assertThat(page.getPageTitle(soneRequest), equalTo("view sone page without sone"))
194 fun `page title contains sone name for request with sone parameters`() {
195 addHttpRequestParameter("sone", "sone-id")
196 addSone("sone-id", currentSone)
197 whenever(currentSone.profile).thenReturn(Profile(currentSone).apply {
202 addTranslation("Page.ViewSone.Title", "view sone page")
203 assertThat(page.getPageTitle(soneRequest), equalTo("First M. Last - view sone page"))
207 fun `page is link-excepted`() {
208 assertThat(page.isLinkExcepted(URI("")), equalTo(true))
212 fun `page can be created by dependency injection`() {
213 assertThat(baseInjector.getInstance<ViewSonePage>(), notNullValue())