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